IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  XML | Open source  >

Совет: Создание переносимых представлений баз данных с помощью пакета MDB2_Schema из репозитория PEAR

Перенос объектов баз данных между различными СУБД с помощью PHP

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Обсудить


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: средний

Викрам Васвани (Vikram Vaswani), основатель компании, Melonfire

21.11.2008

Перенос внутренней базы данных приложения на другую СУБД является непростой задачей, которая зачастую требует ручного пересоздания таблиц базы данных, а также переноса записей с использованием функций SQL и типов данных, поддерживаемых новой СУБД. Этот процесс можно облегчить благодаря пакету MDB2_Schema из PEAR. Пакет позволяет создать XML-представление базы данных, не зависящее от конкретной СУБД, и предоставляет средства для импорта этого представления в любую из поддерживаемых СУБД.

Введение

Если у вас есть опыт работы с различными базами данных на различных платформах, то, скорее всего, вам знакомы трудности, с которыми сопряжен перенос приложений с одной реляционной СУБД (РСУБД) на другую. Разные РСУБД не только поддерживают разные подмножества стандартов SQL-92 и SQL-99, но и часто используют собственные расширения и дополнения SQL.

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

MDB2_Schema – PHP-пакет из репозитория PEAR (PHP Extension and Application Repository) – призван частично избавить разработчиков от рутинной работы по переносу приложения между РСУБД. Пакет предоставляет специальный API, позволяющий сохранить сущности и записи базы данных в нейтральном XML-формате, а затем на основе этого XML-представления воссоздать базу данных и записи в новой РСУБД. MDB2_Schema поддерживает большинство популярных РСУБД и поэтому предоставляет простой и эффективный способ быстрого переноса данных в новую систему.



В начало


Установка

Пакет MDB2_Schema поддерживается Эльги Пормаром (Helgi Pormar), Игорем Фегали (Igor Feghali) и Давидом Кольером (David Coallier). Он выпущен под лицензией BSD и требует для своей работы PHP версии 4.2.0 или выше. Проще всего пакет устанавливается с помощью автоматического инсталлятора PEAR, который входит в стандартную поставку PHP. Для установки выполните следующую команду из командной строки:

shell> pear install MDB2_Schema

Инсталлятор соединится с сервером пакетов PEAR, загрузит пакет и установит его в подходящее место на диске. В данной статье используется MDB2_Schema V. 0.7.2.

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

MDB2_Schema зависит от двух других пакетов из PEAR: XML_Parser и MDB2, необходимого для создания абстрактного представления базы данных. MDB2, в свою очередь, требует наличия драйверов и расширений PHP, специфичных для конкретных СУБД. К моменту написания данной статьи существовали MDB2-драйверы для следующих СУБД: MySQL, SQLite, PostgreSQL, Firebird, Interbase, MS-SQL и Oracle. В примерах мы будем использовать драйверы для MySQL и PostgreSQL. Все перечисленные выше пакеты могут быть установлены стандартным инсталлятором PEAR или вручную. В последнем случае пакеты можно найти по ссылкам, приведенным в разделе Ресурсы.

В данной статье мы продемонстрируем использование пакета MDB2_Schema на примере портирования базы данных world из поставки MySQL на PostgreSQL. Сама база данных содержит различные связанные таблицы, заполненные данными о городах и странах. Для корректной работы примера необходимо установить MySQL и PostgreSQL, а также базу данных world. Инструкции по установке можно найти в разделе Ресурсы.



В начало


Работа через графический интерфейс

Начать работать с MDB2_Schema проще всего с помощью скрипта example.php, включенного в поставку пакета. Этот скрипт предоставляет Web-интерфейс для создания, импортирования и изменения XML-описания базы данных под конкретную СУБД. Для установки скрипта просто скопируйте его в любой каталог в корневой директории вашего Web-сервера.

Интерфейс формы показан на рисунке 1.


Рисунок 1. Web-интерфейс для экспортирования и импортирования XML-представления базы данных
Web form to dump or create a database representation

Для экспорта описания базы данных world из поставки MySQL в XML введите необходимые параметры доступа к серверу MySQL в поля формы и нажмите ОК. Как правило, для опции Dump должно быть выбрано значение All. Кроме того, имеет смысл включить режим отладки (опция Debug).

