Доступ к данным на основе хранимых процедур в веб-приложениях::Журнал СА 1.2009
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Наука и технологии
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Событие  

В банке рассола ждет сисадмина с полей фрактал-кукумбер

Читайте впечатления о слете ДСА 2024, рассказанные волонтером и участником слета

 Читать далее...

Организация бесперебойной работы  

Бесперебойная работа ИТ-инфраструктуры в режиме 24/7 Как обеспечить ее в нынешних условиях?

Год назад ИТ-компания «Крок» провела исследование «Ключевые тренды сервисного рынка 2023». Результаты

 Читать далее...

Книжная полка  

Читайте и познавайте мир технологий!

Издательство «БХВ» продолжает радовать выпуском интересных и полезных, к тому же прекрасно

 Читать далее...

СУБД PostgreSQL  

СУБД Postgres Pro

Сертификация по новым требованиям ФСТЭК и роль администратора без доступа к данным

 Читать далее...

Критическая инфраструктура  

КИИ для оператора связи. Готовы ли компании к повышению уровня кибербезопасности?

Похоже, что провайдеры и операторы связи начали забывать о требованиях законодательства

 Читать далее...

Архитектура ПО  

Архитектурные метрики. Качество архитектуры и способность системы к эволюционированию

Обычно соответствие программного продукта требованиям мы проверяем через скоуп вполне себе понятных

 Читать далее...

Как хорошо вы это знаете  

Что вам известно о разработках компании ARinteg?

Компания ARinteg (ООО «АРинтег») – системный интегратор на российском рынке ИБ –

 Читать далее...

Графические редакторы  

Рисование абстрактных гор в стиле Paper Cut

Векторный графический редактор Inkscape – яркий представитель той прослойки open source, с

 Читать далее...

День сисадмина  

Учите матчасть! Или как стать системным администратором

Лето – время не только отпусков, но и хорошая возможность определиться с профессией

 Читать далее...

День сисадмина  

Живой айтишник – это всегда движение. Остановка смерти подобна

Наши авторы рассказывают о своем опыте и дают советы начинающим системным администраторам.

 Читать далее...

Виртуализация  

Рынок решений для виртуализации

По данным «Обзора российского рынка инфраструктурного ПО и перспектив его развития», сделанного

 Читать далее...

Книжная полка  

Как стать креативным и востребованным

Издательский дом «Питер» предлагает новинки компьютерной литературы, а также книги по бизнесу

 Читать далее...

Книжная полка  

От создания сайтов до разработки и реализации API

В издательстве «БХВ» недавно вышли книги, которые будут интересны системным администраторам, создателям

 Читать далее...

Разбор полетов  

Ошибок опыт трудный

Как часто мы легко повторяем, что не надо бояться совершать ошибки, мол,

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 6195
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 6903
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 4189
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 2989
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 3795
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 3805
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 6299
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 3152
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 3446
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 7263
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 10628
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 12352
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 13983
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 9110
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 7064
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 5375
Комментарии: 3
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 4604
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 3414
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 3145
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 3392
Комментарии: 0
Рецензия на книгу «MongoDB в действии»

 Читать далее...

02.12.2013г.
Просмотров: 3013
Комментарии: 0
Не думай о минутах свысока

 Читать далее...

Друзья сайта  

 Доступ к данным на основе хранимых процедур в веб-приложениях

Архив номеров / 2009 / Выпуск №1 (74) / Доступ к данным на основе хранимых процедур в веб-приложениях

Рубрика: Базы данных /  Инструменты

 АНТОН ГРИШАН

Доступ к данным
на основе хранимых процедур в веб-приложениях

Большинство приложений вынуждено работать с базами данных, общаясь с СУБД на языке SQL-запросов. Иными словами, одни программы на языках высокого уровня составляют другие программы на SQL. Это выглядит привычным – поэтому кажется логичным и удобным, но так ли это на самом деле?

Рассмотрим два способа взаимодействия приложения и базы данных. Первый и на данный момент более популярный способ – генерация SQL-запроса в теле скрипта (здесь и далее приводятся примеры для PHP5 + MySQL 5 с установленным расширением mysqli):

/* Выбрать все города в стране с заданным кодом, динамическая генерация запроса */

$countryCode = 'RU';

