2010-08-05 5 views
42

Есть ли способ сохранить массив в поле mysql? Я создаю систему оценки комментариев, поэтому я хочу хранить массивы идентификаторов пользователей для предотвращения множественных голосований. Я собираюсь создать новую таблицу, содержащую идентификатор комментария и массив идентификаторов пользователей, которые проголосовали за этот комментарий. Затем я присоединяюсь к таблице комментариев и этой таблице и проверяю, существует ли текущий идентификатор пользователя в массиве избирателей или заметке. Если это произойдет, то значки голосования будут отключены. Я думаю, что я буду препятствовать использованию запроса mysql в цикле таким образом.Как хранить массив в mysql?

Вы знаете, какие лучшие способы?

+0

Я знаю, что это легкая задача, чтобы предотвратить несколько отзывов от одного пользователя, но мне нужно, чтобы отобразить инвалид иконки для пользователей, которые уже проголосовали на конкретном комментарии и использовать как несколько MySQL запросов. Как я вижу, функция сериализации справится с этой проблемой ... –

+0

Есть ли причина, по которой вы считаете, что будет сложно, если вы будете использовать нормализованный подход? –

+0

@ Даниэль Вассалло Что значит нормализованный подход? –

ответ

42

Вы всегда можете сериализовать массив и сохранить его в базе данных.
PHP Serialize

После этого вы можете безриализовать массив.

+33

Это нарушает реляционную модель. – outis

+4

Это было идеально для моей ситуации. Просто попробуйте сохранить переменный массив для пользовательских настроек. Спасибо, грант. – CA3LE

+3

Это может иметь большее значение в зависимости от того, как вы собираетесь получить доступ к этим данным позже. Если вам не нужен один конкретный элемент из массива за раз, но только весь массив (именно это я и хотел), это решение просто отлично. –

4

у вас должно быть три таблицы: пользователи, комментарии и комментаторы.

comment_users имеет только два поля: fk_user_id и fk_comment_id

Таким образом, вы можете сохранить вашу производительность до максимума :)

13

Рассмотрим нормализацию структуры таблицы в комментарии, и отдельную таблицу голосов.

Таблица «комментарии»:

id 
comment 
user 
... 

стол «голоса»:

user_id 
comment_id 
vote (downvote/upvote) 

это позволит неограниченное число голосов без необходимости иметь дело с пределами поля базы данных.

Кроме того, у вас могут возникнуть будущие потребности в таких операциях, как «показать все голоса, которые пользователь произнес», удаление конкретных голосов или ограничение максимального количества голосов в день. Эти операции мертвы легко и быстро реализуются с нормализованной структурой и ужасно медленны и сложны в сериализованном массиве.

+4

Весь смысл вопроса ОФ, вероятно, избегает использования нескольких таблиц. – user18490

4

Я бы предпочел более нормализовать структуру вашего стола, что-то вроде;

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


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


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

Теперь его проще в обслуживании! И MySQL принимает только один голос за пользователя и комментарий.

1

создать таблицу, как это,

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

Таким образом, вы можете проверить отправил ли пользователь комментарии не .. Помимо этого должны быть столы для Comments и Users с соответствующими идентификаторами

53

Вы можете решить это следующим образом:

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

композиционный primary key(comment_id, user_id) на intersection tablecomments_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 таблиц, соответственно. Внешним ключам не требуется иметь рабочую реляционную базу данных, но они, безусловно, необходимы для предотвращения нарушенных отношений и сиротских строк (то есть referential integrity).

На самом деле, ссылочная целостность - это то, что было бы очень сложно обеспечить, если бы вы храпили сериализованные массивы в одно поле базы данных.

+2

Это должен быть один подтвержденный ответ. – tomsihap

1

Если вы просто хранить данные в базе данных, как если бы вы были вручную поставив его в массив

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

Затем, когда вы тянете из базы данных, используйте функцию взрываются()

$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/>"; 
} 

Нравится так!

0

Хранение json или serialized массив - лучшее решение на данный момент. В некоторых ситуациях (зачистка " 'символы) JSON может получать неприятности, но сериализации должны быть большим выбором

. Примечание:. Если изменить сериализованные данные вручную, вы должны быть осторожны по количеству символов

1

Вы можете . использовать функцию PHP сериализации для хранения массива в MySQL

<?php 

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

$string_array = serialize($array); 

echo $string_array; 

?> 

выход это будет:

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

И то вы можете использовать функцию unserialize php для декодирования данных.

Я думаю, вы должны посетить this page on storing array in mysql.

Смежные вопросы