За последние 24 часа нас посетили 16473 программиста и 1677 роботов. Сейчас ищут 855 программистов ...

Оптимизация таблицы MySQL (Нужен совет)

Тема в разделе "MySQL", создана пользователем CeperaI99I, 22 янв 2010.

  1. CeperaI99I

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

    С нами с:
    19 июн 2009
    Сообщения:
    30
    Симпатии:
    0
    Адрес:
    Талгар
    Добрый день. Мне нужен совет в области оптимизации бд.
    Есть список из неких предметов, которым пользователь выставляет баллы (1-10).
    Этих предметов порядка 3000 шт. За каждый предмет голосует около 5000 пользователей. Так вот, возник вопрос делать ли отдельную таблицу для каждого предмета, или лучше создать общую таблицу и присваивать каждому голосу идентификатор предмета? Для наглядности:

    Таблицы (Несколько)
    Код (Text):
    1.  
    2. Votes_Predmet1
    3. |user |date|point|
    4.  
    5. Votes_Predmet2
    6. |user |date|point|
    Table (Общая)
    Код (Text):
    1.  
    2. Votes
    3. |user|date|point|predmet|
    P.S.
    В последствии Бд используется для подсчета среднего балла, причем довольно часто. Конечно создавать каждому предмету свою таблицу довольно накладно, но меня беспокоит 15 000 000 записей (Если делать общую таблицу). С другой стороны записи в таблице не очень объемные.

    Так как будет лучше?
     
  2. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Одна таблица, для голосов пользователей (ид предмета, ид пользователя, дата)

    И можно сделать еще одну таблицу по сумме голосов для каждого предмета (ид предмета, сумма голосов, число голосов)

    P.S. И, да, я сильно сомневаюсь что все эти 5к пользователей голосовали 3к раз(я бы на месте пользователя застрелился). Так что стоит умерить фантазию.
     
  3. LuckyScrat

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

    С нами с:
    16 июн 2009
    Сообщения:
    176
    Симпатии:
    0
    Адрес:
    Москва
    в то что проголосуют все и за всё я тоже совсем не верю. или ты им оплачиваешь каждое голосование ? ))

    по поводу быстродействия проведи эксперимент, не ленись, создай таблицу, по выполняй типовые запросы. Посмотри тормозит или нет. При правильном проектировании не должно, если у тебя конечно не дикий highload.

    Мне вот было не лень, забил 15 млн. записей (каждый пользователь, за каждый предмет, оценка рандомно 1...5) , скрипт написать 15 минут

    таблица
    [sql]CREATE TABLE `test` (
    `user` SMALLINT(4) UNSIGNED NULL,
    `date` DATETIME NULL,
    `point` TINYINT(1) UNSIGNED NULL,
    `predmet` SMALLINT(4) UNSIGNED NULL,
    PRIMARY KEY (`user`, `predmet`),
    INDEX `Index 2` (`predmet`)
    )
    COLLATE=cp1251_bin
    ENGINE=MyISAM
    ROW_FORMAT=DEFAULT[/sql]

    запросы
    [sql]
    голосовал ли пользователь за предмет
    select * from `test` where `user`=10 and `predmet`=34; 0.000 sec[/sql]
    все голоса пользователя (может и не нужен в твоей задаче)
    [sql]select * from `test` where `user`=50; 0.000 sec[/sql]
    средняя оценка предмета
    [sql]select avg(`point`) as sred from `test` where `predmet`=578; 0,047 sec[/sql]

    это оценка на коленке.

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

    По результатам действуй.

    Совет Simpliest дельный можешь дополнить мою схему и тоже потестить.
     
  4. CeperaI99I

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

    С нами с:
    19 июн 2009
    Сообщения:
    30
    Симпатии:
    0
    Адрес:
    Талгар
    Проект действительно большой. 3000 и 5000 Я не с неба взял. Подсчетом занимались статистики. Кстати, пользователей гораздо больше 5000 и расчитано так, что каждый из них проголосует за n-ую часть предметов, а в сумме как раз и получаются такие цифры.

    Хорошее предложение.

    Так и сделаю. Спасибо за тесты.
     
  5. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Вот я бы на твоем месте задумался о правильности подсчетов.
    При среднем возрасте вашего посетителя 1год, это около 10 голосований в день.

    Мои эмпирические наблюдения, например, за таким форумом, как Винград, говорят следующее:

    За сообщения голосует не больше 10ка пользователей.
    В среднем на 1 сообщение приходится около 1го голоса.
    В опросах участвует 10-40 человек. (подразумевается голосование в обозримое время - 1-3 месяца, есть ряд опросов по 100 участников, но и висят они уже больше 3х лет)

    Число тем измеряется сотнями тысяч.
    Число сообщений свыше 2млн.
    Число зарегистрированных участников около 80тысяч
    Средний возраст посетителя точно не скажу, но полтора года назад где-то бегали цифры 1-2 года.


    Т.е. имея 2млн сообщений, 1 голос на сообщение и 80тыс участников, получается 125 голосов за 1-2 года его жизни на форуме.

    Вобщем, где-то ваши статистики-аналитики крупно облажались и это видно невооруженным глазом.
    Если бы речь шла скажем о 50к пользователей и 300-600 голосованиях за его жизнь на ресурсе - то это было бы более близкой оценкой.

    Ах да. Возможен вариант с 10ками голосований в день на человека. Это всякие галлереи и фотохостинги. Но в этом случае характеристики среднего возраста посетителя будут несколько другими. В конечном итоге цифры тоже будут не такие.

    К чему я это все? Да к тому, что если иметь реальную статистику среднего числа голосовавших за 1 объект, то во многих случаях (10-50 оценок на 1 объект) все голоса для данного объекта можно хранить в 1м поле в той же таблице где лежат сами объекты.

    Код (Text):
    1. ид_предмета сериализованный_список_голосов_пользователей.
    Где один голос_пользователя это ИД-пользователя и Оценка.