Разбор prepared statements. Клиент vs. сервер.

Фанат

oncle terrible
Команда форума
Разбор prepared statements. Клиент vs. сервер.

Вопрос очень простой.

Какие есть преимущества у библиотек, которые производят разбор на стороне сервера (PDO, mysqli) перед самописными, которые делают разбор на клиенте?

Сам я в этих вопросах плаваю, поэтому хочу спросить мнение тех, кто сам работал.
Пока у меня такая информация:
Сервер.
+ гарантия отсутствия инъекций
- невозможность увидеть запрос в "классическом" виде, чтобы, к примеру, скопировать в консоль
- неполная поддержка некоторыми библиотеками синтаксиса запросов (SHOW в PDO)

Клиент
+ отсутствие минусов серверных библиотек.

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

A-Lex[FM]

Web/Highload/DataScience
Ты сам и ответил на свой вопрос.
Я юзаю уже несколько лет самописную библиотеку и не вижу минусов перед серверными.
Зато я точно знаю сколько по времени занимает обработка каждого запроса, могу посмотреть все запросы, которые выполнялись во время работы скрипта, также реализованы плэйсхолдеры, как в MySQLi.
Единственным минусом является скорость обработки запроса, так как он предварительно парсится скриптом, для подставления значений плэйсхолдеров, но это не сильно замедляет время генерации.
 

alexhemp

Новичок
ганатия отсутствия инъекций - я бы не был так бескомпромиссен... вполне может быть баг и в серверном коде.

Клиент
+ более широкий спектр плейсхолдеров и возможностей вообще (опять-же на примере dbSimple - списковый идентификаторный плейсхолдер, условный плейсхолдер - вообще на порядок улучшает читабельность).
+ поддержка плейсхолдеров для тех СУБД, где их нет
 

Фанат

oncle terrible
Команда форума
У меня тут другой вопрос возник.
по поводу динамического составления запросов.
К примеру, динамическая генерация блока WHERE.
Можно ли это сделать с помощью prepared statements?
или по-хорошему, для этих целей служат сохранённые процедуры?
Как с этим обходятся в DBSimple?
 

Wicked

Новичок
ганатия отсутствия инъекций - я бы не был так бескомпромиссен... вполне может быть баг и в серверном коде.
И к тому же, если не ошибаюсь, Гравицапа уже упоминал про то, что PDO не спасет от криворуких программистов, которые даже с PDO составляют запросы руками:
PHP:
$pdo->prepare("select '".$firstname."', :lastname");
По поводу скорости разных подходов, мне она видится в таком порядке по убыванию:
1) серверные плэйсхолдеры (pdo, mysqli)
2) запросы, полученных путем конкатенации
3) клиентские плэйсхолдеры

по поводу динамического составления запросов.
К примеру, динамическая генерация блока WHERE.
Можно ли это сделать с помощью prepared statements?
Насколько гибко нужно изменять блок WHERE ? Если, например, просто сделать некоторые условия опциональными, то тут подойдет "param = :param OR :param IS NULL"
 

hermit_refined

Отшельник
Как с этим обходятся в DBSimple?
с помощью { }: SELECT * FROM goods WHERE category_id = ? { AND activated_at > ? }
К примеру, динамическая генерация блока WHERE.
Можно ли это сделать с помощью prepared statements?
PDOStatement->execute() принимает массив входных параметров, который можно генерировать одновременно с запросом.
это, конечно, подходит и для подстановок на стороне клиента, в т.ч. для DBSimple.
 

algo

To the stars!
1) Prepared statement парсится и оптимизируется в момент prepare, так что дальнейшие выполнения не требуют генерации плана => prepared требует меньше ресурсов

2) Prepared statement передают от клиента к серверу только данные запроса + Statement ID, а не весь текст запроса целиком => меньше трафика

3) Существующее Mysql API уж конечно быстрее и эффективнее самописной либы на PHP.

В архитектуре PHP/MySQL (раз уж вопрос задан в этом форуме) это не очень играет, т.к
а) Prepared'ы не сохраняются между разными скриптами
б) Mysql парсинг и оптимизация очень простые, в отличие от Oracle/DB2/etc.
в) Как правило, затраты на самописный парсинг в п.3 составляют малую часть затрат всего приложения.

Лично я использую форк библиотеки Котерова на PHP, т.к она предоставляет более удобный синтаксис для списков: WHERE a IN (?@) и не только.

Если же важно что-то из пунктов 1-3 или не хочется привлекать стороннюю библиотеку, тогда конечно mysqli + prepared.


P.S Модифицировать текст запроса и количество данных в prepared нельзя AFAIK ни в какой БД, можно только константы разные подставлять.. И с планом, конечно же, замута - не всегда один и тот же план нужен для разных констант... Но это отдельный разговор и средства есть в некоторых базах для этого.
 

alexhemp

Новичок
Фанат

Собственно под условной генерацией понимается банальное

Код:
$query = "SELECT * FROM TABLE WHERE 1 AND ".(!empty($var) ? "FIELD=?" : "");
$db->query($query, $var);
А Котеров это заменил на элегантное
Код:
$query = "SELECT * FROM TABLE WHERE 1 AND {FIELD=?}";
$db->query($query, 
      empty($var) ? DBSIMPLE_SKIP : $var
);
Но ясное дело - такой синтаксис ни один сервер не поддерживает.
 

camka

не самка
Раз уж мы говорим о преимуществах:

- Основное преимущество prepared statements на стороне сервера именно в их более быстром запуске. Причины упомянул algo. И использовать их следует _только_ для достижения этой цели и _только_ в случаях, когда один и тот же запрос _надо_ запускать несколько (больше одного) раз с разными параметрами.
Попробуйте, сделайте тесты, запуская несколько раз подготовленный на серверной стороне запрос и тот же запрос, каждый раз заново запрашиваемый с клиента. Разница в скорости очень ощутима, особенно, если запрос сам не является тяжелой выборкой, а, скажем, передает данные на добавление или обновление. Так что тут algo не совсем прав, говоря, что в PHP/MySQL эта технология не достойна использования.

- Основное преимущество клиентской реализации - удобство обработки этих самых изменяющихся параметров, подставляемых в запросы.
 

Фанат

oncle terrible
Команда форума
Супер.
Очень полезная для меня тема получилась.
ещё бы сил найти всё это систематизировать и в вики засунуть...
 

camka

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

То есть, каждый тип следует использовать именно для того, для чего он создан.
 

algo

To the stars!
camka:

Так что тут algo не совсем прав, говоря, что в PHP/MySQL эта технология не достойна использования.
На всякий случай замечу - ничего подобного я не говорил.. И уж тем более не писал =))
 

camka

не самка
Креплюсь, креплюсь, а порой не выдержу да и привру ненароком.
 
Сверху