2016-12-08 6 views
0

В настоящее время я пытаюсь смоделировать динамический объект данных, который может иметь или пропустить некоторые свойства (имена свойств известны текущим требованием). Неизвестно, будут ли позже добавляться новые свойства (но это почти наверняка). Моделируется объект что-то вдоль линии это:Структура таблицы для данных со многими NULL

int id PRIMARY KEY NOT NULL; 
int owner FOREIGN KEY NOT NULL; 
Date date NOT NULL; 
Time time NOT NULL; 
Map<String,String> properties; 

Свойство может быть любого типа (INT, BOOL, строка, ...)

я не уверен, как я должен моделировать этот объекта в базе данных SQL. Есть два способа, которые я могу придумать, чтобы сделать это, и я хотел бы иметь некоторый вклад, который будет лучшим выбором с точки зрения «работы» разработчика (обслуживания), потребления памяти и производительности. В качестве дополнительной информации: свойства почти всегда NULL (не существует)

(1) У меня была бы большая таблица с идентификатором, владельцем, датой, временем и каждым свойством в качестве столбца, тогда как отсутствующие свойства для строки моделируются как NULL. например

TABLE_X 
id|owner|date|time|prop_1|prop_2|prop_3|... 

В этой таблице должно быть много значений NULL.

Если новые свойства должны быть добавлены, то я бы сделать TABLE ALTER и вставить новый столбец для каждого нового свойства

Здесь я хотел бы сделать «обычный»

SELECT * FROM TABLE_X ... 

(2) Я бы имеют основную таблицу со всеми NOT NULL данных:

TABLE_X 
id|owner|date|time 

И затем есть отдельная таблица для каждого свойства, например:

TABLE_X_PROP_N 
foreign_key(TABLE_X(id))|value 

Здесь не должно быть значений NULL. Свойство либо имеет значение, либо находится в соответствующей таблице, либо оно равно NULL, а затем не отображается в его таблице.

Чтобы добавить новые объекты, я бы просто добавил другую таблицу.

Вот бы сделать

SELECT * FROM TABLE_X LEFT JOIN TABLE_X_PROP_1 ON ... LEFT JOIN TABLE_X_PROP_2 ON ... 

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

ответ

1

Если вы идете с Варианта 2, я думаю, вам нужно 3 таблицы:

TABLE_HEADER
идентификатор | владелец | Дата | Время

TABLE_PROPERTY
идентификатор | имя

TABLE_PROPERTYVALUE
идентификатор | headerID (ФК) | PropertyID (ФК) | значение

Простота добавления новых свойств позволяет повысить гибкость и ускорить итерацию. Количество свойств также будет иметь эффект (например, если у вас есть 500 свойств, вам не понадобится таблица с 500 столбцами!). Основной недостаток - это станет уродливым, если вам нужно приложить сложную бизнес-логику, используя свойства как более сложную структуру для навигации, и вы не можете обеспечить целостность данных, например, не null для определенных полей. Если вы действительно хотите приобрести мешок с недвижимостью, как вы смоделировали в своей структуре объектов, тогда это легко отобразится. Как и все, что зависит от ваших обстоятельств для наиболее подходящего.

+0

похоже на мой комментарий к arturros answer. Я не уверен, как получить определенное значение свойства, если у меня есть несколько свойств для идентификатора в TABLE_HEADER. Визуально, когда * I * LEFT JOIN они будут рядом друг с другом, но будет ли это также, когда DB Engine делает это? не могут ли столбцы не находиться в случайном порядке? Пример: id1 | владелец1 | date1 | time1 | id_propName1 | name1 | id_propValue1 | id_propName1 | id1 | value1 | id_propName2 | name2 | id_propValue2 | id_propName2 | id1 | значение2 -> как бы я получить значение для prop_2 из этого результата ? – Nogiax

+0

@Nogiax - Структура вашего объекта (Map properties;) указывает, что вы хотите сохранить свойства в сумке свойств, то есть в строках. Который поддался бы варианту 2. Это предполагает, что вы не выполняете объединения и вместо этого выполняете 2 небольших запроса, один для заголовка и 1 для свойств, а логика - всего в вашем коде, а не в базе данных. Если вы хотите присоединиться к свойствам, чтобы сделать одну строку, то есть свойства в виде столбцов, тогда вы можете перейти с параметром 1, так как это будет намного проще в запросе. – Daniel

+0

Спасибо вам объяснение. Ваш подход звучит разумно. У меня есть следующий вопрос: если я выберу все строки из TABLE_HEADER, а количество найденных строк будет X. Тогда я хотел бы получить свойства для каждой строки.Вызвали этот результат в X дополнительных запросах, чтобы получить все свойства для всех объектов (так что это 1 + X запросов для всех данных)? – Nogiax

1

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

properties(
foreign_key(TABLE_X(id)) 
property_name, 
value); 
+0

Это может быть идея, но я не уверен, как отличить значение prop_1 от значения prop_2? В моем втором решении я мог бы назвать столбец «значение» свойства, такого как имя свойства, и поэтому, когда я присоединяюсь к таблицам, это значение связано с именем столбца. Но как это будет работать с вашим решением? Редактировать: Я действительно новичок в этом. Извините, если это «очевидно», как это работает с вашим решением. – Nogiax

1

Похоже, вы пытаетесь реализовать шаблон Entity-Attribute-Value (часто просматриваемый как анти-) здесь. Вы знакомы с ними? Вот несколько ссылок:

https://softwareengineering.stackexchange.com/questions/93124/eav-is-it-really-bad-in-all-scenarios

http://www.dbforums.com/showthread.php?1619660-OTLT-EAV-design-why-do-people-hate-it

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

Лично я очень настороженно относятся к этому типу установки в РСУБД. Я склонен думать, что базы данных стиля NoSQL лучше подходят для этих типов динамических структур, хотя, по общему признанию, у меня относительно мало опыта в реальном мире с NoSQL.

+0

В принятом ответе вашей первой ссылки ничего не говорится о анти-шаблоне. Правильно (ИМО) заявляет, что у него есть преимущества, а также компромиссы, которые разработчик должен судить по их уникальным обстоятельствам. Точно так же ваша третья статья не считает ее анти-шаблоном. – Daniel

+0

@ Даниэль - Я не согласен ... мое использование (анти-) было более примечательным, что его часто рассматривают как антипаттерн и повышают осознание того факта, что существует значительный набор компромиссов осознавая это, вместо того, чтобы отмечать его как один. – jleach

+0

@ jdl134679 - спасибо, я посмотрю ваши ссылки. – Nogiax

Смежные вопросы