В этой статье я хочу рассказать о возможностях, которые предоставляет PHP фреймворк CodeIgniter для одновременной работы с несколькими базами данных. Кроме того, я провел небольшое исследование производительности.
Прежде всего, поясню общий принцип. В работе с несколькими базами данных нет ничего необычного и исключительного. Если вы пишите обычный PHP скрипт (без использования фреймворков и библиотек), то для работы с двумя БД нужно просто создать два соединения.
Т.е. вызвать два раза функцию mysql_connect
(если, конечно, используете MySQL).
Каждый вызов этой функции вернет указатель на соединение, используя который вы сможете отправлять запросы базам данных.
Это была теория, а на практике гораздо удобнее использовать встроенные библиотеки фреймворков для работы с базами данных. Принцип работы при этом, конечно, не меняется, но работать с ними значительно удобнее.
Я расскажу о подключении и использовании нескольких баз данных в CodeIgniter. Но, естественно, это не единственный фреймворк, который имеет встроенные библиотеки для работы с несколькими БД. Например, недавно я читал статью «Работа с несколькими базами данных при помощи ORM в Zend Framework».
В качестве примера рассмотрим подключение к двум БД.
1) Указываем параметры подключения в конфигурационном файле.
Открываем файл application/config/database.php
и ищем блок с настройками подключения к базе.
$db['default']['hostname'] = "localhost"; $db['default']['username'] = "db_user"; $db['default']['password'] = "db_pass"; $db['default']['database'] = "db_name"; $db['default']['dbdriver'] = "mysql"; $db['default']['dbprefix'] = ""; $db['default']['pconnect'] = FALSE; $db['default']['db_debug'] = TRUE; $db['default']['cache_on'] = FALSE; $db['default']['cachedir'] = ""; $db['default']['char_set'] = "utf8"; $db['default']['dbcollat'] = "utf8_general_ci";
Как видите, все параметры подключения находятся в двумерном массиве. В первом индексе указывается название группы параметров данного подключения (в данном случае default
).
Изменяя это название, вы можете определить сколько угодно групп парамеров. Т.е. для работы со второй БД копируем весь этот блок, изменяем первый индекс и указываем параметры подключения ко второй базе.
Например,
$db['db2']['hostname'] = "localhost"; $db['db2']['username'] = "db2_user_name"; $db['db2']['password'] = "db2_pass"; $db['db2']['database'] = "db2_name"; $db['db2']['dbdriver'] = "mysql"; $db['db2']['dbprefix'] = ""; $db['db2']['pconnect'] = FALSE; $db['db2']['db_debug'] = TRUE; $db['db2']['cache_on'] = FALSE; $db['db2']['cachedir'] = ""; $db['db2']['char_set'] = "utf8"; $db['db2']['dbcollat'] = "utf8_general_ci";
2) Подключаемся к нужной базе.
Просто два раза используем стандартный способ подключения к БД в CodeIgniter.
$DB = $this->load->database('default', TRUE, TRUE); $DB2 = $this->load->database('db2', TRUE, TRUE);
При этом в первом параметре указываем название группы параметров нужного подключения. В данном случае это 'default' и 'db2'.
Второй параметр в данном случае обязательно должен быть равен TRUE. Он указывает должен ли метод database вернуть ID соединения. По-умолчанию этот параметр равен FALSE, т.к. в большинстве случаев работать нужно только с одной БД. Но если баз две или больше, то с помощью этих ID можно указать какой базе отправляется запрос.
Третий параметр не обязательный. С его помощью мы указываем активировать или нет класс Active Record.
3) Отправляем запросы.
Как я и говорил, если баз несколько, то для работы с ними нужно использовать ID соответствующих соединений.
Т.е. если в случае одной базы запрос отправляется через объект $this
.
$this->db->query('…');
То при работе с двумя базами отправка запроса будет выглядеть так:
$DB->query('select * from table_name'); $DB2->query('select * from db2_table_name ');
Как видите, код даже немного сокращается.
Потребление ресурсов.
Думаю, не сложно догадаться, что подключение ко второй базе займет какое-то время. Поэтому я решил провести небольшой тест.
Для этого я взял стандартный дистрибутив CodeIgniter и в конструктор контроллера добавил операцию подключения к базе.
После этого включил профайлинг в xDebug и определил общее время работы скрипта и время, которое ушло на создание соединений. Результат получился следующий.
Подключение к одной БД.
Вызов php::mysql_connect
происходит в методе CI_DB_mysql_driver->db_connect
и занимает 4.32 мс.
При этом общее время работы скрипта 131 мс.
Подключение к двум БД.
php::mysql_connect
вызывается два раза (также из CI_DB_mysql_driver->db_connect
) и занимает 5.99 мс.
Общее время — 132 мс.
Отсюда можно сделать простой вывод. MySQL очень быстро создает соединения и поэтому работа одновременно с несколькими базами на производительность практически не влияет.
Кстати, даже самый простой запрос (к одной маленькой таблице без условий) занимает около 30 мс.
Пожалуй, единственный недостаток в том, что при использовании двух БД не работает встроенный в CodeIgniter профайлинг.
Правда, недавно видел инструкцию по исправлению этого недостатка, но сам не пробовал.
Как видите, в использовании нескольких БД нет ничего сложного. Если возникли вопросы, задавайте, попробую ответить 😉