Есть ли способ сохранить массив в поле MySQL? Я создаю систему оценки комментариев, поэтому я хочу хранить массивы пользовательских идентификаторов, чтобы предотвратить множественные голосования. Я собираюсь создать новую таблицу, которая содержит идентификатор комментария и массив идентификаторов пользователей, которые проголосовали за этот комментарий. Затем я' Присоединюсь к таблице комментариев и этой таблице и проверим, существует ли текущий идентификатор пользователя в массиве или примечании избирателей. Если это так, значки голосования будут отключены. Я думаю, что я не позволю использовать MySQL запрос в цикле таким образом.
Вы знаете какие-нибудь лучшие способы?
Вы всегда можете сериализовать массив и сохранить его в базе данных.
PHP Serialize
Затем вы можете десериализовать массив, когда это необходимо.
Рассмотрите возможность нормализации структуры таблицы в комментариях и отдельной таблице голосов.
Таблица «комментарии»:
id
comment
user
...
Таблица «голосов»:
user_id
comment_id
vote (downvote/upvote)
это позволит неограниченное количество голосов без необходимости иметь дело с пределами поля базы данных.
Кроме того, в будущем вам могут потребоваться такие операции, как «показать все голоса, отданные пользователем», удаление определенных голосов или ограничение максимального количества голосов в день. Эти операции невероятно легко и быстро реализовать с нормализованной структурой и ужасно медленными и сложными в сериализованном массиве.
у вас должно быть три таблицы: пользователи, комментарии и comment_users.
comment_users имеет всего два поля: fk_user_id и fk_comment_id
Таким образом вы можете поддерживать максимальную производительность :)
Я бы предпочел больше нормализовать структуру вашей таблицы, например:
COMMENTS
-------
id (pk)
title
comment
userId
USERS
-----
id (pk)
name
email
COMMENT_VOTE
------------
commentId (pk)
userId (pk)
rating (float)
Теперь это проще поддерживать! А MySQL принимает только один голос за пользователя и комментарий.
создать такую таблицу,
CommentId UserId
---------------------
1 usr1
1 usr2
Таким образом вы можете проверить, не являются ли опубликованные пользователем комментарии ..
Кроме этого, должны быть таблицы для комментариев
и пользователей
с соответствующими идентификаторами
Вы можете решить эту проблему следующим образом:
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)
);
Составной первичный ключ (comment_id, user_id)
в таблице пересечений comments_votes
не позволит пользователям голосовать несколько раз за одни и те же комментарии.
Давайте вставим некоторые данные в приведенную выше схему:
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');
Теперь добавим несколько голосов для пользователя 1:
INSERT INTO comments_votes VALUES (1, 1, 1);
INSERT INTO comments_votes VALUES (2, 1, 1);
Вышеприведенное означает, что пользователь 1 отдал голос типа 1 за комментарии 1 и 2.
Если тот же пользователь попытается проголосовать снова за один из этих комментариев, база данных отклонит его:
INSERT INTO comments_votes VALUES (1, 1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
Если вы будете использовать механизм хранения InnoDB, будет разумно также использовать foreign key ограничения на поля comment_id
и user_id
таблицы пересечений. Однако обратите внимание, что MyISAM, механизм хранения по умолчанию в MySQL, не применяет ограничения внешних ключей:
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;
Эти внешние ключи гарантируют, что строка в comments_votes
никогда не будет иметь comment_id
или user_id
значения, не существующего в comments
и users
таблицах, соответственно. Внешние ключи не обязательны для создания работающей реляционной базы данных, но они определенно необходимы, чтобы избежать разрыва связей и бесхозных строк (т.е. ссылочной целостности).
На самом деле, ссылочная целостность - это то, что было бы очень трудно обеспечить, если бы вы хранили сериализованные массивы в одном поле базы данных.