$result = mysqli_query ($db, "SELECT Cities.name FROM Countries, Cities WHERE Cities.countryId = Countries.id \

AND Countries.code = '".mysqli_real_escape_string($db, $countryCode)."'");

Второй способ – доступ к данным через хранимые процедуры. Хранимая процедура – объект базы данных, представляющий собой набор скомпилированных SQL-инструкций. Скрипт вызывает процедуру со списком параметров и обрабатывает полученный результат(ы).

Приведенный выше запрос (SELECT Cities.name FROM Countries, Cities WHERE Cities.countryId = Countries.id AND Countries.code = 'RU') можно сохранить в виде процедуры – getCities, с одним входным параметром – код страны (countryCode char(2)).

Приведу пример создания хранимой процедуры:

DELIMITER $$

CREATE PROCEDURE `getCities`(countryCode char(2))

BEGIN

SELECT Cities.name FROM Countries, Cities WHERE Cities.countryId = Countries.id AND Countries.code = countryCode;

END$$

DELIMITER ;

В момент вызова хранимой процедуры СУБД подставляет значение параметра в тело запроса и возвращает результат выборки данных.

Для вызова хранимой процедуры ‘getCities’ на стороне сервера БД необходимо выполнить следующую команду:

CALL `getCities`('RU');

Вызвать процедуру getCities из PHP-приложения можно следующим образом:

/* Выбрать все города в стране с заданным кодом, вызов хранимой процедуры */

$countryCode = 'RU';

mysqli_multi_query($db, "CALL getCities('".mysqli_real_escape_string($db, $countryCode)."');");

 Работа с БД через хранимые процедуры в настоящий момент встречается реже, чем генерация SQL-запроса в теле программы. На мой взгляд, это происходит по следующим причинам:

  • наиболее популярная связка для написания веб-приложений – PHP + MySQL, однако только в MySQL 5 стало возможно использовать хранимые процедуры;
  • в большинстве пособий по программированию приведены примеры работы с БД, основанные на генерации запроса в теле скрипта, и начинающим программистам сложно отойти от книжных примеров;
  • написание приложения с использованием хранимых процедур подразумевает умение программистов работать с хранимыми процедурами или наличие времени для изучения данной технологии (что не всегда допустимо в рамках конкретного проекта).

Преимущества использования хранимых процедур

  • Повышение скорости работы БД. Процедуры хранятся в скомпилированном виде, а значит, СУБД не тратит время на компиляцию запроса при каждом его исполнении. Приложению не требуется тратить время на генерацию запроса. Команда для вызова хранимой процедуры значительно короче, чем запрос, содержащийся в теле процедуры, поэтому требуется меньше времени и трафика на передачу команд на сервер БД.
  • Большая степень свободы. Хранимые процедуры поддерживают: входные и выходные параметры, локальные переменные, операторы условного ветвления, циклы, вызовы встроенных команд и других процедур, исполнение DDL-операторов. Во многом хранимые процедуры похожи на процедуры языков программирования высокого уровня.
  • Упрощение кода приложения. В приложении нет SQL-запросов, а значит, программисту не нужно писать код для их генерации. Для вызова хранимой процедуры необходимо знать только имя и список параметров (аналогично вызову обычных функций/методов в теле приложения). Такой подход сокращает размер кода и улучшает его читабельность, что положительно влияет на качество конечного продукта.
  • Защита приложения от изменений структуры БД. В процессе развития проекта может возникнуть необходимость в изменении структуры БД, например, добавить/удалить/переименовать таблицу или столбец. Если приложение генерирует SQL-запросы, то необходимо внести изменения во все фрагменты кода, отвечающие за генерацию запросов. Организация доступа через хранимые процедуры не требует внесения изменений в код приложения до тех пор, пока имя хранимой процедуры и список параметров (а также ожидаемый результат) остаются прежними.
  • Снижение количества ошибок и упрощение отладки. Чаще всего ошибки в работе приложения с БД возникают по следующим причинам:
    • приложение использует некорректные значения для генерации SQL-запроса;
    • SQL-выражение некорректно описывает ожидаемый результат (т.е. ошибка в запросе);
    • фрагмент кода приложения, отвечающий за генерацию SQL-запроса, содержит ошибку и не способен правильно построить нужный запрос.
    Если доступ к БД построен на основе хранимых процедур, то:
    • легко узнать, какие значения попадают в хранимую процедуру, достаточно распечатать список аргументов в момент вызова хранимой процедуры;
    • вам не нужно гадать по коду приложения, какой именно запрос должен получиться в том или ином месте программы, достаточно посмотреть на тело хранимой процедуры, что значительно упрощает процесс отладки;
    • этой ошибки возникнуть не может, так как приложение вообще не генерирует SQL-запросов, все запросы находятся в БД в виде хранимых процедур.
  • Безопасность. Использование хранимых процедур позволяет значительно снизить угрозу возникновения уязвимости типа SQL-injection. Кроме того, можно устанавливать права доступа к объектам базы данных для каждой хранимой процедуры, что также способствует повышению уровня безопасности приложения.

Трудности работы с хранимыми процедурами

Существует масса преимуществ, говорящих за использование хранимых процедур. Однако не стоит думать, что хранимые процедуры, безусловно, оптимальное решение для любого проекта. Чтобы сделать осмысленный выбор, давайте рассмотрим отрицательные стороны данного метода.

  • Проблема совместимости. Если необходимо обеспечить легкую переносимость приложения на максимальное количество СУБД, то, вероятно, стоит отдать предпочтение динамической генерации запросов, так как хранимые процедуры поддерживаются не всеми СУБД.
  • Сложность внедрения хранимых процедур в существующий проект. Внедрение хранимых процедур в приложение, использующее динамическую генерацию запросов, приведет к полной реорганизации кода работы с БД. Необходимость такой реорганизации не всегда просто объяснить заказчику.
  • Передача сложных типов данных. Иногда в качестве аргумента процедуре требуется передать не просто строку или число, а массив данных (или более сложный объект). В этом случае данные необходимо преобразовать в строку и в таком виде передавать хранимой процедуре, внутри которой происходит обратное преобразование. Построение запроса в теле приложения в этом случае проще.

Особенности работы с хранимыми процедурами

  • Хранимые процедуры служат только для доступа к данным (извлечение/обновление/удаление) и ни для чего больше. Использование процедур в иных целях (проверка данных или генерация HTML) является ошибкой.
  • Процедура может вернуть более одного результата. В коде вызова хранимой процедуры необходимо делать итерацию по всем возвращаемым результатам и обрабатывать каждый из них в отдельности.
  • Достаточно сложно передать в хранимую процедуру массив значений. Наиболее популярным решением является передача массива в хранимую процедуру в виде строки, содержащей элементы массива, разделенные специальным символом (вертикальная черта – «|»), далее параметр анализируется в теле хранимой процедуры.
  • Если в теле хранимой процедуры необходимо динамически генерировать SQL-запрос (старайтесь всеми возможными способами избегать написания подобных процедур), не забывайте экранировать кавычки и спецсимволы во всех переданных в процедуру параметрах, участвующих в построении запроса, иначе процедура будет содержать потенциальную уязвимость типа SQL-injection.

Пример класса для работы с БД через хранимые процедуры

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

Чтобы стало понятно, о чем идет речь, начнем с примера:

<?php

include 'DBaccess.php';

// Создаем объект доступа к БД

$db = new DBaccess('main_db' , 'localhost', 3306, 'login', 'password', 'utf8');

// Вызываем хранимую процедуру GetCities и передаем в качестве параметра RU

$result = $db->getCities('RU');

// Обрабатываем полученный результат (массив данных)

var_dump($result);

?>

В приведенном выше примере для вызова хранимой процедуры getCities с параметром RU (код страны) используется объект класса DBaccess. С точки зрения приложения такой вызов процедуры выглядит как вызов обыкновенного метода, что позволяет отказаться от логики написания программы, которая в свою очередь составляет другую программу на SQL. Приведу далее код класса DBaccess (для работы класса требуется PHP5 c mysqli расширением, MySQL 5):

<?php

class DBConnection {

    private $db = null;

    public function __construct($dbName, $host, $port, $login, $password, $charset) {

        $this->db = new mysqli($host, $login, $password, $dbName, $port);

        $this->db->set_charset($charset);

    }

    public function __call($storeProcedureName, $params) {

        $quotedParams = array();

        foreach($params as $param)    {

           array_push($quotedParams, $param === null ? 'NULL' : '\''.$this->db->escape_string($param).'\'');

           }

        $sql = 'CALL `'.$storeProcedureName.'`('.implode(',', $quotedParams).');';

        $this->db->multi_query($sql);

        $results = array();

           do {

           if ($result = $this->db->store_result()) {

               $rows = array();

               while ($row = $result->fetch_assoc()) {

                 array_push($rows, $row);

               }

               $result->close();

               array_push($results, $rows);

                 }

        } while ($this->db->more_results() && $this->db->next_result());

    return($results);

    }

}

?>

Внутри класса DBaccess не объявлен метод getCities, однако мы можем вызывать хранимую процедуру как «$db->getCities(‘RU’);».

Это достигается за счет использования магического метода __call() (данная возможность появилась в PHP5), который работает следующим образом: при вызове метода, не объявленного в классе, имя вызываемого метода и список аргументов передается в __call($metodName, $params) для обработки (если метод объявлен).

Таким образом, мы можем вызывать любую хранимую процедуру на сервере, например «$db->loadUser($email, $password);».

В приведенном выше коде класса DBaccess отсутствуют необходимые проверки на ошибки, возможность работы с несколькими БД, проверка стабильности соединения с сервером, автоматическое переподключение и множество других полезных функций. Это сделано намеренно, дабы проиллюстрировать основную идею с использованием минимального количества кода.

Скачать полнофункциональную версию класса для изучения и использования можно здесь: http://www.vipidn.com/dbaccess.zip.

  1. Полнофункциональная версия класса «DBaccess» – http://www.vipidn.com/dbaccess.zip.
  2. Описание магического метода __call() – http://ru2.php.net/manual/ru/language.oop5.overloading.php.
  3. Описание расширения mysqli – http://ru2.php.net/manual/ru/ref.mysqli.php.
  4. Информация к размышлению – «Good and Evil in the Garden of Stored Procedures» (Jeremy D. Miller) – http://codebetter.com/blogs/jeremy.miller/archive/2005/07/05/130093.aspx.

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru