DieZeeL
@DieZeeL
PHP Developer, DevOps

Выборка, сортировка, подсчет данных по нескольким ключам, как решить?

Здравствуйте, есть проблема, с выбором хранилища под данные:
имеем таблицу в MySQL с разными данными (назовем ее Items) и имеем две таблицы Регионы (Regions) и Категории (Categories). Categories и Regions содержат дерево бесконечной вложенности организованное по методу Джо Селко (левый правый ключи)
в Items есть поля указатели на эти таблицы - Region_ID и Category_ID
есть задача - хранить кол-во итемов в категории и регионе, причем кол-во должно быть с учетом всех детей категории и региона (пример):
Регионы:
IDParent_IDLevelName
101Россия
212Москва
312Питер

Категории:
IDParent_IDLevelName
101IT
212Провайдер
312Хостинг


В Москве Провайдеров 5 штук
В Москве Хостеров 10 штук
В Питере Провайдеров 12 шт
В Питере Хостеров 20 шт
В Питере IT - 8 штук (не указана категория 2го уровня)
В Росии Провайдеров (не указан город) 3 шт
Соответвственно:
В России Провайдеров будет 20 шт (суммируем Провайдеров по Питеру, Москве и без города)
В Питере ИТ - будет 40 штук (Суммируем всех из Хостеров, Провайдеров и ИТшников)
Если представить все в виде таблички Каунтеров:
RegionCategoryCount
РоссияИТ58
РоссияПровайдеры18
РоссияХостинг30
МоскваИТ15
МоскваПровайдеры5
МоскваХостинг10
ПитерИТ40
ПитерПровайдеры12
ПитерХостинг20

Если у нас 10 тыс категорий и 18 тыс регионов, то в табличке каунтеров будет 180 млн строк, вроде и не сильно много, но на каждую категорию будет добавляться 18 тыс строк
Запрос к этой таблице если мы ее будем хранить в MySQL будет занимать очень много времени....
Посоветуйте быстрое хранилище которое сможет работать более чем с 1 млрд строк и приемлемым временем выдачи результатов (не более 0,01 сек на запрос 1 строки) и возможностью выбора каунтеров всех регионов допустим по какой-то категории одним запросом (не более 0,1 сек)
Может быть посоветуйте другой вариант хранения счетчиков и их быстрой выборки
  • Вопрос задан
  • 2768 просмотров
Пригласить эксперта
Ответы на вопрос 2
DmitriyEntelis
@DmitriyEntelis
Думаю за деньги
Не буду претендовать на абсолютную верность моей точки зрения, но все же, разные мысли вслух.
Писал в том порядке в каком приходило в голову :)

1. Мне кажется что решение с хранением заранее рассчитанных счетчиков изначально не верное, т.к имеет сложность N2. По базе ФИАС только в РФ территориальных единиц начиная с поселка ~55 000, а если Вы захотите расширяться за пределы?

2. Если говорить про SQL можно делать выборки вида
select count(*) from items where category_id IN ( 1,2,3 ) and region_id IN (1,2,3)

Соответственно что бы получить id элементов для подстановки - можно кешировать id детей в таблицах категорий и регионов. Вам подгадят запросы уровня Россия - т.к там по сути будут все id какие есть)
C учетом того, что запрос IN начинает себя не очень хорошо вести на ~тысячах значений внутри условия, - я бы шардировал таблицу items по полям category_id и region_id

3. Так ли Вам нужна возможность бесконечной вложенности категории и региона? Неужели десятка уровней не хватит? Да, это раздует таблицу items, но её можно будет просто шардировать по item_id

4. Не очень понятно сколько у Вас items, но если тоже сотни миллионов - я бы посмотрел куда то в сторону Hadoop MapReduce

5. Для хранения счетчиков можно тупо взять redis.
instagram-engineering.tumblr.com/post/12202313862/...
Вот тут ребята пишут что на хранение 1kk ключей у них ушло ~70MB в лоб, и это можно оптимизировать.
Пост двухлетней давности, память с тех пор подешевела. Вам нужно будет всего то 12Gb по верхней оценке, опять же шардирование никто не отменял.
Правда см п1, с учетом сложности N2 это может быть быстрым временным решением, но надолго его не хватит, если вы будете увеличивать регионы и категории.

Фуф. Давайте дискутировать :)
Ответ написан
w999d
@w999d
Web-developer
Для поиска лучше использовать сервисы, ориентированные на поиск. Например Solr. Копать в сторону /dataimport, либо реализовать демон, например, на nodejs - для индексации по требованию (через http-запрос либо очередь, например, rabbitmq). Поиск будет работать быстро. вопрос только за быстрой индексацией.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы