2010-08-05 21 views
42

¿Hay alguna forma de almacenar una matriz en el campo mysql? Estoy creando un sistema de calificación de comentarios, así que quiero almacenar las matrices de identificadores de usuario para evitar múltiples votaciones. Voy a crear una nueva tabla que contenga el ID del comentario y la matriz de ID de usuario que votó en este comentario. Luego uniré la tabla de comentarios y esta tabla y verificará si el ID de usuario actual existe en la matriz o nota de los votantes. Si lo hace, los iconos de votación se desactivarán. Creo que evitaré usar la consulta mysql en el ciclo de esta manera.¿Cómo almacenar una matriz en mysql?

¿Conoces alguna manera mejor?

+0

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 ... –

+0

¿Hay alguna razón por la que piense que será difícil si usa el método normalizado? –

+0

@Daniel Vassallo ¿Qué quiere decir con enfoque normalizado? –

Respuesta

42

Siempre puede serializar la matriz y almacenarla en la base de datos.
PHP Serialize

A continuación, puede deserializar la matriz cuando sea necesario.

+33

Esto rompe el modelo relacional. – outis

+4

Esto fue perfecto para mi situación. Solo intento almacenar una matriz variable para la configuración del usuario. Gracias grant. – CA3LE

+3

Esto puede tener más sentido dependiendo de cómo va a acceder a estos datos más adelante. Si no necesita un elemento en particular de la matriz a la vez, sino solo toda la matriz (que es lo que yo quería), esta solución está bien. –

4

debe tener tres tablas: usuarios, comentarios y comentar_users.

comment_users tiene sólo dos campos: fk_user_id y fk_comment_id

De esa forma usted puede mantener su rendimiento hasta un máximo :)

13

Considere la normalización de la estructura de la tabla en un comentario, y una tabla separada votos.

Tabla "comentarios":

id 
comment 
user 
... 

Tabla "votos":

user_id 
comment_id 
vote (downvote/upvote) 

Esto permitiría a un número ilimitado de votos sin necesidad de tener que lidiar con los límites de un campo de base de datos.

Además, puede tener necesidades futuras para operaciones como "mostrar todos los votos que un usuario ha emitido", eliminar votos específicos o limitar el número máximo de votos por día. Estas operaciones son fáciles de implementar y rápidas con una estructura normalizada, y terriblemente lentas y complejas en una matriz serializada.

+4

El objetivo de la pregunta de OP es probablemente evitar el uso de varias tablas. – user18490

4

Prefiero normalizar más la estructura de la mesa, algo así como;

COMMENTS 
------- 
id (pk) 
title 
comment 
userId 


USERS 
----- 
id (pk) 
name 
email 


COMMENT_VOTE 
------------ 
commentId (pk) 
userId (pk) 
rating (float) 

¡Ahora es más fácil de mantener! Y MySQL solo acepta un voto por usuario y comentario.

1

crear tabla como ésta,

CommentId UserId 
--------------------- 
    1   usr1 
    1   usr2 

De esta manera se puede comprobar si el usuario ha escrito los comentarios no son .. Aparte de esto debe haber mesas para Comments y Users con respectiva identificación de

53

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.

+2

Esta debería ser la única respuesta validada. – tomsihap

1

Si usted acaba de almacenar los datos en una base de datos como lo haría si estuviera poniendo manualmente en una matriz

"INSERT INTO database_name.database_table (`array`) 
    VALUES 
    ('One,Two,Three,Four')"; 

Entonces, cuando usted está tirando de la base de datos, utilice la función explode()

$sql = mysql_query("SELECT * FROM database_name.database_table"); 
$numrows = mysql_num_rows($sql); 
if($numrows != 0){ 
    while($rows = mysql_fetch_assoc($sql)){ 
     $array_from_db = $rows['array']; 
    } 
}else{ 
    echo "No rows found!".mysql_error(); 
} 
$array = explode(",",$array_from_db); 
foreach($array as $varchar){ 
    echo $varchar."<br/>"; 
} 

¡Me gusta!

0

Almacenar con json o serialized matriz es la mejor solución por el momento. Con algunas situaciones (recorte " 'caracteres) JSON podría estar recibiendo problemas, pero serializar debe ser gran opción

Nota:.. Si cambia los datos serializados de forma manual, es necesario tener cuidado con la cuenta de carácter

1

Puede . utilizar la función de PHP serializar para almacenar matriz en MySQL

<?php 

$array = array("Name"=>"Shubham","Age"=>"17","website"=>"http://mycodingtricks.com"); 

$string_array = serialize($array); 

echo $string_array; 

?> 

salida del será:

a:3{s:4:"Name";s:7:"Shubham";s:3:"Age";s:2:"17";s:7:"website";s:25:"http://mycodingtricks.com";} 

Y entonces puedes usar la función php unserialize para decodificar los datos.

Creo que deberías visitar this page on storing array in mysql.

Cuestiones relacionadas