U kunt dit als volgt aanpakken:
CREATE TABLE comments (
comment_id int,
body varchar(100),
PRIMARY KEY (comment_id)
);
CREATE TABLE users (
user_id int,
username varchar(20),
PRIMARY KEY (user_id)
);
CREATE TABLE comments_votes (
comment_id int,
user_id int,
vote_type int,
PRIMARY KEY (comment_id, user_id)
);
De samengestelde primaire sleutel
(comment_id, user_id)
op de kruisingstabel
comments_votes
voorkomt dat gebruikers meerdere keren stemmen op dezelfde opmerkingen.
Laten we wat gegevens invoegen in het bovenstaande schema:
INSERT INTO comments VALUES (1, 'first comment');
INSERT INTO comments VALUES (2, 'second comment');
INSERT INTO comments VALUES (3, 'third comment');
INSERT INTO users VALUES (1, 'user_a');
INSERT INTO users VALUES (2, 'user_b');
INSERT INTO users VALUES (3, 'user_c');
Laten we nu wat stemmen toevoegen voor gebruiker 1:
INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);
Het bovenstaande betekent dat gebruiker 1 een stem van type 1 heeft gegeven op opmerkingen 1 en 2.
Als dezelfde gebruiker opnieuw probeert te stemmen op een van die opmerkingen, zal de database het weigeren:
INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Als u de InnoDB
gaat gebruiken opslagengine, is het ook verstandig om foreign key
te gebruiken beperkingen op de comment_id
en user_id
velden van de intersectietabel. Houd er echter rekening mee dat MyISAM
, de standaard opslag-engine in MySQL, dwingt geen externe sleutelbeperkingen af:
CREATE TABLE comments (
comment_id int,
body varchar(100),
PRIMARY KEY (comment_id)
) ENGINE=INNODB;
CREATE TABLE users (
user_id int,
username varchar(20),
PRIMARY KEY (user_id)
) ENGINE=INNODB;
CREATE TABLE comments_votes (
comment_id int,
user_id int,
vote_type int,
PRIMARY KEY (comment_id, user_id),
FOREIGN KEY (comment_id) REFERENCES comments (comment_id),
FOREIGN KEY (user_id) REFERENCES users (user_id)
) ENGINE=INNODB;
Deze externe sleutels garanderen dat een rij in comments_votes
zal nooit een comment_id
. hebben of user_id
waarde die niet bestaat in de comments
en users
tabellen resp. Buitenlandse sleutels zijn niet vereist om een werkende relationele database te hebben, maar ze zijn zeker essentieel om verbroken relaties en weesrijen te voorkomen (bijv. referentiële integriteit
).
In feite is referentiële integriteit iets dat heel moeilijk te handhaven zou zijn geweest als je geserialiseerde arrays in één databaseveld zou opslaan.