Когда две таблицы очень похожи, когда они должны быть объединены?
У меня есть события и фотографии, а затем комментарии для обоих. Прямо сейчас у меня есть две таблицы комментариев, одна для комментариев, связанных с событиями, и другая для комментариев к фотографиям. Схема похожа на это:
CREATE TABLE EventComments
(
CommentId int,
EventId int,
Comment NVarChar(250),
DateSubmitted datetime
)
CREATE TABLE PhotoComments
(
CommentId int,
PhotoId int,
Comment NVarChar(250),
DateSubmitted datetime
)
У меня вопрос, стоит ли мне их объединить и добавить отдельную таблицу перекрестных ссылок, но я не могу придумать, как это сделать правильно. Я думаю, что это должно быть хорошо, что вы думаете?
редактировать
Основываясь на ответе Уолтера (и небольшом чтении), я придумал это:
CREATE TABLE Comments
(
CommentId int,
Comment NVarChar(250),
DateSubmitted datetime
CONTRAINT [PK_Comments] PRIMARY KEY
(
CommentId
)
)
CREATE TABLE EventComments
(
CommentId int,
EventId int
)
CREAT TABLE PhotoComments
(
CommentId int,
PhotoId int
)
ALTER TABLE EventComments ADD CONSTRAINT FK_EventComments FOREIGN KEY (CommentId) REFERENCES Comments(CommentId)
ALTER TABLE PhotoComments ADD CONSTRAINT FK_PhotoComments FOREIGN KEY (CommentId) REFERENCES Comments(CommentId)
Есть ли какие-либо различия в производительности между структурами? Мне это кажется немного предпочтением. Я вижу преимущества во второй схеме: если я хочу добавить некоторую специфичность в комментарии к событиям или фотографии, у меня есть отдельная таблица для этого, и если я хочу, чтобы оба совместно использовали новое свойство, есть одна таблица для добавить новое свойство.
4 ответа
Комментарии, PhotoComments и EventComments связаны в шаблоне, называемом "специализация обобщения". Этот шаблон обрабатывается простым наследованием в объектно-ориентированных языках. Немного сложнее настроить схему таблиц, которые будут отображать один и тот же шаблон.
Но это хорошо понято. Быстрый поиск в Google по "реляционному моделированию специализации обобщения" даст вам несколько хороших статей на эту тему.
Если вы объедините их, это испортит структуру ключей. У вас должны быть нулевые внешние ключи или "мягкая" структура клавиш и типа. Я бы держал их отдельно.
Вы можете объединить их и добавить поле, которое указывает, будет ли это для фотографии или события.
Вам понадобятся два внешних ключа; один для фотографий и один для событий, но наличие их в одной таблице позволяет написать единый набор кода для обработки всех комментариев.
Но я разорван. Будет лучше, если вы будете хранить их отдельно, при условии, что вам никогда не придется смешивать два типа комментариев в одном и том же списке (что потребует UNION).
Мой личный стиль дизайна - объединить их, а затем добавить целочисленный флаг, чтобы указать, для чего предназначен комментарий. Это также даст мне масштабируемость на случай, если я захочу добавить больше позже.