Možná to budete chtít vyřešit následovně:
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)
);
Složený primární klíč
(comment_id, user_id)
na tabulce křižovatek
comments_votes
zabrání uživatelům hlasovat vícekrát o stejných komentářích.
Vložme některá data do výše uvedeného schématu:
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');
Nyní přidáme nějaké hlasy pro uživatele 1:
INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);
Výše uvedené znamená, že uživatel 1 dal hlas typu 1 pro komentáře 1 a 2.
Pokud se stejný uživatel pokusí znovu hlasovat pro jeden z těchto komentářů, databáze jej odmítne:
INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Pokud budete používat InnoDB
úložiště, bude také moudré použít cizí klíč
omezení na comment_id
a user_id
pole průsečíkové tabulky. Pamatujte však, že MyISAM
, výchozí modul úložiště v MySQL, nevynucuje omezení cizích klíčů:
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;
Tyto cizí klíče zaručují, že řádek v comments_votes
nikdy nebude mít comment_id
nebo user_id
hodnota, která v comments
neexistuje a users
tabulky, resp. Cizí klíče nejsou vyžadovány pro fungující relační databázi, ale jsou rozhodně nezbytné, aby se předešlo přerušeným vztahům a osiřelým řádkům (např. referenční integrita
).
Ve skutečnosti je referenční integrita něco, co by bylo velmi obtížné prosadit, pokud byste ukládali serializovaná pole do jednoho databázového pole.