Каковы преимущества использования построителей SQL-запросов?


17

Есть ли какие-либо преимущества в использовании построителя запросов, а не в необработанном SQL?

Например

$q->select('*')
  ->from('posts')
  ->innerJoin('terms', 'post_id')
  ->where(...)

против:

SELECT * FROM posts WHERE ...

Я вижу, что многие фреймворки используют такие уровни абстракции, но я не понимаю преимуществ.


Я думаю, что нужно писать запросы против представлений, а не против таблиц. Я склонен думать, что люди, использующие построители запросов, обычно не пишут представления и не просят администраторов баз данных создать их для них. При этом они не используют всю мощь РСУБД.
Тулаинс Кордова

1
@ user61852: Что может быть, кроме запросов некоторой безопасности и фильтрации бесплатно, что запросы к таблицам не могут обеспечить запросы к таблицам?
Роберт Харви

4
@RobertHarvey То же самое, что программирование интерфейсов, а не конкретных классов. Развязка и гибкость. Дизайн базовых таблиц может измениться до тех пор, пока «контракт», представление, остается «имитирующим» те же столбцы, что и раньше.
Тулаинс Кордова

@ user61852 Достаточно справедливо.
Роберт Харви

@RobertHarvey Я превратил это в ответ.
Тулаинс Кордова

Ответы:


20

Абстракция написания SQL через каркас хорошо, рефераты.

Написание SQL вручную не так уж и плохо, но вы начинаете сталкиваться с проблемами, связанными с выходом и очисткой, и это превращается в беспорядок. Слой абстракции может позаботиться обо всем этом за кулисами, позволяя вашему коду быть чистым и свободным от множества mysql_real_escape_string()вызовов и тому подобного.

Кроме того, это дает возможность учета различных диалектов SQL. Не все базы данных построены одинаково, и могут быть различия в ключевых словах или синтаксисе определенных функций. Использование уровня абстракции дает возможность динамически генерировать правильный синтаксис для вашего варианта.

Хотя уровень абстракции может привести к снижению производительности, он, как правило, незначителен по сравнению с чистотой и надежностью кода, который вы получаете взамен.


1
Я не думаю, что диалекты SQL отличаются в разных СУБД. А в PHP есть PDO, который выполняет очистку для вас
Анна К.

12
Диалекты SQL отличаются, поэтому их называют диалектами. Что касается PDO, уровень абстракции просто скрывает этот беспорядок от нас.

@GlennNelson Анна имела в виду любой диалект, использующий разные бэкэнды (PSQL / MySQL / SQLite ...)
Izkata

2
@AnnaK. Диалект может не меняться, но иногда особенности отличаются. Например, MySQL (с механизмом MyISAM) не поддерживает ограничения внешнего ключа, в то время как PostGres поддерживает. Либо диалект должен сам обрабатывать такую ​​вещь (которая требует полного знания структуры данных, как это делает Django ORM), либо, что более вероятно: пользователь должен быть умным в том, как он его использует, что может заставить его выглядеть как диалект меняется, в зависимости от обстоятельств.
Изката

1
+1 за то, что вы позволили хорошо сложенному инструменту убежать и продезинфицировать вас. Если это может также сделать проверку, тогда даже лучше.
Дэн Рэй

11

Сборщики запросов - моя любимая ненависть, поэтому я написал свой собственный Framework (Apeel), чтобы не использовать их!

Если вы используете PDO (что я определенно рекомендую вам сделать), то анализ ввода будет обработан для вас.

Как сказал кто-то еще, хотя они облегчают переключение между базами данных, они, как правило, поддерживают функциональность «Самый низкий общий знаменатель» и либо не поддерживают, либо имеют более низкую производительность для более сложных функций.

Я разрабатывал системы с базами данных примерно с 1986 года, и за все это время я редко сталкивался с компанией, которая фактически меняла базу данных, которую они используют, за исключением тех случаев, когда им требовалась более высокая производительность. Если вы изменяете базы данных для повышения производительности, то имеет больше смысла тратить время на ручную оптимизацию запросов, чтобы получить максимальную отдачу от новой базы данных, а не использовать конструктор запросов для простоты.

Время, потраченное на то, чтобы разобраться с qwirks построителя запросов (а затем переучиться, когда вы переключаетесь на лучший), было бы гораздо более продуктивно потрачено на изучение того, как оптимизировать ваш SQL.

В любом случае, поэтому НЕ использовать один, хотя некоторые люди любят их.


