Абстракция базы данных - поддержка нескольких синтаксисов

StackOverflow https://stackoverflow.com/questions/216329

Вопрос

В PHP-проекте, над которым я работаю, нам нужно создать несколько расширений DAL для поддержки нескольких платформ баз данных.Основная ошибка, с которой мы сталкиваемся при этом, заключается в том, что разные платформы имеют разный синтаксис - примечательные MySQL и MSSQL совершенно разные.

Что было бы лучшим решением для этого?

Вот пара примеров, которые мы обсуждали:

Построение SQL на основе классов

Это потребовало бы создания класса, который позволяет вам создавать SQL-запросы побитово.Например:

$stmt = new SQL_Stmt('mysql');
$stmt->set_type('select');
$stmt->set_columns('*');
$stmt->set_where(array('id' => 4));
$stmt->set_order('id', 'desc');
$stmt->set_limit(0, 30);
$stmt->exec();

Однако для одного запроса требуется довольно много строк.

Переформатирование синтаксиса SQL

Этот параметр намного чище - он будет считывать SQL-код и переформатировать его на основе языков ввода и вывода.Однако я вижу, что это гораздо более медленное решение с точки зрения синтаксического анализа.

Это было полезно?

Решение

Я бы порекомендовал создавать SQL на основе классов и рекомендовал Доктрина, Zend_Db или MDB2.И да, если для написания простых выборок требуется больше строк, но, по крайней мере, вы можете полагаться на синтаксический анализатор и вам не нужно заново изобретать колесо.

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

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

Другие советы

Решением могло бы быть наличие разных наборов запросов для разных платформ с идентификаторами что-то вроде

MySQL:GET_USERS = "ВЫБРАТЬ * ИЗ пользователей"

MsSql:GET_USERS = ...

PgSql:GET_USERS = ...

Затем при запуске вы загружаете необходимый набор запросов и затем ссылаетесь

Db::loadQueries (платформа):

$users = $db->запрос(GET_USERS)

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top