Es posible que desee hacer frente a esta de la siguiente manera:
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)
);
El compuesto primary key(comment_id, user_id)
en el intersection tablecomments_votes
evitará que los usuarios voten varias veces en los mismos comentarios.
Insertemos algunos datos en el esquema anterior:
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');
Ahora vamos a añadir algunos votos para el usuario 1:
INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);
Lo anterior significa que el usuario 1 dio un voto de tipo 1 en los comentarios 1 y 2.
Si el mismo usuario intenta votar nuevamente en uno de esos comentarios, la base de datos lo rechazará:
INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Si va a utilizar el motor InnoDB de almacenamiento, sino que también será aconsejable utilizar foreign key restricciones sobre las comment_id
y user_id
campos de la tabla de intersección. Sin embargo tenga en cuenta que MyISAM, el motor de almacenamiento por defecto en MySQL, no impone restricciones de clave externa:
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;
Estas claves externas garantizar que una fila en comments_votes
nunca tendrá un valor comment_id
o user_id
que no existe en el comments
y users
tablas, respectivamente. No es necesario que las claves foráneas tengan una base de datos relacional activa, pero son definitivamente esenciales para evitar relaciones rotas y filas huérfanas (es decir, referential integrity).
De hecho, la integridad referencial es algo que habría sido muy difícil de aplicar si tuviera que almacenar matrices serializadas en un solo campo de base de datos.
Sé que es una tarea fácil para evitar múltiples votaciones de un usuario, pero necesito para mostrar los iconos de movilidad reducida para los usuarios que ya se ha votado en el comentario en particular y utilizar el menor número de MySQL consultas como sea posible. Como veo, la función de serializar manejará este problema ... –
¿Hay alguna razón por la que piense que será difícil si usa el método normalizado? –
@Daniel Vassallo ¿Qué quiere decir con enfoque normalizado? –