В настоящее время я пытаюсь смоделировать динамический объект данных, который может иметь или пропустить некоторые свойства (имена свойств известны текущим требованием). Неизвестно, будут ли позже добавляться новые свойства (но это почти наверняка). Моделируется объект что-то вдоль линии это:Структура таблицы для данных со многими 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 способов решения этой проблемы является лучше с точки зрения технического обслуживания (работа для разработчика), потребление памяти (на диске) и производительность (больше запросов в секунду)? Возможно, у вас также есть лучшая идея о том, как с этим бороться. Заранее спасибо
похоже на мой комментарий к 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
@Nogiax - Структура вашего объекта (Map properties;) указывает, что вы хотите сохранить свойства в сумке свойств, то есть в строках. Который поддался бы варианту 2. Это предполагает, что вы не выполняете объединения и вместо этого выполняете 2 небольших запроса, один для заголовка и 1 для свойств, а логика - всего в вашем коде, а не в базе данных. Если вы хотите присоединиться к свойствам, чтобы сделать одну строку, то есть свойства в виде столбцов, тогда вы можете перейти с параметром 1, так как это будет намного проще в запросе. –
Daniel
Спасибо вам объяснение. Ваш подход звучит разумно. У меня есть следующий вопрос: если я выберу все строки из TABLE_HEADER, а количество найденных строк будет X. Тогда я хотел бы получить свойства для каждой строки.Вызвали этот результат в X дополнительных запросах, чтобы получить все свойства для всех объектов (так что это 1 + X запросов для всех данных)? – Nogiax