Подтвердить что ты не робот

Динамическая схема базы данных

Что такое рекомендуемая архитектура для хранения хранилища для схемы динамической логической базы данных?

Чтобы уточнить: где требуется система для хранения хранилища для модели, схема которой может быть расширена или изменена ее пользователями после ее создания, какие хорошие технологии, модели баз данных или механизмы хранения, которые позволят это сделать?

Несколько иллюстраций:

  • Создание/изменение объектов базы данных с помощью динамически созданного DML
  • Создание таблиц с большим количеством разреженных физических столбцов и использование только тех, которые необходимы для "наложенной" логической схемы
  • Создание "длинной, узкой" таблицы, в которой хранятся динамические значения столбцов в виде строк, которые затем необходимо поворачивать для создания "короткого широкого" набора строк, содержащего все значения для определенного объекта
  • Использование системы типов BigTable/SimpleDB PropertyBag

Любые ответы, основанные на опыте реального мира, будут очень признательны

4b9b3361

Ответ 1

То, что вы предлагаете, не нова. Множество людей попробовали это... большинство из них обнаружили, что они преследуют "бесконечную" гибкость, а вместо этого получают гораздо больше, намного меньше. Это "плотва мотель" проектов баз данных - данные поступают, но практически невозможно получить его. Попробуйте концептуально написать код для ЛЮБЫХ видов ограничений, и вы поймете, что я имею в виду.

