Хранение графиков в полностью нормализованных реляционных базах данных

Цель

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


Проблема

EAV является обходным путем к нормальным ограничениям РСУБД.

Если бы вы нормализовали схему EAV, это было бы уродливо.


Идея

Если EAV был нормализован, это было бы уродливо.

Означает ли тот факт, что мы традиционно поддерживаем эту схему вручную, ограничивает их сложность и мощность?

Но если это было поддержано и запрошено программно, что бы это значило?


Графы

Если у вас есть n разные объекты в n разных таблицах, почему не, пусть ваш код генерирует таблицы ссылок n(n+1)/2 и запросы между ними? Не приведет ли это к истинному графику в нормализованной схеме?

В сильно взаимосвязанной базе данных всегда будет экспоненциально больше ребер, чем вершин. Почему бы не сосредоточиться на создании правильных, нормализованных вершин (n таблиц сущностей), и пусть наш код поддерживает ребра ( n^x таблицы ссылок)?


Заключение

Может ли система нормализовать EAV и поддерживать результирующую сложную схему?

Можно ли хранить сложные графы в (и оставаться верными) реляционным базам данных?

Я уверен, что это было сделано раньше, но я никогда не видел его. Что мне не хватает?


Пример проблемы

Сохранение печатных работ и их библиографических данных

  • Многие свойства, которые могут быть не просто строками, а целыми объектами.
  • В мире библиотеки нет простой (и реляционной) схемы, которая может хранить данные без потерь без чрезвычайно сложных схем.
  • Много разных типов ассоциаций и связанных объектов
    • И их соответствующие свойства (которые могут сильно различаться).
    • И их многочисленные отношения, разных типов, между собой.

Вопросы

"Какую проблему вы пытаетесь решить?"
-Piet

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

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

Это "традиционное обслуживание" - это то, о чем я говорю, мы должны автоматизировать. Разве это не ворчит?

Ответы

Ответ 1

Поскольку вы редактируете вопрос, он должен быть активным.

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

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

Вы должны рассмотреть правильную академически полученную альтернативу. Эта полная реляционная целостность и возможности. Это называется Шестой нормальной формой. EAV на самом деле является подмножеством 6NF, без полного понимания; более широко известное исполнение 6NF.

6NF реализован правильно, особенно быстро, поскольку он хранит столбцы, а не строки. Поэтому вы можете сопоставить свои данные (диаграмму серии, точки данных) таким образом, чтобы получить плоскую высокую скорость независимо от векторов, которые вы используете для доступа к графикам. (Вы можете устранить дублирование в более высоком порядке, чем 5NF, но это расширенное использование.)

"Высокосвязанные" не является проблемой вообще. Это характер реляционной базы данных. Предостережение здесь, оно должно быть действительно нормализованным, а не встроенным куском плоских файлов.

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

Мои ответы на эти вопросы дают полное представление о предмете. Последний из них особенно длинный из-за контекста и аргументов. Ответ EAV-6NF на
Ответ EAV-6NF на два
EAV-6NF Ответ Три

И это тоже стоит:
Проблема, связанная с схемой

Ответ 2

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

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

В вашем сценарии всегда будет большое количество путей от одного объекта к другому. Как кто-нибудь узнает, какой путь был "правильным". "Правильный" путь будет просто "набором отношений, которые разработчик решил заполнить".

Представьте себе базу данных, которая имеет эти отношения.

Клиент < === > Invoice < === > InvoiceLineItem < ==== > Продукт

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

Но если бы это был график, где все указывало на все остальное, как я узнаю, какой путь является "правильным". Будет ли это отношение "Customer_Product", "Customer_Invoice_Line_Item" к "Customer_Product" или "Customer_Invoice" к "Invoice_Product" или "Customer" к "Invoice" к "Invoice_Line_Item" к "SomeOtherTableIHaven'tEvenLookedAtYet" к "Продукту"? Ответ может быть "Он должен быть очевиден", но очень часто для того, чтобы что-то было очевидным только для одного разработчика.

Ответ 3

почему бы не позволить генерировать код n (n + 1)/2 "link" таблицы и запросы между ними?

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

Но более реалистично, когда "n" получает умеренный размер, количество ссылочных таблиц становится огромным, действительно, очень быстрым. Настолько, что вы не можете сказать, что эта методология может представлять собой универсальное решение IMO.

Но вот мое настоящее возражение - ваша предлагаемая методология не является жизнеспособным инженерным решением. Инженерия - все о том, чтобы делать компромиссы, и этот метод торгует ЛОТО ради всеобщности. Например, вот что вы теряете, используя свой метод над проверенным и "истинным" дизайном базы данных:

  • Вы теряете возможность иметь открываемую схему - количество таблиц выходит из-под контроля так быстро, любой, кто смотрит на ваш дизайн таблицы, не может знать, что такое отношения.
  • Почти никакая целостность данных не может быть реализована в базе данных, отличной от основного ссылочного типа - весь код, который использует базу данных, должен быть осторожным, чтобы не нарушать правила, или у вас есть повреждение данных.
  • В конечном итоге вы получите очень большое количество таблиц, которые моделируют отношения, которые на самом деле не существуют в вашей бизнес-области. Когда вы используете таблицу "link", вы по существу моделируете отношения "многие ко многим", которые могут или не могут существовать в реальном мире.
  • Вы потенциально теряете огромное количество скорости и получаете очень большой штраф за используемое хранилище. Гораздо эффективнее моделировать отношения 1: N, ссылаясь на "родительский" объект в "дочернем" объекте напрямую.

Ответ 4

Это зависит полностью от определения вашего графика.

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

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

Я уверен, что это было сделано раньше, но я никогда не видел его. Что мне не хватает?

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

Добавление

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

Я думаю, что это гораздо чаще, чем вы думаете. Я в основном знаком с Python, но все основные инструменты ORM/RDBMS, доступные для него (SQLAlchemy, Django, SQLObject,...) поддерживают автоматическое обслуживание таблиц ссылок "многие-ко-многим" в качестве стандартной функции.