Заполненная форма показана на рисунке 2.


Рисунок 2. Заполненная Web-форма
Filled-in Web form

Далее скрипт установит соединение с базой данных MySQL, используя введенные параметры доступа, сгенерирует описания сущностей и данных в виде XML и сохранит их в файле на диске. Фрагмент такого файла приведен в листинге 1.


Листинг 1. Пример описания базы данных MySQL в виде XML
        
<?xml version="1.0" encoding="ISO-8859-1" ?>
<database>

 <name>world</name>
 <create>true</create>
 <overwrite>false</overwrite>

 <table>

  <name>city</name>

  <declaration>

   <field>
    <name>ID</name>
    <type>integer</type>
    <length>4</length>
    <notnull>true</notnull>
    <default>0</default>
    <autoincrement>1</autoincrement>
   </field>

   <field>
    <name>Name</name>
    <type>text</type>
    <length>35</length>
    <notnull>true</notnull>
    <fixed>true</fixed>
    <default></default>
   </field>

    ...

   <index>
    <name>idx_ccode</name>
    <field>
     <name>CountryCode</name>
     <sorting>ascending</sorting>
    </field>
   </index>

  ...

  </declaration>

  <initialization>

   <insert>

    <field>
     <name>ID</name>
     <value>1</value>
    </field>

    <field>
     <name>Name</name>
     <value>Kabul</value>
    </field>

    <field>
     <name>CountryCode</name>
     <value>AFG</value>
    </field>

    <field>
     <name>District</name>
     <value>Kabol</value>
    </field>

    <field>
     <name>Population</name>
     <value>1780000</value>
    </field>

   </insert>

   ...
   
  </initialization>
  
 </table>

 <table>

 ...

 </table>

</database>
        

Здесь уместно будет дать краткое описание формата, используемого MDB2_Schema для создания XML-представлений. Каждая таблица в базе данных описывается элементом <table>, имеющим два основных дочерних элемента:

  • <declaration>, содержащий описания полей и индексов.
  • <initialization>, содержащий данные таблицы. Каждая запись в таблице представлена элементом <insert>, находящимся внутри элемента <initialization>.

После того как описание базы данных в виде XML сгенерировано, его можно импортировать в другую РСУБД с помощью того же Web-интерфейса скрипта example.php. Для этого надо ввести параметры доступа для целевой РСУБД, путь к файлу, содержащему XML-описание исходной базы данных, включить опцию создания базы данных (Create) и режим отладки. После этого можно запустить импортирование. Пакет MDB2_Schema прочитает и проанализирует XML-описание, создаст таблицы со всеми необходимыми полями и заполнит их данными. Результат создания базы данных PostgreSQL из ранее сгенерированного XML-описания показан на рисунке 3.

Результат создания базы данных PostgreSQL из ранее сгенерированного XML-описания показан на рисунке 3.


Рисунок 3. Отладочный вывод скрипта при создании базы данных PostgreSQL из XML-описания
Debug output after creating a PostgreSQL database from an XML representation


В начало


Работа через MDB2_Schema API

Несмотря на удобство работы через визуальный интерфейс, иногда необходимо использовать пакет MDB2_Schema напрямую из приложения на PHP. Программное генерирование XML-описаний и создание баз данных на основе XML делаются несложно. Пример кода на PHP, генерирующего XML-представление базы данных с ее содержимым с помощью MDB2_Schema, приведен в листинге 2.


Листинг 2. Скрипт на PHP, генерирующий описание базы данных в виде XML
                    
<?php
set_time_limit(0); 
// включение класса
include_once 'MDB2/Schema.php';

// Инициализация соединения MDB с базой данных
// Конфигурирование файлового вывода
$options['output_mode'] = 'file';
$options['force_defaults'] = true;
$schema = MDB2_Schema::factory(MDB2::factory('mysql://root@localhost/world'), 
$options);