Конечным результатом обычно является система, которая намного сложнее отлаживать, поддерживать и полна проблем согласованности данных. Это не всегда так, но чаще всего это происходит именно так. Главным образом потому, что программист (-ы) не видит, что этот поход крушения прибывает и не защищает его противником. Кроме того, часто заканчивается случай, когда "бесконечная" гибкость действительно не нужна; это очень плохой "запах", когда команда разработчиков получает спецификацию, которая гласит: "Боже, я не знаю, какие данные они собираются здесь положить, так что давайте их помещать WHATEVER"... и конечные пользователи просто отлично с заранее определенными типами атрибутов, которые они могут использовать (кодировать общий телефон # и позволять им создавать любые из них - это тривиально в хорошо нормализованной системе и поддерживает гибкость и целостность!)

Если у вас очень хорошая команда разработчиков и глубоко осведомлены о проблемах, которые вам придется преодолевать с помощью этого дизайна, вы можете успешно создать хорошо продуманную, а не ужасно глючную систему. Большую часть времени.

Зачем начинать с шансов, уложенных так много против вас?

Не верьте мне? Google "Одна таблица True Lookup" или "Дизайн с одной таблицей". Некоторые хорошие результаты: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10678084117056

http://thedailywtf.com/Comments/Tom_Kyte_on_The_Ultimate_Extensibility.aspx?pg=3

http://www.dbazine.com/ofinterest/oi-articles/celko22

http://thedailywtf.com/Comments/The_Inner-Platform_Effect.aspx?pg=2

Ответ 2

Сильно типизированное поле xml в MSSQL работало для нас.

Ответ 3

Как и некоторые другие, не делайте этого, если у вас нет другого выбора. Один случай, когда это требуется, - это продавать готовый продукт, который должен позволять пользователям записывать пользовательские данные. Продукт моей компании относится к этой категории.

Если вам нужно разрешить своим клиентам делать это, вот несколько советов:
 - Создайте административный инструмент надежный для выполнения изменений схемы и не позволяйте делать эти изменения любым другим способом.
 - Сделать административную функцию; не разрешать обычным пользователям доступ к нему.
 - Записывайте каждую деталь о каждой смене схемы. Это поможет вам отладить проблемы, а также даст вам данные CYA, если клиент делает что-то глупое.

Если вы сможете успешно справиться с этим (особенно первый), то любая из упомянутых вами архитектур будет работать. Мое предпочтение заключается в динамическом изменении объектов базы данных, поскольку это позволяет вам использовать преимущества ваших функций запросов СУБД при доступе к данным, хранящимся в настраиваемых полях. Остальные три варианта требуют загрузки больших фрагментов данных, а затем выполняют большую часть обработки данных в коде.

Ответ 4

У меня есть аналогичное требование и я решил использовать схему MongoDB.

MongoDB (от "humongous" ) - это открытая, масштабируемая, высокопроизводительная, без схемы, документально-ориентированная база данных, написанная на языке программирования С++. (Википедия)

Основные характеристики:

  • имеет богатую функциональность запросов (возможно, ближайшую к SQL DB)
  • готовность к производству (foursquare, sourceforge использовать его)

Lowdarks (материал, который вам нужно понять, чтобы вы могли правильно использовать mongo):

  • нет транзакций (на самом деле он имеет транзакции, но только для атомных операций)
  • здесь: http://ethangunderson.com/blog/two-reasons-to-not-use-mongodb/
  • долговечность.. в основном связанные с ACID вещи

Ответ 5

Я сделал это в реальном проекте:

База данных состояла из одной таблицы с одним полем, которое представляло собой массив из 50. На нем был установлен индекс слова. Все данные были пустыми, поэтому "индекс слова" работал так, как ожидалось. Числовые поля были представлены как символы, и фактическая сортировка была выполнена на стороне клиента. (По-прежнему возможно иметь несколько полей массива для каждого типа данных, если это необходимо).

Схема логических данных для логических таблиц хранилась в одной и той же базе данных с другой таблицей "тип" (первый элемент массива). Он также поддерживал простое управление версиями в стиле copy-on-write с использованием того же поля типа.

Преимущества:

  • Вы можете динамически изменять и добавлять/удалять столбцы, не нужно дамп/перезагрузка базы данных. Любые новые данные столбца могут быть установлены на начальное значение (фактически) за нулевое время.
  • Фрагментация минимальна, так как все записи и таблицы имеют одинаковый размер, иногда это дает лучшую производительность.
  • Все схемы таблиц являются виртуальными. Любая структура логической схемы возможна (даже рекурсивная или объектно-ориентированная).
  • Это хорошо для данных "write-once, read-most, no-delete/mark-as-deleted" (большинство веб-приложений на самом деле такие).

Недостатки:

  • Индексирование только полными словами, без аббревиатуры,
  • Возможны сложные запросы, но с небольшим ухудшением производительности.
  • В зависимости от того, поддерживает ли ваша предпочтительная система баз данных массивы и индексы слов (она была реализована в СУБД PROGRESS).
  • Реляционная модель только в программизме (т.е. только во время выполнения).

И теперь я думаю, что следующим шагом может быть - реализовать такую ​​базу данных на уровне файловой системы. Это может быть относительно легко.

Ответ 6

Весь смысл иметь реляционную БД, чтобы ваши данные были безопасными и последовательными. В тот момент, когда вы разрешаете пользователям изменять схему, происходит целостность данных...

Если вам нужно хранить разнородные данные, например, как сценарий CMS, я бы предложил хранить XML, проверенный XSD в строке. Конечно, вы теряете производительность и легкие возможности поиска, но это хороший компромисс с IMHO.

Так как он 2016, забудьте XML! Используйте JSON для хранения нереляционного пакета данных с соответствующим типом столбца в качестве бэкэнд. Обычно вам не нужно запрашивать значение внутри мешка, что будет медленным, хотя многие современные базы данных SQL понимают JSON изначально.

Ответ 7

Звучит для меня как то, что вы действительно хотите, это своего рода "мета-схема", схема базы данных, которая способна описывать гибкую схему для хранения фактических данных. Изменения динамической схемы являются обидчивыми, а не то, с чем вы хотите общаться, особенно если пользователи не могут внести изменения.

Вы не найдете базу данных, которая больше подходит для этой задачи, чем любая другая, поэтому лучше всего выбрать ее на основе других критериев. Например, какую платформу вы используете для размещения БД? На каком языке написано приложение? и т.д.

Чтобы уточнить, что я подразумеваю под "мета-схемой":

CREATE TABLE data (
    id INTEGER NOT NULL AUTO_INCREMENT,
    key VARCHAR(255),
    data TEXT,

    PRIMARY KEY (id)
);

Это очень простой пример: у вас, скорее всего, есть что-то более конкретное для ваших потребностей (и, надеюсь, немного легче работать), но это служит для иллюстрации моей точки зрения. Вы должны считать, что сама схема базы данных является неизменной на уровне приложения; любые структурные изменения должны отражаться в данных (то есть, является экземпляром этой схемы).

Ответ 8

Создать 2 базы данных

  • DB1 содержит статические таблицы и представляет собой "реальное" состояние данных.
  • DB2 бесплатна для пользователей, поскольку они (или вы) должны будете писать код для заполнения своих нечетных таблиц из DB1.

Ответ 9

Я знаю, что модели, указанные в вопросе, используются во всех производственных системах. Довольно большой используется в большом университете/учебном заведении, в котором я работаю. Они специально используют подход с длинной узкой таблицей для сопоставления данных, собранных многими различными системами сбора данных.

Кроме того, недавно Google выпустил свой внутренний протокол обмена данными, буфер протокола, как открытый источник через свой сайт кода. Система баз данных, смоделированная по этому подходу, будет весьма интересной.

Проверьте следующее:

Модель значения атрибута объекта

Google Protocol Buffer

Ответ 10

EAV подход, я считаю, лучший подход, но поставляется с большой стоимостью

Ответ 12

Я знаю, что это старая тема, но я думаю, что она никогда не теряет актуальности. Я сейчас что-то развиваю. Вот мой подход. Я использую настройку сервера с MySQL, Apache, PHP и Zend Framework 2 как платформу приложения, но она также должна работать с любыми другими настройками.

Вот простое руководство по внедрению, вы можете еще дальше его развивать.

Вам понадобится реализовать собственный интерпретатор языка запросов, потому что эффективный SQL будет слишком сложным.

Пример:

select id, password from user where email_address = "[email protected]"

Макет физической базы данных:

Таблица "specs": (должна быть кэширована на вашем уровне доступа к данным)

  • id: int
  • parent_id: int
  • имя: varchar (255)

Таблица 'items':

  • id: int
  • parent_id: int
  • spec_id: int
  • данные: varchar (20000)

Содержание спецификаций таблицы:

  • 1, 0, 'пользователь'
  • 2, 1, 'email_address'
  • 3, 1, 'password'

Содержание элементов таблицы:

Перевод примера на наш собственный язык запросов:

select id, password from user where email_address = "[email protected]"

для стандартного SQL будет выглядеть так:

select 
    parent_id, -- user id
    data -- password
from 
    items 
where 
    spec_id = 3 -- make sure this is a 'password' item
    and 
    parent_id in 
    ( -- get the 'user' item to which this 'password' item belongs
        select 
            id 
        from 
            items 
        where 
            spec_id = 1 -- make sure this is a 'user' item
            and 
            id in 
            ( -- fetch all item id with the desired 'email_address' child item
                select 
                    parent_id -- id of the parent item of the 'email_address' item
                from 
                    items 
                where 
                    spec_id = 2 -- make sure this is a 'email_address' item
                    and
                    data = "[email protected]" -- with the desired data value
            )
    )

Вам нужно будет иметь таблицу спецификаций, кэшированную в ассоциативном массиве или хэш-таблице или что-то подобное, чтобы получить spec_id из имен спецификаций. В противном случае вам нужно будет добавить еще некоторые служебные данные SQL, чтобы получить spec_id от имен, например, в этом фрагменте:

Плохой пример, не используйте это, избегайте этого, вместо этого кешируйте таблицу спецификаций!

select 
    parent_id, 
    data 
from 
    items 
where 
    spec_id = (select id from specs where name = "password") 
    and 
    parent_id in (
        select 
            id 
        from 
            items 
        where 
            spec_id = (select id from specs where name = "user") 
            and 
            id in (
                select 
                    parent_id 
                from 
                    items 
                where 
                    spec_id = (select id from specs where name = "email_address") 
                    and 
                    data = "[email protected]"
            )
    )

Надеюсь, вы поняли эту идею и можете сами определить, подходит ли вам этот подход.

Наслаждайтесь!: -)

