Você pode querer resolver isso da seguinte forma:
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)
);
A chave primária composta
(comment_id, user_id)
na tabela de interseção
comments_votes
impedirá que os usuários votem várias vezes nos mesmos comentários. Vamos inserir alguns dados no esquema acima:
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');
Agora vamos adicionar alguns votos para o usuário 1:
INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);
O acima significa que o usuário 1 deu um voto do tipo 1 nos comentários 1 e 2.
Se o mesmo usuário tentar votar novamente em um desses comentários, o banco de dados o rejeitará:
INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Se você estiver usando o InnoDB mecanismo de armazenamento, também será aconselhável usar chave estrangeira restrições no
comment_id
e user_id
campos da tabela de interseção. No entanto, observe que MyISAM
, o mecanismo de armazenamento padrão no MySQL, não impõe restrições de chave estrangeira: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;
Essas chaves estrangeiras garantem que uma linha em
comments_votes
nunca terá um comment_id
ou user_id
valor que não existe nos comments
e users
tabelas, respectivamente. As chaves estrangeiras não precisam ter um banco de dados relacional funcional, mas são definitivamente essenciais para evitar relacionamentos quebrados e linhas órfãs (ou seja, integridade referencial
). Na verdade, a integridade referencial é algo que seria muito difícil de aplicar se você armazenasse arrays serializados em um único campo de banco de dados.