Джеймс прав в изложении ...
Также убедитесь, что вы не используете поле, которое может ссылаться на более чем один тип первичного ключа. Поле mpid в вашей таблице message_participants не должно ссылаться как на пользователей, так и на группы.
Перегрузка столбца внешнего ключа всегда плохой дизайн, который приводит к плохой целостности данных и другим проблемам.
Если ваша цель состоит в том, чтобы иметь «временных получателей» - то есть, если я присоединяюсь к группе сегодня, я сразу же вижу все сообщения этой группе со вчерашнего дня - тогда ваша модель близка. Описывать получателя как «участника» - плохая дикция, но я подойду к проблеме следующим образом ...
TABLE MessageRecipients
(
Message_Id INT NOT NULL
CONSTRAINT FK__MessagesRecipients__Messages
FOREIGN KEY (Message_Id) REFERENCES Messages (Message_Id),
RecipientType_Code CHAR(1) NOT NULL
CONSTRAINT CK__MessageRecipients__RecipientType_Code_Domain
CHECK RecipientType_Code IN ('U','G'),
User_Id NULL
CONSTRAINT FK__MessagesRecipients__Users
FOREIGN KEY (User_Id) REFERENCES Users (User_Id),
Group_Id NULL
CONSTRAINT FK__MessagesRecipients__Groups
FOREIGN KEY (Group_Id) REFERENCES Groups (Group_Id),
CONSTRAINT CK__MessageRecipients__RecipientType_Validity
CHECK (RecipientType_Code = 'U' AND User_Id IS NOT NULL AND Group_Id IS NULL)
OR (RecipientType_Code = 'G' AND User_Id IS NULL AND Group_Id IS NOT NULL)
)
В противном случае, если вы хотите, чтобы сообщения были привязаны к пользователям независимо от членства в группе (т. Е. Если я выбрасываю группу, я все еще вижу сообщения из этой группы), то я бы предложил подход Джеймса.