Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Подсчет голосов
 
 автор: kosta_in_net   (28.01.2011 в 05:01)   письмо автору
 
 

есть 2 таблицы: в одной предложения, в другой связанные с ним количество голосов за и против. Структура:
table1
id int(11) unsigned NOT NULL auto_increment
name varchar(20) NOT NULL

table2
id int(11) unsigned NOT NULL auto_increment
golos tinyint(1) NOT NULL

несущественные в данном случае поля я просто удалил из описания. Таблицы связаны по полю id.
В поле голос заносится либо 1 (за), либо 2 (против). Количество записей в table2 с одинаковым id определяется числом голосовавших. Таким образом, количество голосов за или против, можно определить как count(*) WHERE golos=1 или count(*) WHERE golos=2.

Нужно вывести список предложений и количество голосов за и против, вроде такого:


Предложение                    |  За     | Против
--------------------------------------------------------------------------------------------
пить пиво                        | 2    | 3
пить кофе                        | 3    | 2
плюнуть на все и разойтись по домам        | 1    | 0


Запрос получается вроде такого:


SELECT name,IFNULL(za,0) AS za,IFNULL(protiv,0) AS protiv
FROM table1 AS t1
LEFT JOIN (SELECT id, COUNT(id) AS za FROM table2 WHERE golos=1 GROUP BY id) AS t2 ON t2.id=t1.id
LEFT JOIN (SELECT id, COUNT(id) AS za FROM table2 WHERE golos=2 GROUP BY id) AS t3 ON t3.id=t1.id


Вопрос такой: не лучше ли разделить "за" и "против" на разные поля, чтоб потом выбирать:


SELECT name,za,protiv
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t2.id=t1.id
GROUP BY t1.id 


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

Нужно мнение, исходящее из практического опыта. Ввести 100 000 записей и протестить результат я, конечно, могу. Но не хочется тратить на это целый день. Так что, прошу мнение специалистов.
П.С. Изначально данные приходят из формы:
<input type=radio name='golos' value='0'>Воздержался
<input type=radio name='golos' value='1'>Да
<input type=radio name='golos' value='2'>Нет
Соответственно запись данных:

INSERT INTO table2 (id,golos) VALUES (".$_POST['id'].",".quote_smart(@$_POST['golos'])

Но можно и так (если писать в разные поля):

<input type=radio name='no' value=''>Воздержался
<input type=radio name='za' value='1'>Да
<input type=radio name='protiv' value='1'>Нет
Соответственно запись данных:

INSERT INTO table2 (id,za,protiv) VALUES (".$_POST['id'].",".$_POST['za'].",".$_POST['protiv'])

  Ответить  
 
 автор: Valick   (28.01.2011 в 07:48)   письмо автору
 
   для: kosta_in_net   (28.01.2011 в 05:01)
 

Мнение непрофессионала.
Лично мне не понятно как Вы умудрились связать таблицы по автоинкрементным полям.

Вопрос такой: не лучше ли разделить "за" и "против" на разные поля
Что-то мне подсказывает, что не лучше.

Ввести 100 000 записей и протестить результат я, конечно, могу. Но не хочется тратить на это целый день.
А вот это совсем плохо. Потратив один день Вы получите ни с чем не сравнимый опыт, который останется с Вами навсегда, в противном случае Вы сами никогда не станете профессионалом.
___
Вы читали о нормализации таблиц? Мне кажется изучив нормализацию Вас никогда больше не будут волновать проблемы подобного рода.

  Ответить  
 
 автор: kosta_in_net   (28.01.2011 в 08:31)   письмо автору
 
   для: Valick   (28.01.2011 в 07:48)
 

Извиняюсь за ошибку. Структура такова:
table1
id int(11) unsigned NOT NULL auto_increment
name varchar(20) NOT NULL

table2
id int(11) unsigned NOT NULL
golos tinyint(1) NOT NULL

То есть, без автоинкремента во второй таблице.

И так, какие тут проблемы с нормализацией?

  Ответить  
 
 автор: Trianon   (28.01.2011 в 09:08)   письмо автору
 
   для: kosta_in_net   (28.01.2011 в 08:31)
 

1. А хоть какой нибудь уникальный индекс во второй таблице есть? Или даже вообще хоть какой нибудь индекс?

2. Как определить, кому принадлежит голос?

возможно вопросы несовсем в тему. Тогда по заданному вопросу: идея с полями za protiv мне не нравится.

  Ответить  
 
 автор: kosta_in_net   (28.01.2011 в 09:34)   письмо автору
 
   для: Trianon   (28.01.2011 в 09:08)
 

уникальный индекс строится на двух полях: id предложения и id юзера (данное поле исключено из примера, так как не имеет значения для подсчета голосов - оно не влияет на количество). Это и ответ о том, как определить, кому принадлежит голос. Хотя фиксация авторства голоса сделана на всякий случай. Фактически, нужно знать лишь предложение и общее количество голосов. Можно было бы иметь все это в одной записи, сумируя в нее результаты голосования, и тогда получали бы 2 поля: za и protiv; id стало бы уникальным, да и вообще, все можно было бы сделать одной таблицей, а не двумя... Но, на всякий случай сохраняется авторство. Соответственно, много записей и 2 таблицы, вместо одной.
Именно в ситуации 2-х таблиц мне интересно мнение других о способах хранения. Хранение в 1-м поле требует громоздкий запрос для выборки. Это наводит на мысль о его ресурсозатратности и медленности. Хранение в 2-х полях требует чуть больше места, но, как мне кажется, должно давать выигрышь в скорости

  Ответить  
 
 автор: Trianon   (28.01.2011 в 11:54)   письмо автору
 
   для: kosta_in_net   (28.01.2011 в 09:34)
 

SELECT p.name, SUM(state='pro') AS `pro`, SUM(state='contra') AS `contra`
FROM polls p
LEFT JOIN votes v ON v.poll_id = p.id
GROUP BY p.id , p.name 


Легенда:
polls - table1
votes - table2
state - golos
1 - za - pro
2 - protiv - contra

  Ответить  
 
 автор: kosta_in_net   (28.01.2011 в 17:59)   письмо автору
 
   для: Trianon   (28.01.2011 в 11:54)
 

а я и не знал, что можно сделать так: SUM(state='pro') век живи, век учись, и все равно - дураком помрешь :)
Ща посмотрим на это в деле

  Ответить  
 
 автор: kosta_in_net   (28.01.2011 в 18:08)   письмо автору
 
   для: kosta_in_net   (28.01.2011 в 17:59)
 

Работает :)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования