it-swarm-ru.tech

Схема динамической базы данных

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

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

Несколько возможностей для иллюстрации:

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

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

63
Fake Jim

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

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

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

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

Не веришь мне? Google "One True Lookup Table" или "Дизайн одной таблицы". Некоторые хорошие результаты: 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=

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

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

36
Matt Rogish

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

19
Bloodhound

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

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

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

15
Josh Yeager

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

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

Особенности:

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

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

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

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

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

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

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

  1. Вы можете динамически переставлять и добавлять/удалять ваши столбцы, без необходимости дамп/перезагрузка базы данных. Любые новые данные столбца могут быть установлены в начальное значение (практически) в нулевое время.
  2. Фрагментация минимальна, так как все записи и таблицы имеют одинаковый размер, иногда это дает лучшую производительность.
  3. Вся схема таблицы является виртуальной. Возможна любая структура логической схемы (даже рекурсивная или объектно-ориентированная).
  4. Это хорошо для данных "однократная запись, в основном для чтения, без удаления/пометки как удаленные" (большинство веб-приложений на самом деле такие).

Недостатки:

  1. Индексирование только полными словами, без сокращений,
  2. Возможны сложные запросы, но с небольшим снижением производительности.
  3. Зависит от того, поддерживает ли предпочитаемая вами система баз данных массивы и индексы Word (она была дополнена в СУРБД PROGRESS).
  4. Реляционная модель находится только в памяти программиста (то есть только во время выполнения).

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

7
Thevs

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

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

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

6
Sklivvz

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

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

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

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

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

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

    PRIMARY KEY (id)
);

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

3
Daniel Spiewak

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

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

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

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

Google Protocol Buffer

3
siculars

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

2
kamal

В Википедии есть отличный обзор проблемного пространства:

http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model

2
DenNukem

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

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

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

Пример:

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

Физическая структура базы данных:

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

  • id: int
  • parent_id: int
  • имя: варчар (255)

Таблица "товары":

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

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

  • 1, 0, "пользователь"
  • 2, 1, 'email_адрес'
  • 3, 1, "пароль"

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

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

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's 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]"
            )
    )

Я надеюсь, что вы поняли идею и сможете сами определить, является ли такой подход для вас возможным.

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

2
Oliver Konig

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

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

0
Danimal

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

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

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

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

0
FloverOwe

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

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

0
Oren