All streams
Search
Write a publication
Pull to refresh
13
0
Сергей Роговцев @lair

Архитектор

Send message
Оптика привязана к размеру кадра. То, что шикарно рисует на 13х18, на 135-ом выглядит унылым мылом.
Ну и зря удивились бы, хороший пластик заведомо лучше стекла по защитным свойствам. Не зря же защитные очки из пластика делают.
"… и получаем тот же SQL только другими словами"
Не тот же, а типизованный на языке выполнения. Что круто.

«только ради проверки типов?»
Вы не поверите, сколько ошибок экономит это «только». Не говоря уже о том, что не только типов, но и свойст, собственно объектов и так далее. Это как перейти от языка с динамической типизацией к языку со статической — сразу количество ошибок кода уменьшается в разы. Это сильно перевешивает те доли процента производительности, которые нужны на пробег дерева выражений.

«оно доступно только в проприетарном и тяжелом .NET»
Это эти конкретные лямбды доступны только в .net (оставим эпитеты на вашей совести). А другие языки используют другие методы привязки. Всего-то. К ORM как парадигме это отношения не имеет.

«у нас в PHP нестрогая типизация. Компилируется практически все, что угодно»
Сочувствую. Неудивительно, что вам в PHP выгоды ORM неочевидны.
«Потому что, не знает, что программист захочет сделать»
Ну так программисту достаточно это сказать.

"$top_posts = Posts::findTopPosts();

foreach ($top_posts as $post)
{
echo «Post: {$post->title} written by {$post->author->name} \n»;
}

Сколько тут будет SQL запросов? Даже если использовать исхищрения вроде lazy load, сначала будет сделан запрос на выборку записей из Posts по условию (причем выбраны скорее всего будут все поля. хотя нам нужны только title), а потом — N запросов на выборку из таблицы authors. В момент выполнения первого обращения к $post->title ORM не знает, что дальше программист полезет в $post->author->name, и не может заранее выбрать нужные данные."

$top_posts = Posts::findTopPosts();

foreach ($top_posts as $post)
{
echo «Post: {$post->title} written by {$post->author->name} \n»;
}

Сколько тут будет SQL запросов? Даже если использовать исхищрения вроде lazy load, сначала будет сделан запрос на выборку записей из Posts по условию (причем выбраны скорее всего будут все поля. хотя нам нужны только title), а потом — N запросов на выборку из таблицы authors. В момент выполнения первого обращения к $post->title ORM не знает, что дальше программист полезет в $post->author->name, и не может заранее выбрать нужные данные."

Берем и правим:

Posts::findTopPosts().With($post->title).With($post->author.With($author->name))

(если ваш язык не умеет лямбды — извините. Берите ORM, который умеет)

Все, в базу уйдет ОДИН запрос.

«хотя раз вы из защищаете, вы видимо этого не делали»
Конечно не делал. Чукча не читатель, чукча писатель — я написал два разных универсальных ORM, не считая еще нескольких объектных DAL.

«Логика подсказывает, что городить кучу сложного неэффективного кода только для того чтобы сделать «переносимые» обращения к хранилищу — не стоит того.»
Вы просто не понимаете, что задача ORM — не «переносимые» обращения. Задача ORM — представить базу в виде объектов. Типизованных. Все. Больше ничего.

«Вам никогда не казалось глупым городить кучу объектов, для того чтобы вместо «photos_count > 10» написать new Criteria(new CompareCriteria(PhotosModel::PHOTOS_COUNT, CompareCriteria::MORE, new CriteriaInterger(10)))?»
Во-первых, не казалось, потому что критерий «photos_count > 10» не проверяем в компайл-тайме. Что на наличие поля photos_count, что на его тип.

Во-вторых, я уже давно и спокойно пишу Context.Albums.Where(album => album.Photos.Count() > 10), и у меня все работает. Никакой кучи объектов — и полная проверка валидности обращения в компайл-тайм, если в альбоме нет коллекции фотографий, то и выражение не скомпилируется.

«Потому что есть штуки вроде UPDATE posts SET deleted = 1 WHERE author_id = $id, а с ORM — будет цикл с чтением/записью объектов в БД по одному.»
Во-первых, в любом адекватном ORM можно прочитать оптом и записать оптом. Во-вторых, такие операции надо делать на стороне БД, и для этого есть data methods. В-третьих, в реальности это наверняка бизнес-поведение, и его можно спрятать в объект, который и спроецирует его на базу.

«Это ORM-подход — все прочитать, а потом уже разбираться.»
Это подход плохого программиста (я вот как раз уже несколько месяцев чищу сугубо RDBMS-oriented код, в котором все делается именно так). Подход ORM — прочитать, преобразовать, отдать. «Все» нигде не фигурирует.

«С ORM мы даже не знаем, в сколько запросов (и будут ли они например использовать индексы) выльется та или иная операция. „
Ну так просто надо это знать. С RDBMS вы тоже это не всегда знаете.

Любой механизм требует изучения. ORM — тоже. Нельзя работать с данными, отдаваемыми ORM так же, как с любыми другими данными, точно так же, как нельзя работать с данными из веб-сервиса так же, как с любыми другими. Точно так же, как надо учитывать особенности работы рекордсетов и курсоров при работе с ними. В момент, когда программист это понимает, работа становится прозрачной.
… а это мы с вами обсудим выше.