Ответ 13

В прошлом я выбрал вариант C - Создание "длинной, узкой" таблицы, в которой хранятся динамические значения столбцов в виде строк, которые затем необходимо поворачивать для создания "короткого широкого" набора строк, содержащего все значения для определенного объекта.. Тем не менее, я использовал ORM, и это ДЕЙСТВИТЕЛЬНО сделало вещи болезненными. Я не могу придумать, как вы это сделаете, скажем, LinqToSql. Я предполагаю, что мне нужно создать Hashtable для ссылки на поля.

@Skliwz: Я предполагаю, что он больше заинтересован в разрешении пользователям создавать пользовательские поля.

Ответ 14

ElasticSearch. Вы должны учитывать это, особенно если вы имеете дело с наборами данных, которые вы можете разделить по дате, вы можете использовать JSON для своих данных и не фиксируете использование SQL для извлечения данных.

ES отображает вашу схему для любых новых полей JSON, которые вы отправляете, либо автоматически, либо с помощью подсказок, либо вручную, которые вы можете определить/изменить одной командой HTTP ( "сопоставления" ). Хотя он не поддерживает SQL, он обладает отличными возможностями поиска и даже агрегациями.

Ответ 15

На вики c2.com была изучена идея "Динамическая реляционная". Вам НЕ нужен DBA: столбцы и таблицы являются Create-On-Write, если вы не начнете добавлять ограничения, чтобы заставить его действовать скорее как традиционная СУБД: по мере созревания проекта вы можете постепенно "блокировать его".

Концептуально вы можете думать о каждой строке как о выражении XML. Например, запись сотрудника может быть представлена ​​как:

<employee lastname="Li" firstname="Joe" salary="120000" id="318"/>

Это не означает, что он должен быть реализован как XML, это просто удобная концептуализация. Если вы запрашиваете несуществующий столбец, например "SELECT madeUpColumn...", он обрабатывается как пустой или пустой (если только дополнительные ограничения не запрещают такие). И возможно использовать SQL, хотя нужно быть осторожным в сравнении из-за модели подразумеваемого типа. Но помимо обработки типов пользователи динамической реляционной системы будут чувствовать себя как дома, потому что они могут использовать большую часть своих существующих знаний РСУБД. Теперь, если кто-то просто построит его...

Ответ 16

sql уже предоставляет способ изменения вашей схемы: команда ALTER.

просто есть таблица, в которой перечислены поля, которые пользователи не могут изменять, и написать хороший интерфейс для ALTER.