Определение нескольких внешних ключей в одной таблице для нескольких таблиц - PullRequest
14 голосов
/ 29 октября 2010

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

Пост :

  • id
  • title
  • body

Фото :

  • id
  • filepath

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

  • id
  • post_id
  • body

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

Ответы [ 5 ]

10 голосов
/ 29 октября 2010

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

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

alt text

10 голосов
/ 29 октября 2010

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

 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 голосов
/ 29 октября 2010

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

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

 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
0 голосов
/ 29 октября 2010

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

Сообщение:

  • * 1006 сообщения дан *
  • название
  • корпус

PostComment:

  • CommentID
  • post_id body

Фото:

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

PhotoComment:

  • CommentID
  • photo_id
  • корпус

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

0 голосов
/ 29 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...