Potresti voler affrontare questo problema come segue:
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)
);
La chiave primaria
composita (comment_id, user_id)
sulla tabella di intersezione
comments_votes
impedirà agli utenti di votare più volte sugli stessi commenti.
Inseriamo alcuni dati nello schema sopra:
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');
Ora aggiungiamo alcuni voti per l'utente 1:
INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);
Quanto sopra significa che l'utente 1 ha dato un voto di tipo 1 sui commenti 1 e 2.
Se lo stesso utente prova a votare di nuovo su uno di quei commenti, il database lo rifiuterà:
INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Se utilizzerai InnoDB
motore di archiviazione, sarà anche saggio utilizzare chiave esterna
vincoli su comment_id
e user_id
campi della tabella di intersezione. Tuttavia, tieni presente che MyISAM
, il motore di archiviazione predefinito in MySQL, non applica vincoli di chiave esterna:
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;
Queste chiavi esterne garantiscono che una riga in comments_votes
non avrà mai un comment_id
o user_id
valore che non esiste nei comments
e users
rispettivamente tabelle. Le chiavi esterne non sono necessarie per avere un database relazionale funzionante, ma sono sicuramente essenziali per evitare relazioni interrotte e righe orfane (ad es. integrità referenziale
).
In effetti, l'integrità referenziale è qualcosa che sarebbe stato molto difficile da applicare se si fossero archiviati array serializzati in un unico campo di database.