Хорошо ли дублировать FOREIGN KEY, ENUM значения в другие таблицы?

Например:
Есть таблица заказов
id | order_name | type_order | client_id
1 | test_name | default | 1
2 | test_name | default | 2
3 | test_name | default | 3
4 | test_name | default | 4

Есть вторая таблица с предложениями
id | order_id | offer_name
1 | 1 | test_offer_name
2 | 1 | test_offer_name
3 | 2 | test_offer_name
4 | 3 | test_offer_name

Допустим, нам нужно узнать от какого клиента поступило предложение под номером {check_offer_id}
(Для наглядности предположим, что результат выборки можно поместить в переменную)
var order_id = SELECT order_id FROM offers WHERE id = {check_offer_id};
SELECT client_id FROM orders WHERE id = {order_id};
SELECT * FROM users WHERE id = {client_id};

Мы люди умные и не будем делать три запроса в базу. Индексы стоят - делаем LEFT JOIN
SELECT `u`.* FROM offers as `of` 
LEFT JOIN orders as `or` ON (`of`.order_id = `or`.id)
LEFT JOIN users as `u` ON(`or`.client_id = `u`.id)

Получим Всю информацию о клиенте одним запросом!

Теперь в чем суть вопроса. Хорошо/Плохо ли поместить в таблицу с предложениями client_id и type дублируя тем самым ключи чтобы не делать лишних запросов в базу

id | order_id | offer_name | client_id | type
1 | 1 | test_offer_name | 1 | default
2 | 1 | test_offer_name | 1 | default
3 | 2 | test_offer_name | 2 | default
4 | 3 | test_offer_name | 3 | default

Это приме абстрактный. В проекте таких таблиц очень много, операции очень часто выполняются и чтобы добраться к каким то данным из таблицы по ключу нужно делать по 3-5 джоинов.
(Например представьте что в таблице users есть поле city_id, а в таблице с городами есть поле admin_area_id, а в таблице с областями есть поле country_id. И представьте какой запрос нужно сделать чтобы получить айди страны для того чтобы собирать статистику вообще в отдельную таблицу по странам.
  • Вопрос задан
  • 2705 просмотров
Решения вопроса 1
nazarpc
@nazarpc
Open Source enthusiast
В общем случае такое дублирование называется денормализацией, и в случае когда нормализированный "красивый" вариант не справляется с нагрузкой приходится использовать не такую красивую, но более эффективную для конкретной задачи структуру.
В JOIN ничего плохого нет, но если это для вас узкое место - то да, такое изменение имеет место.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы