Конструктор SQL-запросов

[sid]

Новичок
Конструктор SQL-запросов

Существует решение, которое называется конструктор SQL-запросов (QueryObject по Фаулеру). Основная идея в генерации SQL кода с помощью объекта. Однако все БД имеют специфический синтаксис. Значет если реализовывать QueryObect в рамках ANSI SQL, то мы отказываемся от использования специфичных и полезных возможностей конкретной БД. Но не переписывать же объект для каждой БД.

Может кто-нибудь сталкивался с этим решением и может поделиться опытом его использования. Конкретно интересует насколько это обосновано писать конструктор для конкретной БД или лучше реализовывать конструктор на ANSI SQL.
 

StUV

Rotaredom
с учетом недавнего опыта правки багов в системе написанной с использованием Qt, ничего кроме матерных слов в адрес "ОО конструкторов SQL запросов" в голову не приходит....
 

Tor

Новичок
[sid]
посмотри, как это сделано во "взрослых" проектах

-~{}~ 30.06.05 08:41:

ADODB, PEAR :: DB, etc.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Tor, SelenIT: вы очевидно не поняли вопроса и выставили себя идиотами, ляпнув первое пришедшее в голову. ха-ха-ха.

[sid]
Однако все БД имеют специфический синтаксис. Значет если реализовывать QueryObect в рамках ANSI SQL, то мы отказываемся от использования специфичных и полезных возможностей конкретной БД. Но не переписывать же объект для каждой БД.
Правильно, поэтому нахрен такие решения. Схема базы должна быть оптимизирована, запросы должны быть оптимизированы (если конечно не пишется приложение типа phpWhateverAdmin). А сгенерировать можно крайне неудачные запросы --- кто его знает, как этот QueryObject внутри работает...
 

Vasya

Guest
писать конструктор для конкретной БД или лучше реализовывать конструктор на ANSI SQL
Imho, лучше сделать небольшую иерархию. То есть, в базовом классе реализовать ANSI, а в потомках, заточенных на конкретную СУБД, перекрыть специфичные методы.
 

ForJest

- свежая кровь
[sid]
Для нескольких СУБД нужно будет иметь несколько вариантов конструктора запросов. Конструктор запросов не решает проблемы поддержки разных СУБД. Никак.
Поэтому не нужно задаваться этим вопросом в таком аспекте.
Точно также как построитель математических выражений не может помочь решать уравнения различных типов.
 

[sid]

Новичок
Tor, SelenIT
Ребята вы вообще вопрос читали? :)

ForJest
Безусловно, но не решает, но на это есть уровень абстракции от БД.

Vasya
То есть вы предлагаете реализовать в базовом классе ANSI, а в производных конкретную специфику БД?
Может оно и хорошо, но я не совсем представляю как это можно сделать. Самое большое отличие м/у разнами БД - это список используемых функций для обработки данных. Учитывая как эти функции могут компоноваться, я даже незнаю, как подобный механизм может быть реализован!
 

crocodile2u

http://vbolshov.org.ru
fixxxer в форуме по MySQL предлагал (и не так давно) решение: в "конструктор" передается шаблон запроса, составленный по определенным правилам, и данные, кот. должны быть вставлены в запрос. Такой подход, конечно, более примитивен, что ли, по сравнению с "Универсальным Конструктором Запросов", зато его несложно переписать под диалект любой СУБД, весит он мало и работает шустро. Но запросы (в данном случае шаблоны запросов) придется писать самому.

Если ближе к данной конкретной теме - честно говоря, не вполне представляю себе такой конструктор, даже и для одной СУБД. Получится программа, которая пишет программу...
 

ForJest

- свежая кровь
http://patternshare.org/default.aspx/Home.MF.QueryObject
A Query Object is an interpreter [Gang of Four], that is, a structure of objects that can form itself into a SQL query
-------------
Это структура или объект, которая может трансформировать себя в SQL запрос.
[sid]
Это шаблон проектирования.
Шаблон. Проектирования.
Не решение. Не объект. Не класс. Это шаблон проектирования.
А та каша которая получилась в этом обсуждении из-за того, что обсуждается реализация чего-то что притянуто за уши называется похожим на этот шаблон.
Давай мы разберёмся с тем, что всё таки обсуждается?
 

crocodile2u

http://vbolshov.org.ru
Возможно, автору покажется интересным:

http://propel.phpdb.org/
http://www.wiki.cc/php/Object_Relational_Mapping

Это не совсем то, что здесь обсуждается (по крайней мере, как я это понимаю), но все же тесно связано с этими вопросами.
 

[sid]

Новичок
crocodile2u
Насчет вашего подхода, я так сейчас и делаю. Просто хотелось найти методы автоматизации конструирования запросов. Видимо это очень сложно.

За линки спасибо, я знаком с ORM Propel - это действительно немного не то о чем я спрашивал :)


ForJest
Никакой каши здесь нет. Я ясно представляю идеи, которые высказывают люди. Возможно я не совсем точно задал вопрос. Если так, то обратитесь к QueryObject по Фаулеру. Меня интересует опыт применения данного паттерна на практике, потому что я прекрасно понимаю высказанную им идею (и она не нравиться), но честно говоря, не совсем понимаю как он может быть полезен, особенно в долосрочных проектах!
 

StUV

Rotaredom
[sid]
для нахождения правильного решения вопроса необходимо сначала достаточно точно его (вопрос) сформулировать...