4

Теоретически? Да. Гленн Нельсон указал, как они часто будут вам помогать. (Если это хороший построитель запросов).

На практике? Не всегда соответствует теории и может вызвать проблемы. Предположим, что вы используете построитель запросов к какой-то популярной СУБД, и все выглядит превосходно. Затем клиент просит вас обратиться к его СУБД, в которой есть некоторые причуды, с которыми выбранный вами конструктор запросов просто не может справиться. (Я столкнулся с этой проблемой, когда мне пришлось работать со старой версией Pervasive.)

НО! Что вы должны сделать, это отделить слой доступа к данным и убедиться, что вы можете заменить новый, если это необходимо. Таким образом, вы можете создать этот крутой конструктор запросов со всеми функциями, но если вам нужно подключить новый, который использует этот нечетный псевдо-sql для рассматриваемой БД.


2
Разве что-то вроде странной ситуации с БД не должно быть решено заранее? Я имею в виду выяснение того, какую БД использует ваш клиент, и выбор подходящих фреймворков / библиотек соответственно - это то, что нужно обработать, прежде чем писать одну строчку кода.

3

Я думаю, что практическое, ежедневное преимущество построителя запросов - это повторное использование кода и способность следовать принципу DRY.

С помощью построителя запросов вы можете помещать повторяющиеся части SQL в методы. А затем используйте эти методы для составления сложного SQL. Примером может служить, например, повторно используемое предложение JOIN:

function joinTaskWithClient($queryBuilder) {
    $queryBuilder->join('task', 'contract', 'task.contract_id = contract.id')
                 ->join('contract', 'client', 'contract.client_id = client.id');
}

Таким образом, использование будет:

$queryBuilder->select('client.name')
             ->from('client')
             ->where('task.id=:task')->setParameter('task', 42);
joinTaskWithClient($queryBuilder);

Как вы можете заметить - с помощью построителя запросов вы можете добавлять части SQL в любом порядке (например, часть JOIN после WHERE) в отличие от случая, когда вы собираете строку SQL вручную. Кроме того, вы можете прочитать о шаблоне компоновщика, чтобы увидеть его намерения и преимущества.

Я согласен в отношении экранирования и очистки, но этого можно достичь и без построителя запросов. Относительно абстракции типа БД / диалекта - это довольно теоретическое и сомнительное преимущество, которое практически никогда не использовалось на практике.


Для меня это тоже главное преимущество. Другое - то, что с помощью абстрагирования в методы вы можете дать методам более осмысленные имена и даже создать из них язык, специфичный для предметной области, что сделает цель более ясной. Вы также можете передать конструктор запросов и позволить различным компонентам добавлять в него определенные биты. И последнее, но не менее важное: я обнаружил, что это позволило мне инкапсулировать шаблоны в методах с осмысленными именами .... Я нашел несколько конструкторов запросов, в которых добавление столбцов тупо переписывало более ранние, что делает многие из вышеперечисленных бесполезными ...
malte

2

я предоставлю ответ на основе файла readme моего собственного сборщика SQL ( диалект )

(простой текст следует, удалены ссылки на библиотеку)

Требования

  1. Поддержка нескольких поставщиков БД (например, MySQL, PostgreSQL, SQLite, MS SQL / SQL Server, Oracle, DB2, ..)
  2. Легко расширяется на новые БД (предпочтительно через независимую от реализации конфигурационную настройку)
  3. Модульность и независимая от реализации переносимость
  4. Гибкий и интуитивно понятный API

Характеристики

  1. основанные на грамматике шаблоны
  2. поддержка пользовательских программных представлений
  3. дБ абстракция, модульность и переносимость
  4. готовые шаблоны
  5. экранирование данных

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

Большинство вышеперечисленных функций поддерживаются большинством сборщиков SQL (хотя я не думаю, что все перечисленное поддерживается, насколько мне известно)

Примеры использования:

  1. Платформа CMS, способная работать (без изменения базового кода) с несколькими поставщиками БД
  2. Пользовательский код приложения, в котором поставщик БД может изменяться и / или схемы дБ являются динамическими (это означает, что многие запросы не могут быть жестко закодированы, но все же должны быть достаточно абстрагированы, чтобы код был устойчив к изменениям)
  3. Прототипирование с использованием другой БД, отличной от используемой в производственной среде (по крайней мере, для некоторого кода потребуется дублирующая база кода)
  4. Код приложения не тесно связан с конкретным поставщиком и / или реализацией БД (даже внутри одного и того же поставщика БД, например, с разными версиями поставщика БД), поэтому является более надежным, гибким и модульным
  5. Многие обычные случаи запросов и экранирования данных обрабатываются самой платформой, и обычно это оптимально и быстрее

