Хранение нескольких вариантов голосования в таблице MySQL

У меня есть опрос с неопределенным количеством вариантов (у него может быть только 2 варианта, но также может быть 10, 20 и более вариантов на выбор). Мне нужно сохранить текущий подсчет голосов в таблице MySQL. Я не могу придумать централизованный способ их хранения, за исключением: создайте поле vote_count и сохраните сериализованный массив вариантов голосования, сопоставленных с подсчетами. Когда новые данные голосования поступают в это поле, оно считывается, десериализуется, соответствующие значения увеличиваются, затем поле записывается. Для этого требуется 2 запроса, и в секунду может поступать 5 или более голосов.

Поэтому мне нужен способ хранить подсчет голосов для неизвестного количества вариантов голосования и иметь возможность быстрого доступа к нему (мне нужны актуальные подсчеты для каждого варианта, отображаемого на странице голосования) и быстро обновлять его (когда поступают новые голоса) . Он должен находиться в таблице MySQL. Не существует «верхнего» предела количества вариантов голосования.


person Xeos    schedule 16.07.2013    source источник
comment
Можете ли вы предоставить некоторые примеры данных, чтобы лучше проиллюстрировать вопрос?   -  person Gordon Linoff    schedule 17.07.2013
comment
@GordonLinoff, решение теперь является общепринятым ответом. Представьте, что у меня есть два опроса: Do you agree: yes | no и Do you disagree: yes | no | maybe Теперь мне нужно хранить счетчики для каждого варианта в таблице MySQL. Я не могу просто создать поле для «да», «нет» и «может быть», потому что не каждый опрос использует их все, и может быть 30 или 40 вариантов, которые еще не являются полями, а это означает, что мне нужно каждый раз изменять таблицу создается новый опрос.   -  person Xeos    schedule 17.07.2013


Ответы (2)


Стандартным шаблоном для обработки многозначных атрибутов или повторяющихся значений является добавление второй таблицы.

Рассмотрим заказ на покупку, в котором может быть более одной позиции. Мы представляем позиции в дочерней таблице с внешним ключом для родителя в таблице заказов на покупку:

CREATE TABLE `purchase_order` (id int not null, foo varchar(200), ... );
CREATE TABLE `line_item` (id int not null, order_id int not null, ... ); 
ALTER TABLE `line_item` ADD FOREIGN KEY (order_id) REFERENCES order(id) ;


INSERT INTO purchase_order (id, foo) VALUES (101, 'bar'); 

INSERT INTO purchase_order (id, order_id) VALUES (783, 101);
INSERT INTO purchase_order (id, order_id) VALUES (784, 101);
INSERT INTO purchase_order (id, order_id) VALUES (785, 101);

Мы можем получить количество позиций, связанных с заказом на покупку, например:

SELECT COUNT(1)
  FROM line_item 
 WHERE order_id = 101; 

Или мы можем получить количество позиций для каждого заказа на покупку, например:

SELECT o.id, COUNT(l.id) AS count_line_itesm
  FROM purchase_order o
  LEFT
  JOIN line_item l
    ON l.order_id = o.id
 GROUP BY o.id 

В вашем случае, какие объекты вам нужно представлять (человек, место, вещь, концепция или событие; которые могут быть однозначно идентифицированы, и вам нужно хранить информацию о них.

Мне трудно понять, какие сущности вам нужно представлять.

poll -
poll_question - a single question on a given poll
poll_question_answer - a possible answer to a question to a given poll question
voter - 
ballot - associated with one voter and one poll (?)
vote - the answer given to a particular poll question

Хороший дизайн базы данных исходит из понимания сущностей и отношений и разработки подходящей модели.

person spencer7593    schedule 16.07.2013
comment
Спасибо. Это то, что я буду делать. Имейте таблицу с вариантами ответов для каждого опроса. - person Xeos; 17.07.2013

Разве вы не можете просто иметь одну таблицу вопросов и другую таблицу возможных ответов (несколько строк на вопрос, сколько хотите). Затем либо сохраните подсчеты в таблице ответов, либо (лучше) создайте другую таблицу фактических введенных ответов (таким образом вы сможете регистрировать сведения о человеке, дающем ответы, и легко использовать СУММ/СЧЁТ, чтобы вычислить, сколько голосов проголосовало каждый вариант есть).

person Kickstart    schedule 16.07.2013
comment
Ага. Собираюсь сделать это. Спенсер ответила первой.. Но все равно спасибо. - person Xeos; 17.07.2013
comment
+1. Это подход, который я бы выбрал, родительская таблица и дочерняя таблица с внешним ключом. - person spencer7593; 17.07.2013
comment
Нет проблем, хотя, кажется, я добрался туда первым ;-) - person Kickstart; 17.07.2013