Comments 38
Как-то раз я столкнулся со схожей структурой в mysql — где были объект и атрибуты объектов и все на сайте от статей до пользователей было перемешано — собрать один объект было то-еще веселье из кучи JOIN'ов и подзапросов.
Вытащить данные по серии объектов и взаимосвязями для отчета — локальный персональный ад.
Теперь я понял куда смотрели разработчики той системы и как это сделать правильно.
Спасибо!
P.S Пользователи статьи конечно разделили на разные микросервисы c postgres, а товары крутится на mongo.
Я видел негативные статьи, что OrientDB теряет данные (хотя негативные статьи можно найти про любую популярную БД).
В стартапе использвал, но до тяжёлого боя он, к сожалению, не дожил.
Отвечает Александр SbWereWolf Друзь.
на ру-трекере
Нахрена качать DataGrip с рутрекера, если можно взять с официального сайта?
А все потому что имя таблицы и поля, в sql нельзя использовать как параметр, в том числе в виде списка, хотя чисто технически это вполне возможно, + добавить оптимизации аналогичные полнотекстовому поиску, вроде индекса объединяющего несколько таблиц.
типа:
select t.primarykey from (select table from tables where table_name like ...) t where (select field from t.fields where field_name in (..)) like ...
а не Javaу пихать в RDBMS *картинка с грозящим кулаком мужиком*.
https://en.wikipedia.org/wiki/Anchor_modeling
Create index Object.description on Object( description by value ) fulltext
engine lucene metadata {
"analyzer" : "org.apache.lucene.analysis.ru.RussianAnalyzer"
}
Почему только RussianAnalyzer? Как с остальными языками быть?
Да, по хорошему для каждого языка нужен свой полнотекстовой индекс:
Create property Object.title_en string ( collate ci )
Create index Object.title_en fulltext
engine lucene metadata {
"analyzer" : "org.apache.lucene.analysis.ru.EnglishAnalyzer"
}
Create property Object.title_ru string ( collate ci )
Create index Object.title_ru fulltext
engine lucene metadata {
"analyzer" : "org.apache.lucene.analysis.ru.RussianAnalyzer"
}
Select from Object
where searchable = true
and ( title_ru lucene "Ска*" or description_ru lucene "Ска*" )
Как определить язык запроса — вопрос отдельный.
P.S. Есть свой реляционный звездолет (Какие реализации могут быстро искать пересечение множеств (система тегов)?) на
OrientDB выглядит очень привлекательно. Намучился с MongoDB. Собирался переехать на PostgreSQL — нужны связи. Но смущают тесты производительности https://www.arangodb.com/performance/
Предполагаю, что выборки по графам OrientDB будут быстрее цепочки джоинов в PostgreSQL, если рассматривать этот пример.
Навскидку у этого бенчмарка есть следующие косяки:
- Используется графовое апи, хотя документное (использованное в этой статье) и быстрее и как правило удобнее.
- В одних субд (аранго) используются первичные ключи, а в других (ориент) — вторичные (как slug в этой статье), что даёт лишний поиск первичного ключа.
Ща попробую у себя погонять.
- Почему они используют графовое апи стало понятно — для вычисления shortest-path на графе. Другое дело, что shortest-path — довольно специфичная штука. Навскидку не могу придумать где она могла бы быть полезна.
2 Для получения идентификаторов друзей там делается следующего вида запрос в OrientDB: select out_Relationship._key as out from Profile where _key="P1" limit 1000
То есть сначала по вторичному ключу ищется первичный ключ, по нему читается запись из которой берутся первичные ключи друзей, а потом вытягиваются записи для всех 1000 друзей, чтобы взять у них вторичный ключ. Для сравнения, запрос в MongoDB: .find({_from: id}).toArray(function (err, result) { result = result.map(function (e) { return e._to.substr(2); });
, то есть из коллекции рёбер делается выборка по индексу и эта выборка с минимальными трансформациями возвращается.
Вот, кстати, наткнулся на ответ разработчиков OrientDB: http://orientdb.com/orientdb-performance-challenge/
Java же прожорлива в этом плане.
Пилим каталог товаров не притрагиваясь к реляционной алгебре