#database-design #relational-database #foreign-key-relationship
#база данных-дизайн #реляционная база данных #связь с внешним ключом
Вопрос:
У меня есть таблица с именем branch
, в которой будут храниться сведения о филиале, такие как его менеджер, местоположение и т.д. Поля являются:
branch_id
branch_manager
branch_location
Данные в этой таблице будут выглядеть следующим образом:
1 Mr. John Doe Manhattan
2 Miss. Jane Doe Utah
3 Mr. Random Guy Somewhere
Существует еще одна таблица с именем services
, в которой хранятся все сведения о службе. Поля являются:
service_id
service_name
Данные будут похожи:
1 New Sales
2 After-Sales Support
3 Replacement
4 Exchange Offer
Теперь я хочу сохранить службы, доступные в каждой ветке. Обычно я предполагаю, что это делается путем создания новой таблицы с именем, branch_services
которая будет содержать branch_id
и service_id
. Итак, если у меня есть следующая запись в branch_services
branch-id service-id
1 2
1 3
2 1
Это означает, что филиал в Манхэттене осуществляет послепродажную поддержку и замену, в то время как филиал в Юте осуществляет только новые продажи.
Теперь мой вопрос — вместо того, чтобы иметь эту branch_services
таблицу, что, если я сохраню разделенный запятыми список служб в самой таблице ветвей?
1 Mr. John Doe Manhattan 2,3
2 Miss. Jane Doe Utah 1
3 Mr. Random Guy Somewhere
Каковы основные аргументы против этого? Является ли это тем, что запросы будут выполняться сложнее / медленнее (например, если бы я хотел посмотреть, какие все ветви предоставляют определенную услугу)? Есть ли какое-либо преимущество в структурировании через запятую?
Ответ №1:
Вы можете хранить свои данные так, как вам удобнее (т. Е. У вас могут быть текстовые поля на кириллице), но вы также должны учитывать, что вы хотите сделать со своими данными (т. Е. Вы хотите сохранить английские слова, а вы и ваши коллеги не знаете кириллицы). Алфавит).
Если вы работаете с реляционной базой данных, я подозреваю, что вы собираетесь использовать SQL. Теперь я могу написать запрос, подобный:
select b.branch_location,
s.service_name
from branch b
inner join branch_services b_s
on b.branch_id = b_s.branch_id
inner join services s
on b_s.service_id = s.service_id
Для получения:
branch_location service_name
Manhattan After-Sales Support
Manhattan Replacement
Utah New Sales
Поскольку SQL предназначен для запроса RDMS, и в нашем случае связь существует между содержимым столбцов branch_id
в branch
и branch_services
(или service_id в branch_services
и services
).
Конечно, мы можем понять, что это 2,3
означает то же самое, что 2
и 3
в двух разных строках, но SQL не способен этого понять. [На самом деле, что мы делаем, это разделяем 2,3
строку на два значения и связываем каждое из них со строкой в services
таблицах. Не так просто сделать это в чистом SQL.]
Ваш вопрос касается производительности, прежде чем попасть туда, возникает реальный вопрос: «Могу ли я запросить такую структуру с помощью SQL?» Да и нет.
Если получить список филиалов и служб, как в моем запросе выше, может быть довольно сложно, то получить ветку, которая выполняет определенную услугу, все еще выполнимо, в конце концов, если нужно проверить, кто это делает New Sales
, вам нужно только посмотреть, есть ли в вашем списке служб 1, но исключить все 10, 11, 12 и так далее. Хм … не так прямолинейно.
Я пытаюсь показать вам, что структура из трех таблиц является более гибкой, если вам нужно использовать ее с SQL, а не с человеческим мозгом. К сожалению, компьютеры еще не настолько умны.
Итак:
Возможно ли хранить данные через запятую в столбце? ДА.
Это хорошая идея? Обычно нет, если вы хотите использовать его в связи с другой таблицей.
Обычно? Если им нужно просто предоставить длинную строку, разделенную запятыми, тогда да.
Комментарии:
1. Я получил только один ответ на этот вопрос, но он был лучшим! большое спасибо!!
2. Я старался изо всех сил, реляционные базы данных иногда следуют вызывающей логике. Максимально упрощайте дизайн и свои запросы