MySQL - соответствующее применение VIEWS или FOREIGN KEYS

Предположим, у меня есть таблица, которая служит инвентарем моего дома — inventory_items, если хотите. inventory_items содержит все, что у меня есть, но только самую общую информацию (то есть поля, которые будут применяться ко всему, что у меня есть, например, имя, дата покупки).

Затем я хочу иметь отдельную таблицу для electronics_data, которая является элементом инвентаря, но имеет специальную информацию для хранения (скажем, серийный_номер, мощность), и еще одну для furniture_data, которая содержит информацию о мебели (количество_ножек, материал).

Во всех случаях элементы в electronics_data будут иметь соответствующий элемент в inventory_items, связанный полем идентификатора. То же самое относится и к furniture_data.

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

1) Создайте отношение внешнего ключа между inventory_items и electronics_data - таким образом, загрузка всех элементов также даст мне все мои дочерние данные. Но не все элементы в inventory_items будут иметь соответствующий элемент в electronics_data, значит ли это, что внешний ключ не может работать?

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

Это общие вопросы, в частности 2) я думаю, что это очень зависит от данных.

Спасибо!


person depose    schedule 02.11.2016    source источник
comment
Этот вопрос не имеет ничего общего с администрированием базы данных, это вопрос дизайна.   -  person Shadow    schedule 02.11.2016
comment
@ Тень - отмечено. Формулировка скорректирована соответствующим образом.   -  person depose    schedule 02.11.2016
comment
Следуйте тегу EAV, который я добавил.   -  person Rick James    schedule 03.11.2016


Ответы (3)


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

2) Представление может left join дочерние таблицы в таблице inventory_items. Если поля, используемые в объединении, проиндексированы во всех таблицах, то операция не требует больших ресурсов. Самая большая проблема может заключаться в том, как вы строите представление, если у вас много специализированных дочерних таблиц. Но это, вероятно, более широкий вопрос дизайна приложения в любом случае (если вы смотрите на свои электронные устройства, то вы, вероятно, не хотите видеть поля из таблицы предметов мебели - в этих специализированных представлениях я бы использовал inner join, а не left join).

person Shadow    schedule 02.11.2016

ну, это сделает вашу жизнь проще, если вы сможете присоединиться к таблицам при извлечении данных. Существует множество способов объединения таблиц, в вашем случае, если все ваши таблицы имеют столбец I.D, вы можете использовать «Equijoin». Вот как вы можете это сделать.

SELECT inventory_items.name, electronics_data.wattage, furniture_data.material 
FROM inventory_items, electronics_data, furniture_data
WHERE inventory_items.i.d=electronics_data.i.d=furniture_data.id;

поэтому с таким соединением вы можете добавить столько столбцов, сколько хотите, но обязательно выделите таблицу, из которой они взяты, и в предложении «ГДЕ» покажите, где они равны, иначе он не вернет никаких данных.

person Pedroh_5iva    schedule 02.11.2016
comment
Лучше использовать явный синтаксис соединения, чтобы можно было легко различать критерии соединения и критерии фильтрации. Кроме того, если OP объединяет несколько дочерних таблиц так, как вы предложили, результат будет пустым. - person Shadow; 02.11.2016
comment
Вы не можете использовать = в SQL. - person philipxy; 03.11.2016

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

Несколько слов о производительности просмотра. Возьмите представление, которое объединяет очень большие таблицы таким образом, что запрос

select * from <view>

занимает много времени, скажем, 30 минут. Запрос

select * from <view> where <criteria>

может занять доли секунды. В большинстве современных СУБД критерии where объединяются с существующим запросом в определении представления для выполнения запроса. Он не выполняет определение представления, а затем выполняет фильтрацию. Поэтому проверяйте производительность представления с помощью реальных запросов, а не запросов «дампа данных».

person TommCatt    schedule 06.11.2016