web-dev-qa-db-fra.com

Comment stocker un tableau dans mysql?

Est-il possible de stocker un tableau dans le champ mysql? Je crée un système d'évaluation des commentaires, je souhaite donc stocker les tableaux d'identifiants d'utilisateurs afin d'éviter plusieurs votes. Je vais créer une nouvelle table contenant l'id de commentaire et le tableau d'identifiants d'utilisateurs ayant voté pour ce commentaire. Ensuite, je vais joindre le tableau des commentaires et ce tableau et vérifier si l'ID utilisateur actuel existe dans le tableau des votants ou dans la note. Si c'est le cas, les icônes de vote seraient désactivées. Je pense que je vais empêcher d'utiliser mysql en boucle de cette façon.

Vous arrive-t-il de connaître de meilleurs moyens?

45
King Julien

Vous pouvez toujours sérialiser le tableau et le stocker dans la base de données.
PHP Sérialiser

Vous pouvez ensuite désérialiser le tableau si nécessaire.

48
Grant Collins

Vous voudrez peut-être aborder ceci comme suit:

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 clé composite primaire(comment_id, user_id) sur le tableau d'intersection comments_votes empêchera les utilisateurs de voter plusieurs fois sur les mêmes commentaires.

Insérons quelques données dans le schéma ci-dessus:

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');

Ajoutons maintenant quelques votes pour l'utilisateur 1:

INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);

Ce qui précède signifie que l'utilisateur 1 a voté de type 1 sur les commentaires 1 et 2.

Si le même utilisateur essaie de voter à nouveau sur l'un de ces commentaires, la base de données le rejettera:

INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'

Si vous utilisez le moteur de stockage InnoDB , il sera également judicieux d’utiliser clé étrangère contraintes sur les champs comment_id et user_id de la table des intersections. Cependant, notez que MyISAM , le moteur de stockage par défaut de MySQL, n’impose pas les contraintes de clé étrangère:

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;

Ces clés étrangères garantissent qu'une ligne dans comments_votes n'aura jamais une valeur comment_id ou user_id qui n'existe pas dans les tables comments et users, respectivement. Les clés étrangères ne sont pas obligées d'avoir une base de données relationnelle opérationnelle, mais elles sont essentielles pour éviter les relations brisées et les lignes orphelines (c'est-à-dire. intégrité référentielle ).

En fait, l’intégrité référentielle est très difficile à appliquer si vous aviez stocké des tableaux sérialisés dans un seul champ de base de données.

60
Daniel Vassallo

Envisagez de normaliser la structure du tableau en commentaires et en un tableau de votes séparé.

Tableau "commentaires":

id
comment
user
...

Tableau "votes":

user_id  
comment_id
vote (downvote/upvote)

cela permettrait un nombre illimité de votes sans avoir à gérer les limites d'un champ de base de données. 

Vous pouvez également avoir besoin d'opérations telles que "afficher tous les votes d'un utilisateur", supprimer des votes spécifiques ou limiter le nombre maximal de votes par jour. Ces opérations sont extrêmement simples et rapides à mettre en œuvre avec une structure normalisée, et horriblement lente et complexe dans un tableau sérialisé.

13
Pekka 웃

vous devriez avoir trois tables: utilisateurs, commentaires et comment_users.

comment_users n'a que deux champs: fk_user_id et fk_comment_id

De cette façon, vous pouvez maintenir vos performances au maximum :)

4
Dennis Haarbrink

Je préférerais normaliser davantage la structure de votre table, quelque chose comme;

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


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


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

Maintenant, c'est plus facile à entretenir! Et MySQL n'accepte qu'un seul vote par utilisateur et par commentaire.

4
Björn

créer un tableau comme ça,

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

De cette façon, vous pouvez vérifier si l'utilisateur qui a posté les commentaires ne sont pas .. En dehors de cela, il devrait y avoir des tables pour Comments et Users avec leurs identifiants respectifs

Si vous ne stockez que les données dans une base de données comme vous le feriez si vous les placiez manuellement dans un tableau

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

Ensuite, lorsque vous extrayez de la base de données, utilisez la fonction 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/>";
}

Ainsi!

1
Hardline_98

Vous pouvez enregistrer votre tableau en tant que JSON.
il existe une documentation pour le type de données json: https://dev.mysql.com/doc/refman/5.7/en/json.html

0
Roberto Murguia

Vous pouvez utiliser la fonction php serialize pour stocker array dans MySQL.

<?php

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

$string_array = serialize($array);

echo $string_array;

?>

La sortie sera: 

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

Et ensuite, vous pouvez utiliser la fonction php unserialize pour décoder les données.

Je pense que vous devriez visiter cette page sur le stockage de tableaux dans mysql .

0
Shubham Kumar

Stocker avec json ou serialized array est la meilleure solution pour le moment . Dans certaines situations (rognage des caractères), json risque de poser problème, mais sérialiser devrait constituer un excellent choix.

Remarque: Si vous modifiez manuellement les données sérialisées, vous devez faire attention au nombre de caractères.

0
Bŭnyãmin Akçãy