Зачем нужна таблица соединения для отношения 1:m в SQL
-
13-09-2019 - |
Вопрос
В чем преимущество наличия соединительных таблиц между первыми отношениями 1:m и вторыми отношениями 1:m в следующей базе данных?
альтернативный текст http://dl.getdropbox.com/u/175564/db/db-simple.png
Книга Деревья и иерархии Джо Селко в SQL для Smarties говорит, что причина в уникальных отношениях в 1:m.Например, следующие таблицы запрещают пользователям дважды задавать один и тот же вопрос и дважды давать один и тот же ответ соответственно.
Первое соотношение 1:m
users-questions
===============
user_id REFERENCES users( user_id )
question_id REFERENCES questions ( question_id )
PK( user_id, question_id) // User is not allowed to ask same question twice
Второе соотношение 1:m
questions-answers
=================
question_id REFERENCES questions( question_id)
answer_id REFERENCES answers( aswer_id )
PK( question_id, answer_id ) // Question is not allowed to have to same answers
Это преимущество уникальности не убеждает меня сделать мой код более сложным.Я не могу понять, почему я должен ограничивать возможность наличия вопросов или ответов с одним и тем же идентификатором в базе данных, поскольку я, возможно, могу запретить это с помощью PHP.
Решение
Обычно это происходит из-за дублирования данных.
Что касается ваших рассуждений, да, вы можете применить это на бизнес-уровне, но если вы допустите ошибку, это может привести к поломке значительного объема кода.Проблема в том, что ваша модель данных может содержать всего несколько таблиц.Повезло тебе.Когда ваша модель данных растет, если вы не можете понять ее структуру и вам приходится помещать всю логику для поддержки денормализованных таблиц на уровень графического интерфейса, вы можете очень легко столкнуться с проблемами.Обратите внимание, что сложно обеспечить потокобезопасность в графическом интерфейсе вашей базы данных SQL без использования блокировки, которая снизит вашу производительность.
СУБД очень хорошо справляются с этими проблемами.Вы можете поддерживать чистоту своей модели данных и использовать индексацию, чтобы обеспечить необходимую скорость.Ваша цель должна состоять в том, чтобы сначала сделать все правильно, и денормализовать таблицы только тогда, когда вы увидите явную необходимость в этом (для производительности и т. д.).
Хотите верьте, хотите нет, но во многих ситуациях нормализация данных облегчает, а не усложняет вашу жизнь, когда дело касается вашего приложения.Например, если у вас есть одна большая таблица с вопросами и ответами, вам придется написать код, чтобы проверить ее уникальность.Если у вас есть таблица с первичным ключом, вы просто пишете
insert into table (col1, col2) values (@id, @value) --NOTE: You would probably
--make the id column an autonumber so you dont have to worry about this
База данных не позволит вам вставить, если у вас там не уникальное значение ИЛИ если вы размещаете ответ без вопроса.Все, что вам нужно сделать, это проверить, сработала ли прошивка, не более того.Как вы думаете, в каком из них меньше кода?
Другие советы
Что ж, идея уникальных отношений кажется мне бессмысленной, возможно, потому, что я привык к СУБД, в которых можно определять уникальные ключи, отличные от первичного ключа.В моем мире таблицы отображения, подобные этим, позволяют реализовать отношения «многие ко многим», а использовать их для отношений «один ко многим» — это безумие. Я имею в виду, если вы сделаете это, возможно, вы намереваться чтобы связь использовалась как «один ко многим», но то, что вы на самом деле реализован это поддержка «многие ко многим».
Я не согласен с тем, что вы говорите о том, что уникальные составные ключи бесполезны на уровне персистентности, потому что вы можете обеспечить это на уровне приложения.Ограничения уникальности на уровне сохраняемости имеют множество сложно воспроизводимых преимуществ, например, в MySQL возможность использовать преимущества INSERT ... ON DUPLICATE KEY UPDATE
.
Я согласен, что таблица соединений для связи «один-ко-многим» в этой ситуации, похоже, не приносит особой пользы, и, как говорит @chaos, вы фактически в конечном итоге реализуете поддержку «многие-ко-многим».Но Джо Селко умный парень – действительно ли он дает именно такой ответ?
Еще одна возможная причина реализации таблицы соединения по принципу «один ко многим» заключается в том, что она полностью отделяет вопросы/ответы от зависимости от пользователей.
Например, предположим, что вы добавили Dogs
столы и Deities
стол.Мы все знаем, что собаки не могут регистрироваться в качестве пользователей, потому что у них нет адресов электронной почты, а боги не регистрируются в качестве пользователей, потому что, ну, это ниже их достоинства.Возможно, собаки и боги все еще задают вопросы, но для этого вам может понадобиться реализовать таблицу вопросов о собаках и таблицу вопросов о божествах.Теоретически это все еще «многие ко многим», но на практике это делается для того, чтобы иметь возможность иметь несколько связей «один ко многим».