Подтвердить что ты не робот

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

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

Сообщение

  • ID
  • название
  • Тело

Фото

  • ID
  • путь_к_файлу

Комментарий

  • ID
  • post_id
  • Тело

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

4b9b3361

Ответ 1

Вы можете сделать это:

 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

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

Ответ 2

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

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

alt text

Ответ 3

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

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

 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

Ответ 4

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

Ответ 5

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

Сообщение:

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

PostComment:

  • CommentID
  • post_id

Фото:

  • PHOTOID
  • путь_к_файлу

PhotoComment:

  • CommentID
  • photo_id
  • Тело

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