Как управлять операторами SQL на уровне данных - PullRequest
2 голосов
/ 30 марта 2009

в проекте PHP мы уже отделили бизнес-логику от доступа к базе данных. Все задачи базы данных инкапсулированы в разные классы базы данных, сгруппированные по базе данных и теме. Эти классы выглядят очень ужасно, половина источника - строки SQL, которые заполняются параметрами и так далее. Мы думали о размещении SQL в «других» местах, таких как файлы ресурсов или что-то в этом роде. Что считается лучшим для этого, и знаете ли вы какие-либо вспомогательные инструменты / библиотеки для PHP?

С уважением

Stephan

Ответы [ 4 ]

2 голосов
/ 31 марта 2009

Я не знаю PHP, но по своему опыту работы с другими языками я могу вам многое сказать: слои доступа к данным являются главной целью астронавтов архитектуры . Существует так много «лучших практик», что ни один из них не является действительно лучшим. При разработке DAL очень легко попасть в ловушку чрезмерного абстрагирования. Просто зайдите так далеко, как вам нужно.

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

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

2 голосов
/ 30 марта 2009

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

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

Другой подход может заключаться в создании Query-классов, в которых запросы создаются динамически;

class FruitQuery {
    ...
    public function addTypeCriteria($type) {
        $this->internalSQLCriterias[]  = "fruit=:type";
        $this->internalSQLParameters[] = array(':type', $type);
    }
    ...
    public function create() {
        $this->internalSQLQuery = "SELECT ... FROM Fruits";

        if (sizeof($this->internalSQLCriterias) > 0) {
            $this->internalSQLQuery .= " WHERE ";
            $moreThanOne = '';

            foreach ($this->internalSQLCriterias as $criteria) {
                $this->internalSQLQuery .= $moreThanOne . $criteria;
                $moreThanOne = " AND ";
            }
        }
    }
    ...
    public function execute() {
        /* Bind the parameters to the internalSQLQuery, execute and return results (if any) */
    }
...

Этот класс абсолютно не завершен в любом случае, и вы, возможно, захотите переосмыслить его структуру - но вы, вероятно, поймете мысль, которую я пытаюсь сформулировать. :) Конечно, вы должны отфильтровать входные данные для построителя запросов, чтобы избежать нарушений безопасности!

0 голосов
/ 30 марта 2009

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

В теперь известном паттерне MVC ваша бизнес-логика равна , что обычно содержит SQL, который формирует слой модели.

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

  1. Если в SQL есть заметное повторение, я бы добавил быструю рефакторинг, чтобы скрыть все общие методы SQL внутри. Методы не обязательно должны его выполнять, а просто создавать. Все зависит от вашего приложения и того, каким образом SQL сложен. Если у вас нет нижележащего слоя, который осуществляет фактическую связь с базой данных, возможно, частью рефакторинга может быть его добавление.

  2. Я бы подумал о построителе запросов. Что является очень хорошим балансом между производительностью и гибкостью. Вы можете найти построитель запросов только как часть уровня ORM или доступа к базе данных (например, Zend_Db и его подкомпонентов), Propel и / или Doctrine. Таким образом, вы можете перенести построитель запросов с одного из них на ваш проект, не используя весь слой (что на самом деле не должно быть сложным, поскольку все они основаны на PDO). Это не должно добавить каких-либо заметных проблем с производительностью.

  3. Я бы рассмотрел доктрину ОРМ. Это имеет значительное влияние на производительность, хотя. Однако в итоге вы получите очень легко обслуживаемый код.

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

0 голосов
/ 30 марта 2009

Ну, вы всегда можете использовать PDO для согласованного API для разных баз данных и писать переносимые операторы SQL .

Другим вариантом будет использование уровня абстракции базы данных, например Zend_DB .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...