Лучший способ сделать слой MySQL Object - PullRequest
2 голосов
/ 22 августа 2011

Я не профессионал в MySQL, но хочу сделать что-то вроде Object Layer над реляционными таблицами MySQL.

Я хочу иметь очень много "структур" с полями типа "bigint", "longtext", "datetime", "double", которые хранятся всего в 7 таблицах.

entity_types (et_id, et_name) - список "структур";

entity_types_fields (etf_id, parent_et_id, ....., etf_ident, etf_type) - список свойств структуры, хранящихся в одной таблице для ВСЕХ структур; etf_type содержит значение int (0,1,2,3), которое ссылается на одну из 4 описанных ниже таблиц.

сущностей (e_id, et_id) - список всех доступных сущностей (id и id типа сущности)

и 4 таблицы данных (содержащие все данные для сущностей) -

entity_props_bigint (parent_e_id, parent_etf_id, ep_data) - для свойств данных BIGINT entity_props_longtext (parent_e_id, parent_etf_id, ep_data) - для свойств данных LONGTEXT entity_props_datetime (parent_e_id, parent_etf_id, ep_data) - для свойств данных DATETIME entity_props_double (parent_e_id, parent_etf_id, ep_data) - для свойств данных DOUBLE

Как лучше всего делать выборку из такого слоя данных?

Пусть у меня есть список e_id (id сущностей), каждая сущность может иметь любой тип. Я хочу получить предопределенный список свойств. Если некоторые объекты не имеют такого свойства, я хочу, чтобы оно было равно NULL.

У вас есть информация о том, как это сделать? Может быть, у вас есть ссылки или вы уже имели дело с такими вещами.

Спасибо!

1 Ответ

0 голосов
/ 22 августа 2011

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

Я изменил тег relational вашего вопроса на eav, потому что ваш дизайн - это вариант дизайна Entity-Attribute-Value . В переполнении стека существует ограничение в пять тегов. Но вы должны знать, что ваш дизайн не реляционный.

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

Как лучше всего делать выборку из такого слоя данных?

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

SELECT e.e_id, f.etf_ident, f.etf_type, 
    p0.ep_data AS data0, 
    p1.ep_data AS data1, 
    p2.ep_data AS data2,
    p3.ep_data AS data3
FROM entities AS e
INNER JOIN entity_type_fields AS f ON e.et_id = f.parent_et_id
LEFT OUTER JOIN entities_props_bigint   AS p0 ON (p0.parent_e_id,p0.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_longtext AS p1 ON (p1.parent_e_id,p1.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_datetime AS p2 ON (p2.parent_e_id,p2.parent_etf_id) = (e.e_id,f.etf_id) 
LEFT OUTER JOIN entities_props_double   AS p3 ON (p3.parent_e_id,p3.parent_etf_id) = (e.e_id,f.etf_id) 

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


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

Вот как я бы это сделал:

  • Храните любые атрибуты, которые имеют все ваши подтипы сущностей, в виде таблицы супертипа.

    сущностей (e_id, entity_type, name, date_created, создатель, sku и т. Д.)

  • Храните любые атрибуты, относящиеся к подтипу сущности, в их собственной таблице, как в наследовании таблицы классов Мартина Фаулера design.

    entity_books (e_id, isbn, pages, издатель, тома и т. Д.)

    entity_videos (e_id, формат, регион, диски и т. Д.)

    entity_socks (e_id, ткань, размер, цвет и т. Д.)

  • Используйте схему Closure Table для моделирования иерархии объектов.

    entity_paths (ancestor_e_id, потомок_e_id, длина_пути)

Для получения дополнительной информации о таблицах наследования и закрытия таблиц классов см. Мои презентации Практические объектно-ориентированные модели в SQL и Модели для иерархических данных в SQL или моя книга Антипаттерны SQL: предотвращение ловушек программирования баз данных или книга Мартина Фаулера Шаблоны архитектуры корпоративных приложений .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...