И, спешу заметить, задача ORM — не в том, чтобы абстрагироваться от особенностей БД (хотя, конечно, это приятный бонус).
«Потому, что способ доступа к данным, предлагаемый ORM, нельзя оптимально реализовать с существующими реляционными БД по крайней мере. „
Аргументируйте.

“Потому что ORM как бы представляет базу в виде набора объектов, которыми она *не является*.»
Это верно для любого DAL, будь он ORM или не-ORM. Этот маппинг все равно есть.

«Оптимальный способ доступа к БД — выборка всех интересующих данных хорошим запросом с индесом и их разбор — и нормально составить такой запрос ORM принципиально не способен, хотя бы потому, что не знает, какие данные понядобятся в будущем.»
Почему же не знает? Вполне знает, если ORM написан хорошо и используется хорошо.

«Кроме того, уровень многих программистов низок, и в ходе написания ORM они еще ухудшают ситуацию, делаю «прослойку» еще более неэфффективной и требовательной к ресурсам.»
Это верно и для чистой RDBMS.

«Также ORM'ы плохо работают там, где надо работать с группами сущностей (особенно большими), а не отдельнми объектами.»
Почему? Аргументируйте.

«Опять же, БД с большими таблицами работают замечательно.»
На стороне клиента-то? И давно вы читали на клиентской стороне рекордсет записей так в миллион?

«И все попытки их как-то по-другому представить будут вести к низкой эффективности операций с ними. „
Вы забываете о том, что они уже “как-то иначе» представлены. Маппинг так или иначе существует, пусть он и идет на объект типа датасет. Единственный способ работать с данными без преобразований — это прямо в базе.
Я сказал — если все и правда супер. Какие тогда дыры?
Я же специально сказал — и один запрос на вставку узла (если удалось — на перемещение). Там, где можно сделать выборку одним запросом, нельзя сделать вставку одним запросом. Там, где можно сделать вставку, нельзя выборку. Плавали.

«А вообще, вы так говорите, как будто только от наличия ООБД эти проблемы с хранением иерархических данных сами собой решатся.»
Вы немного потеряли тему. Речь шла исключительно о том, зачем писать непереносимые запросы. ООБД тут уже не при чем.
А какая разница программисту, естественный это процесс, или иллюзия, если все и правда супер?
Ну тогда приведите конкретный пример с цифрами.
Уверены, что не выйдет так, что если грамотно продумать структуру и архитектуру, то выигрыш по скорости от использования RDBMS покроет недостатки от использования не-нативного ORM?
Пользователь иногда ищет по полям, по которым индекса нет (потому что «иногда», а не «часто»). Вот и привет «с точки зрения логики нативная работа со структурами данных быстрее».
«ну два запроса… сначала вставить узел, а потом обновить указатели на родителя у узлов-потомков, чтобы они ссылались на новый узел»
Схема с pattern id? Таки покажите мне запрос, которым вы выберете всех предков одного узла. Вверх до корня. Одним запросом.

«кроме того, я не понимаю зачем в базе данных хранить объекты размеров в 2 гб. в таком случае я храню их в файлах, а в базе делаю ссылку на файл. чем это хуже?»
Потерей целостности, например. Проблемами с блокировками. Проблемами при разнесении на фермы. Да мало ли чем еще.
«А без индексов будет феерический звездец по производительности»
… что, давайте покроем все поля индексами?

«Я лично щупал монгодб, там данные хранятся в BSON, никакого отношения к RDBMS оно не имеет. „
И как bson реагирует на запрос по неидексированному полю?
А без индексов? Запрос бывает и не по индексированному полю.

(а еще бывают трюки с покрывающими индексами, скажем, или полнотекстовыми, или xml — в итоге выходит, что для реализации всего этого проще взять движок RDBMS и немного допилить напильником. Смотри на шарпойнт.)
«о каких эффективных запросах вы говорите? select? можно, например для oracle, написать что-то типа «select oracle_super_performance_magic_key name, value as blob from MyTable where id = ?» и такой запрос в oracle вытянет blob с потрясающей быстротой?»
А вот нет. Я хочу читать данные секторами (и писать секторами). И вот сделать это переносимо — нельзя. Поэтому и выше в запросе name и value могут быть блобом, только нафиг мне нужен двухгиговый блоб в памяти?

«если нет, то какая разница: иерархия это или нет?»
Большая. Напишите мне один простой запрос, возвращающий всех предков заданной точки дерева. Удалось? Теперь напишите такой же простой запрос, который вставит узел в это дерево в произвольную точку.
Вот и возникает вопрос — а за счет чего она сравнима? «Что у нея внутре»? Ведь «с точки зрения логики», сканирование табличных данных выгоднее, нежели сканирование произвольных структур. Не выходит ли так, что внутри там, на самом деле, неявная генерация табличного представления для каждого «типа» документов?

В частности, шарпойнт — тоже в каком-то смысле документоориентированная СУБД (как и TFS). Но внутри там RDBMS, просто специальным образом организованная.
А вы попробуйте написать переносимый запрос, эффективно работающий с иерархическими данными. Или с блобами. Или с полнотекстовым поиском.

Сразу становится понятно, зачем писать то, что непереносимо.
Это когда вы решаете задачу «прочитать-записать».

А когда вы решаете задачу «найти все, удовлетворяющие условию», как тогда?
Должна. Именно поэтому я предпочитаю те системы, которые умеют делать верификацию структуры данных при ее изменении.

Information

Rating
Does not participate
Location
Montreal, Quebec, Канада
Date of birth
Registered
Activity