За последние 24 часа нас посетили 61387 программистов и 1606 роботов. Сейчас ищут 838 программистов ...

Подсчёт мест в конкурсе

Тема в разделе "MySQL", создана пользователем Psih, 14 ноя 2009.

  1. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Есть таблица конкурса:
    [SQL]
    CREATE TABLE competition (
    cmp_usr_id int unsigned not null,
    cmp_rating int unsigned not null,
    cmp_place smallint unsigned,
    PRIMARY KEY(cmp_usr_id),
    KEY(cmp_rating)
    ) ENGINE=InnoDB;
    [/sql]

    При оценке фотки рейтинг пользователя обновляется запросом
    [SQL]
    UPDATE competition SET cmp_rating = cmp_rating + $vote WHERE cmp_usr_id = $usr_id
    [/sql]

    И после этого нужно пересчитать все места пользователей. Сейчас это выглядет примерно так:
    [SQL]
    SET @place := 0;
    UPDATE competitions SET place = @place := @place + 1 ORDER BY cmp_rating;
    [/sql]

    Собственно мысль в том, что это явно не самый лучший вариант, может у кого есть идеи получше? Процедуры тоже принимаются :)

    Рейтинг и места должны обновлятся live обязательно. Это топы у меня обновляются раз в 10 минут, а тут нельзя.
     
  2. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    А нахрена их вообще считать и писать в таблицу?
     
  3. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Сортируй по DESC рейтинга и бери ключ строки как место
     
  4. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Simpliest
    Как это зачем считать? А как показывать баллы пользователей и считать их места?

    сортировка это понятно, но нужно ещё показывать место пользователя в конкурсе не только в списке, но и в профиле и ещё нескольких местах. Если бы было так просто, я бы сюда не писал.
     
  5. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    1 запись - 1 место,
    2 запись - 2 место.


    Так нужно четко определиться с голосованием и результатами. Результаты обычно объявляются после голосования, там уже и выставляется place
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    $place=mysql_num_rows(mysql_query("SELECT * FROM `users` WHERE rating>=$user_rating"));
     
  7. DarkElf

    DarkElf Активный пользователь

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Psih

    кмк, можно создать отдельную memory-табличку,

    ID - autoincrement
    user_ID - unique_id

    которую очищать каждый раз и записывать туда ID-шники в порядке убывания кол-ва голосов. и будет эта табличка типа memory.
     
  8. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Это уже хуже.

    А может это... ну его в пень такую прецезионность рейтинга в профиле?

    В смысле, место в общем ретинге будет всегда актуальным(сортировка), а в профиле указать что рейтинг обновляется раз в 6/12/24 часа... Ну и в профиле ссылку на общий рейтинг в обязательном порядке.

    Хотя... пользователей сколько? тысячи? сотни тысяч?

    Просто, если пользователей немного - то твой вариант пересчета вполне подойдет. Если много..... Один пользователь за 5 минут может оценить 10ток фото.
    И ты тупо убьешь базу.
     
  9. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Mr.M.I.T.
    не прикалывайся.

    Что произойдет если у нас будет 200к пользователей? И рейтинг решат посмотреть 100ня из них ниже 150000го места.
     
  10. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    каанешна, таблички то быстрее пересчитывать
    $place=mysql_result(mysql_query("SELECT COUNT(*) FROM `users` WHERE rating>=$user_rating"),1);
     
  11. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    + а если ещё это кешировать....
     
  12. DarkElf

    DarkElf Активный пользователь

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Simpliest

    memory-таблицы - нет))
     
  13. Darevill

    Darevill Активный пользователь

    С нами с:
    20 сен 2009
    Сообщения:
    50
    Симпатии:
    0
    Зачем переписывать все места, если меняется только часть?
    Если при голосовании юзер поднялся с 150 места на 140, то нужно передвинуть всех между этими местами на 1 позицию вниз (149 -> 150, 148 -> 149, ... 140 -> 141)
    [sql]UPDATE `competition` SET `position`=`position`+1 WHERE `position` BETWEEN 140 AND 149[/sql]

    а данному юзеру записать место 140
     
  14. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Давай без канешна?

    Вот чего не знаю, того не знаю. Насколько мне известно в higload любят выделять память MySQL столько, чтобы поместилась вся база с индексами. Чем это отличается от memory-таблиц в плане производительности - я не в курсе.

    В любом случае, как общее решение вариант Mr.M.I.T. правильнее. Хотя я бы
     
  15. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Simpliest
    тоесть ты хочешь сказать что местное кеширование хуже полного?
    Upd. А это ты не о том =)
     
  16. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    И как мы это узнали? Хотя, если убрать из твоего запроса места, а вставить фактический рейтинг - то прокатит.

    Но мое сердце все же принадлежит вот этому варианту :)
     
  17. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    ? В смысле? Я такого не говорил :)

    Я сказал такое
     
  18. DarkElf

    DarkElf Активный пользователь

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Simpliest

    тем, что memory-таблицы в любом случае будут в памяти. хотя, если таблички захотят больше памяти, чем есть - будет нехорошо...
     
  19. Darevill

    Darevill Активный пользователь

    С нами с:
    20 сен 2009
    Сообщения:
    50
    Симпатии:
    0
    По рейтингу конечно. Текущее место у юзера записано, а то, на которое нужно встать - получить запросом, исходя из нового пересчитанного рейтинга.
    Можно и сразу по рейтингу места сдвигать, но потом всё равно делать запрос чтобы вычислить место, так что всё равно
     
  20. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    DarkElf
    Они у нас в любом случае в памяти :) Мы ведь не Васи Пупкины?
    А вот насколько работа memory-таблиц будет быстрее(и будет ли) в этом случае - мне неизвестно.
     
  21. DarkElf

    DarkElf Активный пользователь

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Simpliest

    что будет с myisam/innodb таблицей, если места для нее в памяти не хватит? она окажется на жестком диске.
    memory-таблица просто откажется принимать новые данные. но все равно останется в памяти.
     
  22. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Ты гонишь...
    Перечитай мой предыдущий пост.
     
  23. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Значит так.

    Место нужно пересчитывать сразу, потому что это конкурс, а не топ, и в конкурсе могут быть разные условия, к примеру если лидер меняется за 5 минут до конца конкурса - конкурс продливается на 15 минут. И тому подобное.

    Насчёт передвижения юзеров - да, это логично. Только меня вот интересует такой факт - а сколько нужно сделать запросов, что бы передвинуть человека и тех, кто за ним. Тут нужно с WHERE поработать тоже ещё.

    Так что жду ещё предложений и строю своё :)
     
  24. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    На каждое изменение рейтинга будет 2 запроса.
     
  25. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Psih
    для общего ORDER BY
    для частного COUNT()

    не пойму чё те не так?