// получение описания объектов базы данных 
$data = $schema->getDefinitionFromDatabase();
if ($data instanceof MDB2_Error) {
    die ($data->getMessage() . ': ' . $data->getUserInfo());
} 

            
// запись структуры и содержимого базы данных в файл 
$options['output'] = '/tmp/all.xml';
$ret = $schema->dumpDatabase($data, $options, MDB2_SCHEMA_DUMP_ALL);
if ($ret instanceof MDB2_Error) {
    die ($ret->getMessage() . ': ' . $ret->getUserInfo());
} else {
    echo 'Database structure and contents successfully dumped to /tmp/all.xml. 
    <br />';
}


// запись только структуры
$options['output'] = '/tmp/structure.xml';
$ret = $schema->dumpDatabase($data, $options, MDB2_SCHEMA_DUMP_STRUCTURE);
if ($ret instanceof MDB2_Error) {
    die ($ret->getMessage() . ': ' . $ret->getUserInfo());
} else {
    echo 'Database structure successfully dumped to /tmp/structure.xml. 
    <br />';
}

// запись только данных
$options['output'] = '/tmp/content.xml';
$ret = $schema->dumpDatabase($data, $options, MDB2_SCHEMA_DUMP_CONTENT);
if ($ret instanceof MDB2_Error) {
    die ($ret->getMessage() . ': ' . $ret->getUserInfo());
} else {
    echo 'Database contents successfully dumped to /tmp/content.xml. <br />';
}
?>
        

В листинге 2 сначала включается необходимое определение класса из MDB2_Schema, а затем происходит инициализация слоя абстракции MDB2 с помощью вызова метода factory(). В этот метод передается строка DSN, содержащая параметры доступа к экспортируемой базе данных. Полученный экземпляр MDB2 далее используется для инициализации экземпляра MDB2_Schema, который сохраняется в переменной $schema.

После создания объекта MDB2_Schema остается выполнить два простых шага, чтобы сгенерировать описание данных в виде XML. Сначала вызывается метод getDefinitionFromDatabase(), возвращающий определения объектов базы данных, а затем – dumpDatabase(), выполняющий запись сущностей и данных в XML-файл. Имя и путь к выходному файлу задаются по ключу output в ассоциативном массиве $options, который передается в метод dumpDatabase() в качестве второго аргумента. Третьим аргументом метода является константа, определяющая режим экспортирования: только сущности (MDB2_SCHEMA_DUMP_STRUCTURE), только данные (MDB2_SCHEMA_DUMP_CONTENT) или и то, и другое (MDB2_SCHEMA_DUMP_ALL).

Необходимо сказать несколько слов о массиве $options, передаваемом в метод factory() из MDB2_Schema. В этом массиве устанавливаются различные опции, определяющие режим экспортирования базы данных и выходное представление. Например, ключ output_mode определяет, надо ли записывать значение, возвращаемое методом dumpDatabase(), в файл, или надо передать его в PHP-функцию, а ключ output задает путь к файлу или имя функции. В листинге 2 ключ output_mode имеет значение file, поэтому создаются файлы all.xml, structure.xml и content.xml, но с таким же успехом можно определить некую функцию и передать ей результат выполнения dumpDatabase() для дальнейшей обработки.

Создание базы данных из XML-описания (даже в другой РСУБД) делается даже проще, чем генерация описания. В листинге 3 показан процесс чтения сгенерированного описания и конвертирования его в базу данных PostgreSQL.


Листинг 3. Скрипт на PHP, выполняющий импорт XML-описания базы данных
                    
<?php
set_time_limit(0);
// включение класса
include 'PEAR/MDB2/Schema.php';

// инициализация соединения MDB с базой данных
$schema = MDB2_Schema::factory(
    MDB2::factory("pgsql://postgres:postgres@localhost/world"));

// разбор файла описания
$data = $schema->parseDatabaseDefinitionFile('/tmp/structure.xml');
if ($data instanceof MDB2_Schema_Error) {
    die ($data->getMessage() . ': ' . $data->getUserInfo());
} else {
    echo 'Database definition parsed. <br />';
}

// создание базы данных
$ret = $schema->createDatabase($data);
if ($ret instanceof MDB2_Error) {
    die ($ret->getMessage() . ': ' . $ret->getUserInfo());
} else {
    echo 'Database schema successfully imported. <br />';
}
?>
        

