Определение нескольких внешних ключей в одной таблице для нескольких таблиц

У меня есть 3 модели:

Сообщение:

  • Я бы
  • заглавие
  • тело

Фото:

  • Я бы
  • Путь файла

Комментарий:

  • Я бы
  • post_id
  • тело

и соответствующие таблицы в БД. Теперь, если я хочу иметь комментарии только к своим сообщениям, я могу просто добавить следующий внешний ключ: ALTER TABLE comment ADD FOREIGN KEY (post_id) REFERENCES post (id), Но я хочу иметь комментарии для других моделей (фото, профиль, видео и т. Д.) И хранить все комментарии в одной таблице. Как я могу определить внешние ключи (мне определенно нужны FK для ORM) в таком случае?

5 ответов

Решение

Вы могли бы сделать это:

 post:
  * post_id (PK)
  * title
  * body

 photo:
  * photo_id (PK)
  * filepath

 comment:
  * comment_id (PK)
  * body

 comment_to_post
  * comment_id (PK) -> FK to comment.comment_id
  * post_id (PK) -> FK to post.post_id

 comment_to_photo
  * comment_id (PK) -> FK to comment.comment_id
  * photo_id (PK) -> FK to photo.photo_id

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

Найдите что-то общее для публикации, профиля и т. Д. - я использовал Entity из-за отсутствия лучшего слова, то подтип.

  • В этой модели один объект может иметь много комментариев, один комментарий принадлежит только одному объекту.

альтернативный текст

Если вы хотите знать, можете ли вы иметь несколько внешних ключей для одного столбца, тогда ответ - нет, вы не можете.

Вы можете иметь отдельные внешние ключи, если хотите. Таким образом, вы можете изменить таблицу комментариев следующим образом:

 comment:
  * comment_id (PK)
  * PostID (FK to Post.PostID)
  * PhotoID (FK to <Photo>.PhotoID)
  * ProfileID (FK to <Profile>.ProfileID)
  * Body

И вам нужно будет убедиться, что вы разрешаете пустые значения в столбцах PostID,PhotoID и ProfileID в таблице комментариев, а также, возможно, устанавливаете значение по умолчанию, равное null.

Вот DDL для достижения этой цели -

Create table Photo
(
PhotoID int,
PhotoDesc varchar(10),
Primary key (PhotoID)
)

Create table Post
(
PostID int,
PostDesc varchar(10),
Primary key (PostID)
)

Create table Profiles
(
ProfileId int,
ProfileDesc varchar(10),
Primary key (ProfileId)
)

Create table Comment  
(
CommentID int,
PhotoID int,
PostID int,
ProfileId int,
body varchar(10),
Primary key (CommentID),
Foreign key (PhotoID) references Photo(PhotoID),
Foreign key (PostID) references Post(PostID),
Foreign key (ProfileId) references Profiles(ProfileId)
)

insert into Photo values (1,'Photo1')
insert into Photo values (2,'Photo2')
insert into Photo values (3,'Photo3')

insert into Post values (11,'Post1')
insert into Post values (12,'Post2')
insert into Post values (13,'Post3')

insert into Profiles values (111,'Profiles1')
insert into Profiles values (112,'Profiles2')
insert into Profiles values (113,'Profiles3')

insert into Comment (CommentID,PhotoID,body) values (21,1,'comment1')
insert into Comment (CommentID,PhotoID,body) values (22,3,'comment2')
insert into Comment (CommentID,PostID,body) values (23,11,'comment3')
insert into Comment (CommentID,PostID,body) values (24,12,'comment4')
insert into Comment (CommentID,ProfileId,body) values (25,112,'comment5')
insert into Comment (CommentID,ProfileId,body) values (26,113,'comment6')

-- to select comments seperately for Photos, profiles and posts
select * from Comment where PhotoID is not null
select * from Comment where ProfileId is not null
select * from Comment where PostID is not null

В этом случае вы можете добавить поле ENUM, которое будет содержать "фото", "профиль"... Это будет вторая часть внешнего ключа

Поскольку комментарии к фотографиям - это не то же самое, что комментарии к публикациям, я буду хранить их в отдельных связанных таблицах. Так что я бы имел:

Сообщение:

  • сообщения дан
  • заглавие
  • тело

Оставьте комментарий:

  • CommentID
  • post_id body

Фото:

  • Регистрационный номер фото
  • Путь файла

PhotoComment:

  • CommentID
  • регистрационный номер фото
  • тело

Использование идентификатора в качестве имени вашего ПК является плохой практикой, так как это значительно усложняет создание отчетов и повышает вероятность непреднамеренного присоединения к неправильной таблице в сложном запросе. Если вы используете tablenameID и последовательно используете одно и то же имя для Fks, тогда также легче увидеть отношения.

Другие вопросы по тегам