Я разве что-то плохое сказал про Postgres? По-моему вполне оригинально использовать постгресовский jsonb заместо Mongo или MySQL, и я бы даже так и сделал, тем более, что оно быстрее монги. Статья о другом, о том, как можно добавить поверх существующего кода Redis и получить быстрый результат.
Мы в своем магазине (сейчас около 8000 товаров) для хранения товаро перешли на MongoDB
Это дало нам много преимуществ:
1) отсутствие схемы позволяет добавлять поля товара на лету (например одни имеют вес, а другие количество таблеток в упаковке
2) возможность хранить массивы — используем в случае когда товар может быть сразу в 2-3 и более категориях
3) эти же массивы используем для фильтров
Скорость поразительна, разумеется важно проиндексировать важные поля
Но при этом это не снимает проблему именования атрибутов? На вскидку: менеджер для одного товара создал поле «цена» в том время как у всех товаров используется «розничная цена». Получаем два разных поля, так ведь?
Несмотря на многообразие полей у товаров, они все-таки жестко прописаны в административной панели. Я лишь описал наш кейс, пока что MongoDB нас полностью устраивает.
И цены у нас вручную нельзя прописать, они пересчитываются автоматически на основе прайсов поставщиков, равно как и скидки :)
Делал сложные фильтры на много тысяч товаров с помощью Elasticsearch, заодно получил возможность полнотекстового поиска по названию, описанию и составу, учитывая опечатки.
Видимо мой юмор не очень понятен, но я всего-лишь сделал акцент на том, что MySQL в вебе используется чаще, чем Postgres, добавив чувства гордости большинству :) На то есть как исторические причины (уверен, вы знаете это и без меня), так и объективные. Так и быть, заменил предложение.
Веб — он бывает разным — если это домашний вордпрессик установленный за 5 минут на самом дешевом тарифе, то на хостингах постгрес если и есть то по запросу или «покупайте наш крутой VPS/VDS» и ставьте что хотите.
А на серьезных проектах — за последние лет 5 моих собеседований — про MySQL я не услышал ни одного вопроса. ни бекапы, ни репликации, вообще ни одного. PG, Oracle, MSSQL спрашивают много и активно, MySQL — остался только у хостеров или у тех, у кого задача с него смигрировать.
— богомерзские автоинкременты в mysql (до insert не выйдет получить id записи что в некоторых случаях делает жизнь болью и вынуждает использовать UUID)
— отсутствие возможности делать вложенные транзакции
— alter запросы не покрываются транзакциями (не шибко удобно для миграций).
Это тот минимум почему в некоторых задачах mysql в принципе не выйдет эффективно использовать и вам придется подстраиваться под инструмент и городить костыли.
А так… компаний много разных всяких, кто использует mysql или postgres (допустим skype на нем работал, а может и до сих пор).
Я с mysql работаю 15 лет (а так же работал с MSSQL, Oracle), ни чего из перечисленного не создавало мне проблемы.
И ещё раз, это инструменты, не нравится эта лопата, возьмите другую, которая вам нравится. Бессмысленно ругаться на совковую лопату, что ей трудно копать огород, а на штыковую, что ею долго перекидывать кучу земли. А если вам нужно перекидать кучу гравия, то возьмите шахтёрскую…
Так я ж не спорю, у меня тоже с этим проблем не было пока не перешел на инструмент, где с этим все хорошо (хотя у оракла тоже с этим все хорошо). Как бы мелочь но приятно. По поводу выбора инструментов — это так, согласен. Просто что бы знать из чего выбирать люди должны лучше представлять что зачем.
Почему вы от меня требуете понимания того, чего сами с оппонентами не понимаете. Если бы понимали, то высказываний ваших не было бы. А с дуру можно любую БД положить вы же понимаете это?
Что касается упомянутого случая, то это была БД примерно на 150 млн записей в основной таблице.
Кстати, да! Elastic одна из замечательных вещей, которая активно используется во всех наших проектах. Фильтрацию товаров с ее помощью делать просто сказка
Первый — крупный интернет-проект с >10млн пользователей, используется следовательно для поиска и фильтрации людей по куче полей (город, пол, возраст и т д). Нода работает на одном сервере с 32GB оперативной памяти, больше не требуется, интенсивность поиска доходит до 200 запросов в секунду, ответ в среднем менее 0.05ms. Обновление индекса выставлено каждые 30сек.
В свое время стоял выбор между Sphinx и Elastic — выбор пал в пользу последнего. Поскольку метод обновления индекса в Sphinx не очень эффективен при таком большом количестве записей. Плюс удобный REST API, хорошая документация, сообщество, результаты тестирования, в общем, мы довольны. Руская морфология добавляется плагином, работает хорошо.
Второй — небольшой интернет магазин с 7000 товарами, использую исключительно для поиска товаров. Здесь он работает также хорошо. Обновление индекса здесь, разумеется, моментальное. Единственное, потребление памяти конечно, не самое лучшее (после многих дней аптайма оно составляет 1.0-1.5GiB). Однако для нас всегда был приоритет в скорости, да и недорогого сервера с 8GB оперативки хватает за глаза.
Насчет фасетчатого поиска — у Elastic с этим все отлично, вы можете комбинировать любые сложные вариации фильтров, как простых соответствий, так и range (для цен например). В общем, присмотритесь к Elastic и не жалейте память, вряд ли его использование будет экономически невыгодным, учитывая удобство, которое он предоставляет.
Не просто думал, а даже смотрел в эту сторону. Но внедрить и настроить эластик — мне показалось задачей посложнее, чем разобраться с редис и добавить десяток строк кода.
Эластик очень хорош, вернее, даже не эластик, а solr, он очень хорошо умеет искать, группировать, выводить количество найденных совпадений.
Даже сам на интервалы разбивать и считать попадания в интервалы) Сам использую на около 30К товаров, летает.
В моем пониманию ES выстроен на lucene. Solr в свою очередь так же построен на базе lucene.
Т.е lucene это такая core сущность, на основе которой уже сделаны полноценные решения для поиска — Solr/ES. И как мне кажется ES появился, потому что Solr многим не нравился. Согласны?)
PS: Я бы с радостью почитал где нибудь о истории развитии ES и Solr, так как сам не имею четкого представления об этом :(
Респект! Но почему бы не искать прямо по EAV-модели в SQL? Это же очень легко делается, даже по произвольному количеству атрибутов. Взяли первый атрибут, по таблице связей entity_id — value_id получили множество товаров (entity_ids), далее взяли второй атрибут и сократили это множество, далее взяли следующий атрибут… и так далее.
А причем тут дизайн и структура БД? Вы точно уверены что ulmart применяет EAV? Да и по скорости работы ulmart не показатель (по крайней мере в старой версии), я бы даже сказал наоборот.
текущую версию делали не мы. И даже при этом, я могу сказать что тормозит скорее клиентская часть.
На нашем движке страницы отдавались не более чем за 0.5с
Тут еще важно сколько у товаров свойств по которым возможны фильтры. Я не поверю, что выборка по 3-4 условиям из EAV таблицы в десятки миллионов записей с нагрузкой в 30-40 запросов в секунду будет отрабатывать за приемлемое время без танцев с бубнами.
Зачастую смекалки уже недостаточно и нужно принципиально новое решение, с EAV вы как раз примерно очертили границы его возможностей, это 0.5 с. Запаса прочности у такого решения практически нет, да и масштабировать его трудно и затратно.
ну справедливости ради у вас там больше 100мс (по крайней мере сейчас)
кстати то что выбранные значения исчезают немного расстраивает, посмотришь цвет, а твои фильтры уже сбросились наполовину
По моим измерениям те же 0.5с на отдачу страницы.
Предлагаю закончить фехтование линейками и писюнами. Модель EAV достаточна для 99% интернет-магазинов рунета, удобна в поддержка и обладает многими преимуществами структурированности данных. Никто не спорит, что есть случаи, когда EAV не позволит выполнить требования. Ни EAV, ни другие решения не являются догмами, и ВСЕ имеют свои плюсы и минусы и области применения.
Чтобы не делать SELECT * FROM IN () по БД, достаточно хранить минимальный набор инфы о товаре в том же редисе. Будет ещё быстрее выбирать, а минимум данных не сожрёт память.
Особенно оно понадобится, когда будет миллион товаров и они будут шардиться по разным БД. Тогда с разных серверов MySQL страница будет собираться значительно дольше, чем из редиса.
Усложнение бизнес-логики? Ничуть. Просто не нужно делать декомпозицию данных в sql парадигме. Ну и по хорошему именно бизнес-логика со способом хранения данных напрямую не должна быть связана вообще ни как.
Не, я имел в виду вещи вроде foreign keys и транзакций (грубый пример в контексте сабжа — размещение заказа с последующим обновлением состояния продуктов на складе и прочее). Не спорю, все это можно сделать на уровне непосредственно кода (как и аналоги прочих join'ов и union'ов). Но вот именно про это я и говорил — будет очевидное усложнение логики, и тут уже фиг его знает, перекроет ли профит (в смысле времени выполнения) от простого in memory хранилища это дополнительное усложнение кода.
Возможно, тут эффективнее будет оставить хоть тот же mysql/postgresql но держать всю базу в памяти.
я имел в виду вещи вроде foreign keys и транзакций
Еще раз повторюсь: "Просто не нужно делать декомпозицию данных в sql парадигме". Декомпозиция бизнес зачади в код и структуру данных должны при использовании noSQL решений проводиться вне парадигмы sql. Код приложения при этом будет другой, структура данных тоже будет другая. И делается это на фазе проектирования, т.е. еще до написания приложения. Если это выполняется после, то нужно очччень серьезное обоснование почему переезда приложения с sql -> nosql оправдан.
В статье рассказано о том как решить проблему масштабирования — вкраце, разбивать данные на блоки.
Интереснее почитать про разработку схему данных. У меня есть ощущение, что 95% всех проектов никогда не упруться в ограничение памяти для Redis, а вот модель данных станет проблемой с первой секунды проектирования.
Не станет проблемой, если думать в парадигме noSQL. Ясное дело, не все данные можно эффективно впихнуть в набор типов redis-а. Выбор в пользу редиса должен в том числе приниматься в контексте "могу ли я/команда думать в категориях nosql, а не РСУБД".
могу ли я/команда думать в категориях nosql, а не РСУБД
То есть вы предлагаете все держать в nosql? а зачем? Опять же такая же проблема будет как и со всякими mongodb — появляются связи между объектами (а они появятся) и уже начинаем кастыли ваять.
Могу ли я/команда построить систему без привязки к конкретной СУБД, лучше так. Тогда в РСУБД мы будем хранить все и в nosql агрегации данных для масшабирования.
Нет, я этого не предлагаю. Я просто упираю на то, что не нужно пытаться на Х делать Y (например, писать на PHP как на Java). И тогда волосы будут относительно гладкими и шелковистыми.
построить систему без привязки к конкретной СУБД
Построить можно что угодно и на чем угодно. Вопрос, какими силами/матами/костылями. Я к тому, что если в проекте выбор пал на nosql, то нужно быть уверенным, что команда умеет его готовить. Потому что в противном случае может в итоге оказаться, что поверх nosql написали свою, кровью и соплями, простенькую РСУБД.
Всегда в подобных обсуждениях мне вспоминается Erlang. Требует разворота мозга для переходящих с С-подобных языков. Так и тут, nosql требует все же некоторого разворота мозга для эффективной работы. Но если такой разворот выполнить, то проблем с бизнес-логикой не будет.
Вы о чем вообще? А как еще на PHP писать кроме как «как на Java»? Или вы имеете в виду что «не писать полноценный сервер на PHP»?
все же некоторого разворота мозга для эффективной работы
Да не требует он «разворота мозга», просто надо мыслить агрегациями данных. И для 90% проектов nosql может использоваться только как кеширующий слой, но не основная база данных (я не говорю о случаях когда мы храним независимые документы, логи и прочее, это я отношу к 10% задач).
Нет, я о другом. О том, что человек может PHP код, но делает это в парадигме Java. Так, как если бы он кодил на Java. Ну банально на вскидку — все гоняется через XML (конфиги, обмен данными), явное приведение типов, создание объектов на все-все-все.
Ну банально на вскидку — все гоняется через XML (конфиги, обмен данными), явное приведение типов, создание объектов на все-все-все.
Увы если делать по другому начинается адЪ. Не нужно конечно каждый инт или строку в объект заворачивать, но это нормально делать все объектами инкапсулируя поведение если мы практикуем ООП.
По поводу явного приведения типов — в php7 есть тайпхинтинг для скаляров, который в строгом режиме требует этого. И да это удобно для библиотек например). По умолчанию каст типов будет происходить автоматически, бросая иключения в случае потери данных.
Ну а конфиги в xml это рак, в основном юзают аннотации или yml.
PHP очень похож по семантике на Java/C#, он конечно не дотягивает до них (куда ему), и там есть странности, но писать на нем как на java это более чем нормально. Вопрос в том насколько надо упарываться и насколько люди придерживаются своему здравому смыслу.
P.S. Тем неменее минусовать не стал, имхо, больше статей по Redis хороших и полезных.
Это дало нам много преимуществ:
1) отсутствие схемы позволяет добавлять поля товара на лету (например одни имеют вес, а другие количество таблеток в упаковке
2) возможность хранить массивы — используем в случае когда товар может быть сразу в 2-3 и более категориях
3) эти же массивы используем для фильтров
Скорость поразительна, разумеется важно проиндексировать важные поля
И цены у нас вручную нельзя прописать, они пересчитываются автоматически на основе прайсов поставщиков, равно как и скидки :)
Ну а Postgres — это стандарт, зря вы так.
А на серьезных проектах — за последние лет 5 моих собеседований — про MySQL я не услышал ни одного вопроса. ни бекапы, ни репликации, вообще ни одного. PG, Oracle, MSSQL спрашивают много и активно, MySQL — остался только у хостеров или у тех, у кого задача с него смигрировать.
А спорить таки да, толку нету.
— отсутствие возможности делать вложенные транзакции
— alter запросы не покрываются транзакциями (не шибко удобно для миграций).
Это тот минимум почему в некоторых задачах mysql в принципе не выйдет эффективно использовать и вам придется подстраиваться под инструмент и городить костыли.
А так… компаний много разных всяких, кто использует mysql или postgres (допустим skype на нем работал, а может и до сих пор).
И ещё раз, это инструменты, не нравится эта лопата, возьмите другую, которая вам нравится. Бессмысленно ругаться на совковую лопату, что ей трудно копать огород, а на штыковую, что ею долго перекидывать кучу земли. А если вам нужно перекидать кучу гравия, то возьмите шахтёрскую…
Без всякого постргесса
Устроит в качестве примера домашнего вордпрессика?
Что касается упомянутого случая, то это была БД примерно на 150 млн записей в основной таблице.
Первый — крупный интернет-проект с >10млн пользователей, используется следовательно для поиска и фильтрации людей по куче полей (город, пол, возраст и т д). Нода работает на одном сервере с 32GB оперативной памяти, больше не требуется, интенсивность поиска доходит до 200 запросов в секунду, ответ в среднем менее 0.05ms. Обновление индекса выставлено каждые 30сек.
В свое время стоял выбор между Sphinx и Elastic — выбор пал в пользу последнего. Поскольку метод обновления индекса в Sphinx не очень эффективен при таком большом количестве записей. Плюс удобный REST API, хорошая документация, сообщество, результаты тестирования, в общем, мы довольны. Руская морфология добавляется плагином, работает хорошо.
Второй — небольшой интернет магазин с 7000 товарами, использую исключительно для поиска товаров. Здесь он работает также хорошо. Обновление индекса здесь, разумеется, моментальное. Единственное, потребление памяти конечно, не самое лучшее (после многих дней аптайма оно составляет 1.0-1.5GiB). Однако для нас всегда был приоритет в скорости, да и недорогого сервера с 8GB оперативки хватает за глаза.
Насчет фасетчатого поиска — у Elastic с этим все отлично, вы можете комбинировать любые сложные вариации фильтров, как простых соответствий, так и range (для цен например). В общем, присмотритесь к Elastic и не жалейте память, вряд ли его использование будет экономически невыгодным, учитывая удобство, которое он предоставляет.
Даже сам на интервалы разбивать и считать попадания в интервалы) Сам использую на около 30К товаров, летает.
Т.е lucene это такая core сущность, на основе которой уже сделаны полноценные решения для поиска — Solr/ES. И как мне кажется ES появился, потому что Solr многим не нравился. Согласны?)
PS: Я бы с радостью почитал где нибудь о истории развитии ES и Solr, так как сам не имею четкого представления об этом :(
По каким причинам этот подход был отвергнут?
Конкретно — ulmart.ru его предыдущий дизайн сайта.
А у вас опять много громких заявлений.
На нашем движке страницы отдавались не более чем за 0.5с
кстати то что выбранные значения исчезают немного расстраивает, посмотришь цвет, а твои фильтры уже сбросились наполовину
Предлагаю закончить фехтование линейками и писюнами. Модель EAV достаточна для 99% интернет-магазинов рунета, удобна в поддержка и обладает многими преимуществами структурированности данных. Никто не спорит, что есть случаи, когда EAV не позволит выполнить требования. Ни EAV, ни другие решения не являются догмами, и ВСЕ имеют свои плюсы и минусы и области применения.
Это можно отнести тогда ко всей статье в целом.
Особенно оно понадобится, когда будет миллион товаров и они будут шардиться по разным БД. Тогда с разных серверов MySQL страница будет собираться значительно дольше, чем из редиса.
Возможно, тут эффективнее будет оставить хоть тот же mysql/postgresql но держать всю базу в памяти.
Еще раз повторюсь: "Просто не нужно делать декомпозицию данных в sql парадигме". Декомпозиция бизнес зачади в код и структуру данных должны при использовании noSQL решений проводиться вне парадигмы sql. Код приложения при этом будет другой, структура данных тоже будет другая. И делается это на фазе проектирования, т.е. еще до написания приложения. Если это выполняется после, то нужно очччень серьезное обоснование почему переезда приложения с sql -> nosql оправдан.
Интереснее почитать про разработку схему данных. У меня есть ощущение, что 95% всех проектов никогда не упруться в ограничение памяти для Redis, а вот модель данных станет проблемой с первой секунды проектирования.
То есть вы предлагаете все держать в nosql? а зачем? Опять же такая же проблема будет как и со всякими mongodb — появляются связи между объектами (а они появятся) и уже начинаем кастыли ваять.
Могу ли я/команда построить систему без привязки к конкретной СУБД, лучше так. Тогда в РСУБД мы будем хранить все и в nosql агрегации данных для масшабирования.
Нет, я этого не предлагаю. Я просто упираю на то, что не нужно пытаться на Х делать Y (например, писать на PHP как на Java). И тогда волосы будут относительно гладкими и шелковистыми.
Построить можно что угодно и на чем угодно. Вопрос, какими силами/матами/костылями. Я к тому, что если в проекте выбор пал на nosql, то нужно быть уверенным, что команда умеет его готовить. Потому что в противном случае может в итоге оказаться, что поверх nosql написали свою, кровью и соплями, простенькую РСУБД.
Всегда в подобных обсуждениях мне вспоминается Erlang. Требует разворота мозга для переходящих с С-подобных языков. Так и тут, nosql требует все же некоторого разворота мозга для эффективной работы. Но если такой разворот выполнить, то проблем с бизнес-логикой не будет.
Вы о чем вообще? А как еще на PHP писать кроме как «как на Java»? Или вы имеете в виду что «не писать полноценный сервер на PHP»?
Да не требует он «разворота мозга», просто надо мыслить агрегациями данных. И для 90% проектов nosql может использоваться только как кеширующий слой, но не основная база данных (я не говорю о случаях когда мы храним независимые документы, логи и прочее, это я отношу к 10% задач).
Нет, я о другом. О том, что человек может PHP код, но делает это в парадигме Java. Так, как если бы он кодил на Java. Ну банально на вскидку — все гоняется через XML (конфиги, обмен данными), явное приведение типов, создание объектов на все-все-все.
И я о том же. Это и есть «разворот мозга».
Увы если делать по другому начинается адЪ. Не нужно конечно каждый инт или строку в объект заворачивать, но это нормально делать все объектами инкапсулируя поведение если мы практикуем ООП.
По поводу явного приведения типов — в php7 есть тайпхинтинг для скаляров, который в строгом режиме требует этого. И да это удобно для библиотек например). По умолчанию каст типов будет происходить автоматически, бросая иключения в случае потери данных.
Ну а конфиги в xml это рак, в основном юзают аннотации или yml.
PHP очень похож по семантике на Java/C#, он конечно не дотягивает до них (куда ему), и там есть странности, но писать на нем как на java это более чем нормально. Вопрос в том насколько надо упарываться и насколько люди придерживаются своему здравому смыслу.