I have 3 tables for a messaging system
Conversations
| id |
Participants
| id | conversation | user |
Messages
| id | conversation | user | text |
I want to restrict messages being inserted into a conversation if the user is not part of through the participants table
I think I could structure it in a better way by having participant in the messages table. But then id have to do an extra query by seeing what a users participant id is before inserting a message.
Id rather do it with a constraint or foreign key. What would the best way to do this be?
You can use EXISTS
in the INSERT
statement:
INSERT INTO Messages(id, conversation, user, text)
SELECT :id, :conversation, :user, :text
FROM dual
WHERE EXISTS (
SELECT 1
FROM Participants
WHERE conversation = :conversation AND user = :user
)
If your version of MySql is 8.0+ you can omit FROM DUAL
.
Replace :id
, :conversation
, :user
and :text
with the column values that you want to insert.
If ID
is an autoincremented integer change to:
INSERT INTO Messages(conversation, user, text)
SELECT :conversation, :user, :text
................................
Or, first create a UNIQUE
constraint for the combination of columns conversation
and user
in Participants
:
ALTER TABLE Participants ADD CONSTRAINT unique_conv_user UNIQUE (conversation, user)
and then add a foreign key constraint for the combination of columns conversation
and user
in Messages
:
ALTER TABLE Messages
ADD CONSTRAINT fk_conv_user
FOREIGN KEY (conversation, user) REFERENCES Participants(conversation, user);
This way you can only insert new rows in Messages
if the combination of conversation
and user
already exists in Participants
.
Is this a trick question? You just described the main use case of referential integrity in a data base. Make Messages.(ID, User) a foreign key of the Participants table.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.