Ответы пользователя по тегу MySQL
  • Можно ли организовать фильтр/поиск товаров посредством JSON_EXTRACT?

    batyrmastyr
    @batyrmastyr
    Сделать можно, но здесь вас ждёт множество граблей:
    1. Крайне неэффективное хранение: объём в разы больше, чем если раскидать по таблицам.
    2. Эффективность индексов по JSON полю: если в постгресе она не особо радует, но можно выбирать между простотой и скоростью работы, то в мускуле есть только убогие костыли с индексированием частей объекта через генерируемые столбцы.
    3. OR = JSON_OVERLAPS, IN = JSON_CONTAINS или разворачивать вручную. И чёрт знает, сработает ли индекс потому, что это функции, а не операторы.
    4. Типизация значений: в JSON можно пихнуть и '3', и 3 и 3.0. Нужно внимательно следить за типами и при сохранении, и при поиске, чтобы всё правильно находилось.

    В общем, если хотите навернуть такое, то стоит крепко задуматься о переходе на постгрес, в нём хотя бы 2 и 3 проблемы не будут выглядеть неразрешимыми.
    Ответ написан
    Комментировать
  • Какой стэк использовать для быстрого доступа данных?

    batyrmastyr
    @batyrmastyr
    1) > чтобы хранить весь массив данных в виде json
    JSON уже давно можно хранить в самом MySQL, если вам нужно произвольное число параметров, но значения их скалярные. Для индексации - виртуальные колонки и индексы по ним.
    Если хочется найти искать «1» в массиве [1, 2,5], то вам в PostgreSQL.
    2) «Полнотекстовый поиск» — что вы от него хотите? Если вам нужно точное совпадение, только быстрее, то берите что угодно.
    Если вам нужен учёт словоформ, то он есть как минимум в Монге, Эластик, Постгрес, Сфинкс/Мантикора.
    Если вы хотите больше контроля (поиск с учётом особенностей > 1 языка, тюнинг морфологии, какое-то ранжирование), то выкидываем Монгу (нет тюнинга морфологии и ранжирования, а на каждый язык нужно вешать отдельный индекс).
    Если вы и ранжирование хотите тюнить (вплоть до простенького машинного обучения) и вообще максимальную скорость поиска, то вас спасёт только Мантикора/Сфинкс, всё остальные грустно глотают пыль.

    Но золотая середина - Постгрес. На него довольно легко перекатиться и он избавляет от необходимости разводить NoSQL зоопарк.
    P.S. И забудьте про монгу, Постгрес лучше неё почти по всем параметрам.
    Ответ написан
    Комментировать
  • Как правильно реализовать ТОП дня, недели, месяца?

    batyrmastyr
    @batyrmastyr
    1. Вместо top_[daily|weekly|monthly] можно завести общую таблицу top со столбцом для признака, что это дневной/недельный/месячный рейтинг.
    2. Обновлять данные в ней раз в день/час.
    3. В транзакции удаляете старые записи и делаете Insert into (select ..., ‘daily’ as type
    INION select ..., ‘weekly’ as type
    INION select ..., ‘montly’ as type
    ).
    При желании можно суточный рейтинг обновлять раз в час, а недельный и месячный раз в сутки.

    Когда rating_log слишком распухнет, можно будет:
    1) секционировать её по времени. Либо встроенными средствами БД, либо вручную перенося старые записи в таблицу-архив.
    2) Воспользоваться более специализированными решениями: расширение timescaleDb для PostgreSQL или колоночную базу типа ClickHouse. Но оба варианта требуют тестирования перед использованием: например, оба не очень любят работу со строками, а Кликхаус предпочитает, чтобы данные вставляли пачками, а не построчно.
    Ответ написан
    Комментировать
  • Как организовать пагинацию, если БД и поисковая машина - это раздельные сервисы?

    batyrmastyr
    @batyrmastyr
    1. Попробуйте искать целиком в сфинксе используя распределённые индексы.
    index rss {
    type = distributed
    agent_persistent = 127.0.0.1:9312:rss1
    ...
    agent_persistent = 127.0.0.1:9312:rssN
    agent_persistent = 127.0.0.1:9312:rssUpdates
    }
    В первые N частей закидываете все документы более-менее равномерно их распределив, например, по датам создания или номерам и индексируете редко, раз в сутки или неделю.
    В последний rssUpdates выбираете только документы изменившиеся с последней индексации, прописываете sql_query_killlist чтобы исключить из результатов устаревшие копии документов из других индексов.

    2.1. Точное число результатов довольно быстро можно узнать так из SHOW META:
    "SELECT ... WHERE <условия без сортировки> LIMIT 1; SHOW META like 'total_found';" и смотрите результат второго запроса.

    2.2 Дальше делаете "честные запросы" - фильтрацию, сортировки для получения нужной страницы, но с указанием max_matches: "SELECT .. WHERE ... LIMIT ... OPTION max_matches=страница * размер страницы". В типичной ситуации, когда пользователь угомонится на первых страницах, скорость значительно увеличится.

    3. В третьем сфинксе появился CREATE INDEX для обычных, не текстовых, столбцов. Может помочь.

    4. В Постгресе сейчас есть "обёртка сторонних данных" и через неё можно стучаться, например, к mysql. К Сфинксу стучаться не пробовал, но стоит попробовать схему "данные в постгресе, полнотекстовый индекс из сфинкса подключаем через JOIN".
    Ответ написан
    Комментировать
  • В чем основные отличия mySQL от Postgre?

    batyrmastyr
    @batyrmastyr
    Из простых преимуществ постгреса - многие запросы в нём отрабатывают шустрее, можно весьма гибко прописать ограничения на данные (если в поле "а" что-то есть, то в поле "б" может быть только "с"), даже крупному магазину может хватить настроек по-умолчанию при которых база довольствуется смешным объёмом памяти.

    Из недостатков по сравнению с Mysql - нет множеств (заменяется массивом перечислений), большая строгость работы (число или перечисление нельзя взять и сравнить со строкой "5 = '5'", нужно привести их к одному типу "5 = '5'::int" или " 5::text = '5'5 ", а ваша обёртка над базой может быть не готова к такому).

    В контексте nosql баз данных например вижу преимущества в быстродействии, например, причем на порядок.

    Увы, это преимущество скорее всего окажется мифом - сейчас как раз потихоньку выпиливаем MongoDB.
    Если говорить про MongoDB, то в моих задачах он работал либо не быстрее мускуля или постгреса при поиске, либо в разы (в 2 - 50 раз) медленнее при записи. При этом Монга жрала 1,5 гига памяти, мускуль - 300 Мб, а постгрес - меньше 15 Мб (да, меньше жалких пятнадцати мегабайт).
    Ответ написан
    3 комментария