ты можешь подробно описать для чего тебе понадобился такой конструктор и какие функции он должен выполнять?

(решений данной задачи очень много и каждое из них "заточено" под свой круг задач - самое универсальное решение (имхо) - это конкретный диалект SQL конкретной субд)
 

[sid]

Новичок
StUV
Насчет диалекта согласен.

Насчет задач, еще раз повторяюсь, QueryObject по Фаулеру (посмотрите там все изложено по полочкам). Если кто не знаком вкратце скажу, что это объет конструирующий SQL-код (это не уровень абстракции от БД). Интересует, кто сталкивался с ИСПОЛЬЗОВАНИЕМ такого решения и может что то сказать в его защиту! Конкретно интересует, находил ли кто-то удобный механизм абстракции от специфических возможностей БД (функции, языковые конструкторы).

Хотелось, что бы это решение могло оперировать не только критериями ORDER BY, GROUP BY etc. Но и функциями спецефичной БД, при этом оставалась возмножность переноса механизма на диалект другой СУБД. Возможно ли это или это утопия? (Что то я все больше к последнему склоняюсь :)
 

syfisher

TDD infected!!
[sid]
А почему необходимо выносить уровень "независимости" от конкретной СУБД именно в конструктор SQL? По-моему, логичнее выносить это на один уровень выше - так называемый Data Access Object, который уже делегирует QueryObject-у. QueryObject по моему опыту полезен именно с точки зрения того, что его можно передавать между различными классами, которые могут принимать дополнительные решения и дополнять его условиями, полями и т.д.
Уверенности в том, что он будет эффективным решением с точки зрения переносимости в общем-то нет.

Не сочтите за рекламу, но вот ссылка

http://limb-project.com/wiki/doku.php?id=limb:ru:3_x:architecture:daos

схемы, где используется некая реализация QueryObject-а. На UML диаграмме это ComplexSelectSQL. SQLBaseDAO может аккумулировать несколько критерий. Атрибут SQLBaseDAO $sql класса ComplexSelectSQL затем передется в метод process(&$sql) каждого критерия и в конечном итоге получаем тот запрос, который удовлетворяет всем критериям. Таким образом, якобы можно постараться достить повышения уровня повторного использования кода классов критериев. На практике - пока слишком мало прецедентов.
 

[sid]

Новичок
syfisher
Спасибо за ссылку, но я LIMB уже до дыр заездил! :)

В целом, примерно так же я и собираюсь реализовать свое решение!

В данном случае, переносимость, в принципе существенно выше, но проблема в том, что тогда QueyObject обладает слишком маленькой степенью детализации. Мы опять таки приходим к ANSI SQL (прощай ПОЛЕЗНАЯ специфка БД), так как сгенерировать код из такого QueryObject который будет рационально и оптимально использовать конкретную БД, помоему, невозможно. Если это не так, то поправьте меня пожалуйста.
 

robocomp

Новичок
[sid]
возможно, я тоже не понял вопроса, но мне неясно, в чём проблема -)
(Шаблон квери обжект я посмотрел, три прямоугольника диаграммы асилил успешно)

Реально пользовался такой штукой. Показалось неудобно и не понятно -(
Наверное, у нас просто получилась кривая реализация, вот что.
Но вышло так, что новые разработчики посто офигевали от того, где же какой запрос, как он собирается и где его найти
опять же на этапе, когда у нас сервер начал утуплять под нагрузкой и в результате анализа логов запросов были выявлены явные кандидаты на модернизацию (запросы) найти места, где эти запросы выполняются было _не_просто_. Авторитеные разарботчики ПО говорили: "О-о-о-о. Фиг знает. Ща поищу"
Я вот лично не нашёл пару запросов в своём коде -(
Собственно, вот и все.
Плюсы -- не надо писать запросы SQL, чего большинство "талантливых" программстов пхп просто не умеют. (на собеседовании задаю вопрос, где надо сделать лефт жоин и груп бай -- мягко говоря единицы отвечают -( может, фигово задаю?)


Об абстракции от бд:
м-м-м. на первый мысль приходит фабрика какая-нить в голову.
которая достаёт в зависимости от используемой СУБД соотвествующую реализацию queryObject
если конкретной реализации нету, то достаётся "куцая" реализация для ANSI SQL.

Насчёт того, что "переносимость нужна нечасто", как говорил один автор.
Она нужна нечасто в реальных приложениях. А вот [sid] походу решил написать каркас, который покажет миру, кто здесь кул хацкер, поэтому переносимость на самом деле нужна

Вот например мы не стали юзать пропел, потому что креол не понимает оракула. Точнее, как у них на сайте было написано "не очень хорошо понимает"
 

StUV

Rotaredom
новые разработчики посто офигевали
это точно =)))
да и не только новые ;-)

[sid]
имхо, QueryObject есть смысл использовать только для составления простых запросов.
там же где важна оптимизация - запросы надо писать руками
в крайнем случае можно сохранять текст запросов для разл. субд (напр. в файл) и по месту использовать соответствующий.

По поводу переносимости - для переписывания действительно важных (тормозных) запросов под конкретную субд опытному sql-прогеру понадобится намного меньше времени, чем понадобится времени тому же php-шнику на оптимизацию одного запроса "в случае чего..." при использовании КвериОбжекта
 

robocomp

Новичок
StUV

к слову, о "сложных запросах, написанных руками"
можно посмотреть мануал по propel и hibernate где как раз такой вариант и рассмотрен.
 
Сверху