Нетривиальная задача (MySQL и PHP)

MarkusM

Новичок
Нетривиальная задача (MySQL и PHP)

Всем, доброго времени суток.

Вот столкнулся с проблемой.

На сайте есть каталог статей. У каждой статьи есть заголовок, основной текст и анотация (остаьное не нужно для объяснения проблемы).
Анотация состоит из 10 уникальных предложений. Статьи разбиты по категориям (имеется отдельная таблица с категориями).
Хотим разадавать сайтам-партнерам листинг статей.
То есть партнер регистрируется и потом ему выдается список статей этой категории, с названием статьи и с анотацией.
Анотация состоит из трех предложений из тех 10 предложений которые прилагаются к статье.
По поводу анотации: мы генерируем 120 уникальных вариантов анотаций по три предложения. То есть в 120 вариантах, например, комбинация из 1,7 и 10 го предложения встречается только один раз.
Далее каждый партнер для каждой статьи получает рандомно один из 120 вариантов анотаций, причем этот вариант для данной статьи выдаваемой этому партнеру должен быть постоянным.
То есть номер этого варианта надо где-то хранить.

Далее, при отдаче партнеру листинга статей необходимо перемешать их, то есть назначить каждому партнеру свою сортировку вывода статей в листинге.
И эту сортировку для каждого партнера надо сохранить, она должна быть постоянной.
В принципе задачу вроде объяснил.

Как я сначала решил эту задачу:
Я создал таблицу ordering.
partnerID articleID variantID ordering

и таблицу summary_variants
variantID articleID summaryVariant
в эту таблицу я пишу автоинкрементов ID варианта анотации , ID статьи и один из вариантов анотации.
То есть в таблице для каждой статьи есть 120 строк.
в ordering в partnerID я писал ID партнера, в articleID писал ID статьи, в variantID рандомный ID варианта из 120 вариантов и в ordering порядок сортировки.
То есть в этой таблице для каждого партнера будет столько записей сколько имеется статей.

Теперь о проблемах. Все это прекрассно работает и не вызывает проблем. Но это только пока.
Как выяснилось количество статей будет свыше 60 000 тысяч. Ожидаемое кол-во партнеров 5 000 - 6 000, возможно больше.
То есть получаем для таблицы ordering 60000*6000-360 000 000 строк. Если перевести все это в kb, то очень много получается. В несколько раз больше максимального размера файла базы.
А значит этот вариант не годится. Мне тут предложили для каждого партнера создавать отдельную таблицу с ID партнера и в нее писать все что будем выдавать ему.
В этом случае увеличится скорость отдачи, но тогда в базе со временем будет столько таблиц, сколько будет партнеров.
Вот я теперь и зашел в тупик что делать. Что можете посоветовать? Может направите на путь истинный.
 

Фанат

oncle terrible
Команда форума
у меня получилось 1,3 гига (умножил количество строк на 4 байта и поделил на 3х1024). где я ошибся?
 

MarkusM

Новичок
Автор оригинала: *****
у меня получилось 1,3 гига (умножил количество строк на 4 байта и поделил на 3х1024). где я ошибся?
Добрый день, уважаемый!
Спасибо, что натолкнули!!! Не знаю как у меня получилось, что размер вышел такой.
Сейчас посмотрел действительно, хоть строк и много, но размер файла примерно будет 1,5Gb
А почему 4 байта?
Таблица ordering.
[sql]CREATE TABLE `ordering` (`partnerID` smallint(5) unsigned NOT NULL default '0',
`articleID` mediumint(6) unsigned NOT NULL default '0',
`variantID` tinyint(3) unsigned NOT NULL default '0',
`ordering` mediumint(6) unsigned NOT NULL default '0',
KEY `partnerID` (`partnerID`),
KEY `articleID` (`articleID`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;[/sql]
В итоге на строку 10 байтов.

6000*60000*10/(3*1024)=1,422Gb

Собственно то, что нужно.
Не зря все таки создал тему. И последний вопрос, а то что в таблице строк 6000*60000 и возможно больше никак не повлияет на скорость?
 

Фанат

oncle terrible
Команда форума
сам я ошибся при подсчетах.
я считал int одним байтом.
для статей медиум, кстати, не подойдет. да и для многих других полей их типы - тоже. максимальный айди надо брать с запасом.

360 миллионов строк - это не очень много. бывает и больше.
главное - памяти под кючи в сервер наставить - и все будет летать
 

MarkusM

Новичок
для статей медиум, кстати, не подойдет.
Почему? При mediumint(7) можно максимально загнать 8388607 строк, В смысле максимальный ID будет 8388607.

да и для многих других полей их типы - тоже. максимальный айди надо брать с запасом.
partnerID smallint( 5 ) максимальный ID = 32767. Достаточно! С огромным запасом.
variantID tinyint( 3 ) макс. номер 127. Вариантов всего будет 120. то есть здесь например о запасе не надо думать.
Ну и ordering mediumint( 6 ) здесь так же как и ID статей.

360 миллионов строк - это не очень много. бывает и больше.
главное - памяти под кючи в сервер наставить - и все будет летать
Понятно. Еще раз спасибо.
 

MarkusM

Новичок
Автор оригинала: .des.
http://dev.mysql.com/doc/refman/5.1/en/partitioning.html

Вот станет 5.1 GA и проблема ваша сойдет на нет гораздо раньше, чем достигнет 360М
Прошу прощения, но я не понял что Вы хотели сказать. Я слаб в анг., поэтому не понял о чем там речь.
Вы хотите сказать, что с выходом 5.1 GA проблемы у меня начнутся раньше чем в таблице будет 360М строк?
Поясните пожалуйста если не трудно.
 

.des.

Поставил пиво кому надо ;-)
проблемы у меня начнутся раньше
Как раз, наоборот, данная проблема исчезнет вовсе.
Когда 5.1 перестанет быть бетой и станет рекомендуемым релизом, Вы с легкостью сможете использовать partitioning и разбить Вашу большую таблицу не меняя клиентского кода.
 

MarkusM

Новичок
Автор оригинала: .des.
Как раз, наоборот, данная проблема исчезнет вовсе.
Когда 5.1 перестанет быть бетой и станет рекомендуемым релизом, Вы с легкостью сможете использовать partitioning и разбить Вашу большую таблицу не меняя клиентского кода.
Вот теперь все понятно. В принципе я так и подумал. Спасибо большое за разъяснения.
Я получил исчерпывающий ответ на свои вопросы.
 
Сверху