Наконец, пример варианта использования, который у меня был. я создавал приложение, в котором базовая схема БД (wordpress) не подходила для того типа запросов к данным, которые необходимо было выполнить, плюс некоторые таблицы WP (например, посты) должны были использоваться (поэтому имелись совершенно новые таблицы для всех данных приложения не было выбора).

В этом случае возможность создания MVC-подобного приложения, в котором модель может запрашиваться в соответствии с пользовательскими / динамическими условиями, делает жесткое кодирование запросов почти кошмаром. Представьте себе, что нужно поддерживать запросы к 2-3 таблицам с объединениями и фильтровать условия, чтобы увидеть, к какой таблице присоединиться, с какими, а также позаботиться о необходимых псевдонимах и так далее.

Ясно, что это был случай использования абстракции запроса, и, более того, он нуждался (или, по крайней мере, очень выиграл от этого) в возможности определения пользовательских мягких представлений (конгломерат объединенных таблиц, как если бы они были одной пользовательской таблицей, подходящей для модели) , Тогда это было намного проще, чище, модульнее и гибче. В другом аспекте приложение (код) также использовало уровень абстракции запроса в качестве инструмента нормализации (схема БД) . Как некоторые говорят, это было будущее .

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

Видишь, что я имею в виду?


1

Довольно часто некоторые аргументы для этих запросов действительно являются некоторыми значениями, а не константами. Теперь многие из них по существу были получены из сообщений в форме пользователя. И, следовательно, существует множество возможностей для атак SQL-инъекций. Таким образом, формирование запроса по своей сути требует полной проверки.

Теперь это не означает, что мы не доверяем разработчику, но формирование запроса может быть простым, но повторение всех возможных проверок достоверности везде может означать, что вы можете иногда пропустить случайно или изменить запрос, но не изменять запрос, но не не обновлять проверку проверки. Некоторые новички могут даже знать все опасности пропустить это. Следовательно, абстракция построителя запросов весьма важна.


0

Раньше я думал, что создатели запросов - это приложения с графическим интерфейсом, которые позволяют вам выбирать таблицы и графически объединять их при создании SQL-кода, но теперь я понимаю, что вы также называете создателей запросов API-интерфейсами, которые не требуют создания запросов на чистом SQL. , поэтому абстрагируйся от потенциальных различий в разновидностях SQL.

Использование таких конструкторов запросов - это хорошо , но я склонен думать, что люди, которые в значительной степени полагаются на них, как правило, не спрашивают администраторов баз данных: «эй, этот запрос я часто использую, пожалуйста, создайте из него представление».

Не пойми меня неправильно.

Я думаю, что вы должны писать запросы к представлениям, а не к таблицам. Не для безопасности или фильтрации, которые являются вескими причинами, но по той же самой причине вы должны кодировать против интерфейсов, а не против конкретных классов: разъединение. Представления похожи на «контракты», точно так же, как интерфейсы являются «контрактами» в ООП. Вы можете изменить базовые таблицы, но пока вы заставляете представления показывать один и тот же «контракт» программистам, код не должен нарушаться.

Опять же, не поймите меня неправильно, вы можете использовать конструкторы запросов для запросов к представлениям, но многие представления появляются как процесс maduration, который является результатом необходимости писать запросы и спрашивать вашего администратора базы данных: "man, создайте это, пожалуйста" ,

Я ошибаюсь, думая, что, не написав запросы, вы не можете обнаружить необходимость создания определенных представлений?

Еще одна вещь, которая меня беспокоит, - это то, что начинающие программисты не осваивают SQL, одну из самых красивых технологий, созданных человеком, не делая этого.


Как насчет администратора базы данных, который говорит: «Этот запрос работает плохо, давайте работать вместе и улучшать его». Поначалу все могло работать нормально, но сейчас возникают проблемы. Если все, что нужно, это индекс, зачем беспокоиться об этом с разработчиком?
JeffO

Это совершенно другая ситуация, и все в порядке.
Тулаинс Кордова

Я просто чувствую, что привлекаю DBA каждый раз, когда запрос извлекает одну запись из таблицы или представления, что создает узкое место в процессе разработки.
JeffO
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.