Вначале происходит инициализация экземпляра класса MDB2_Schema, которому передается объект MDB2, описывающий целевую базу данных (в данном случае PostgreSQL). После этого метод parseDatabaseDefinitionFile() читает XML-описание и сохраняет его в переменной $data, а затем метод createDatebase() создает все объекты базы данных и наполняет их данными.

Выполнение скрипта может занимать продолжительное время, особенно в случае больших или сложных баз данных, поэтому в начале листинга 3 происходит вызов set_time_limit(0). Как только скрипт закончит работу, можно открыть ваш любимый клиент для PostgreSQL и убедиться, что данные были перенесены корректно.

postgres-# \c world
Password for user "postgres":
You are now connected to database "world".
world-# \dt
              List of relations
 Schema |      Name       | Type  |  Owner
--------+-----------------+-------+----------
 public | city            | table | postgres
 public | country         | table | postgres
 public | countrylanguage | table | postgres
(3 rows)

world=# SELECT * FROM city;
 id | name      | countrycode |       district       | population
----+-----------+-------------+----------------------+------------
  1 | Kabul     | AFG         | Kabol                |    1780000
  2 | Qandahar  | AFG         | Qandahar             |     237500
...
        



В начало


Замечания

Несмотря на то, что MDB2_Schema работает достаточно успешно с большинством популярных баз данных, включая MySQL, PostgreSQL и SQLite, необходимо помнить, что это все-таки автоматическое средство, и, следовательно, оно подвержено ошибкам. Например, ошибки могут возникать при переносе данных полей типа TIMESTAMP или DATE, для которых не определено значение по умолчанию. В этом случае при вызове метода parseDatabaseDefinitionFile() возможно появление ошибок при обработке элементов <default>. Единственный способ решения этой проблемы – это ручное изменение XML-описания с учетом особенностей синтаксиса целевой РСУБД.

Как видно из приведенных листингов, пакет MDB2_Schema позволяет легко и безопасно перемещать данные между различными РСУБД. Несмотря на то, что это неидеальное решение, и в некоторых случаях может потребоваться ручная работа, пакет является эффективной альтернативой ручному переносу таблиц и написанию SQL-кода для экспорта/импорта записей из одной базы данных в другую. Попробуйте его использовать в следующий раз, когда вам придется переносить базу данных, и посмотрите, что получится!



Ресурсы

Научиться

Получить продукты и технологии
  • Скачайте ознакомительные версии программного обеспечения IBM: используйте в вашем следующем проекте ознакомительные версии ПО, которые можно скачать прямо с сайта IBM developerWorks (EN).

  • Пакет MDB2_Schema: экспорт баз данных в виде файлов XML, не зависящих от РСУБД. Данное представление можно использовать для создания, изменения или удаления сущностей, а также вставки записей в базы данных (EN).

  • MDB2: скачайте пакет, представляющий собой сочетание абстрактных слоев PEAR DB и Metabase. Пакет предоставляет унифицированный API для всех поддерживаемых РСУБД (EN).

  • Драйвер MySQL: скачайте драйвер MySQL для пакета PEAR MDB2 (EN).

  • Драйвер PostgreSQL: скачайте драйвер PostgreSQL для пакета PEAR MDB2 (EN).

  • Демонстрационная база данных world для MySQL: скачайте инструкции по загрузке и установите базу данных, содержащую данные о странах, городах и языках (EN).

  • IBM DB2® Enterprise 9: скачайте ознакомительную версию DB2 9 или DB2 Express-C 9 – бесплатную версию сервера DB2 Express 9. (EN)

Обсудить


Об авторе

Викрам Васвани (Vikram Vaswani) – основатель и президент консалтинговой фирмы Melonfire, специализирующейся на технологиях и инструментах с открытым исходным кодом. Также является автором книг Решения по программированию на PHP and Как сделать все что угодно с помощью PHP и MySQL .




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



 


 


 


Поделиться этой статьей:

забобрить забобрить memori сохранить в memori




В начало


IBM, DB2, Rational, and pureXML are trademarks of IBM Corporation in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of others. Другая компания, продукт или название услуги могут быть торговыми марками или знаками обслуживания, принадлежащими иным физическим или юридическим лицам.

IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.
    IBM в России Конфиденциальность Контакты