|
|
|||||||||||||||||||||||||||||
|
Хранение XML данных в Oracle (Storing XML Data). Часть 2Источник: cyberguru
Репозиторий Oracle XML DB может функционировать как файловая система в базе данных Oracle. Любые данные репозитория Oracle XML DB отображаются на ресурсы, которые имеют путевое (pathname - составное) имя (или URL) и сохранены в BLOB или в объекте Oracle XMLType. Репозиторий Oracle XML DB предоставляет возможность исчерпывающего управления этими ресурсами. Вы уже изучили, как загружать XML с помощью протокола интерфейсов репозитория XML DB. В этой секции мы обсудим другие темы: возможность версии контролировать документы и созданные связи, управление ресурсами. Мы также обсудим основные PL/SQL пакеты, обеспечивающие эту функциональность:
Управление ресурсамиВ Oracle Database 10g вы можете использовать модуль DBMS_XDB для создания и удаления ресурсов, папок-фолдеров и связей ресурсов. Вы также можете использовать этот модуль для блокирования/разблокирования ресурсов во время чтения или обновления XML данных: DECLARE В этом примере все записи о клиентах считываются из таблицы customer и ресурсные XML документы, созданные в директории /public репозитория XML DB, используют функцию DBMS_XDB.createResource(). Дополнительно в репозитории XML DB можно создать папку /public/important_customer, как показано ниже: DECLARE Далее, можно создать некий ресурс README.txt для отображения содержимого этой папки: DECLARE END; С того момента как создан в директории /public список клиентов, можно создать набор связей, вместо создания второй копии данных: EXEC DBMS_XDB.link('/public/customer1.xml', Если вы хотите удалить ресурс, можно использовать функцию DBMS_XDB.DeleteResource(): DBMS_XDB.DeleteResource Вы можете удалить ресурс с ресурсными на него связями. Разумеется, после перемещения оригинального ресурса все связанные ресурсы более с ним не связаны. Каждый из них вместо этого будет содержать копию данных. Контроль версийПакеты DBMS_XDB_VERSION и DBMS_XDBPL/SQL обеспечивают функцию контроля версий Oracle XML DB, которая дает способ создания и управления различными версиями Version-Control Resource (VCR) в Oracle XML DB. Когда XML DB ресурс встроен в VCR, некий флажок маркирует его как VCR, и текущий ресурс становится исходной версией. Эта версия физически не сохраняется в базе данных. Другими словами, нет дополнительной копии этого ресурса, сохраненной, когда он был сделан версией. Следующие версии сохраняются в тех же таблицах. Коль скоро версия ресурса становится системно-сгенерированной, она лишается составного (pathname) имени. Но вы все еще можете получить доступ к ресурсу через функцию, предоставленную в пакете DBMS_XDB_VERSION. Когда проверяется ресурс, ни какой другой пользователь не может его обновить. Когда ресурс обновляется впервые, создается его копия. Вы можете сделать несколько изменений ресурса без обратного эффекта. Вы всегда будете получать последние версии ресурса, даже если у вас есть различные пользователи. Когда ресурс перезапускается, оригинальная версия, которая заканчивает работу, помещается на место обычного постоянного хранения. Характеристики версий для VCR содержатся в репозитории XML DB. В этом релизе версионность работает только для небазируемых на схемах (non-schema-based) ресурсах. Таким образом, XMLType, базируемые на раздельных XML-документах, и XMLType CLOB, которые обладают присоединенными схемами, официально не поддерживают использование VCR. Тем не менее, мы обнаружили, что до тех пор, пока вы не создадите уникальные метаданные, ассоциированные с конкретной версией, например индексы, VCR будут работать. ЗАМЕЧАНИЕ Вы не можете переключиться с VCR на не-VCR. Oracle XML DB предоставляет функции для отслеживания всех изменений в VCR Oracle XML DB. Следующий код демонстрирует эти функции: DECLARE Вы можете получить идентификатор ресурса VCR: SET AUTOPRINT ON Для обновления VCR вам понадобится проверить ресурс, выполнить обновление файлов и затем вернуть их в репозиторий XML DB: DECLARE Заметим, что ресурсы не обновятся до тех пор, пока проверяется новый файл. Если вы хотите завершить проверку, вы можете "распроверить" ресурс: DECLARE Сохранение XML документов в реляционных таблицахРеляционные таблицы обычно проектируются, не принимая во внимание хранение XML. Однако во многих случаях эти таблицы могут быть использованы для сохранения расщепленных (shredded) XML-документов и порождения полезных XML-отображений с помощью создания XMLType-представлений, использующих XML-опции Oracle Database 10 g , или генерирующих XML с использованием Oracle XDK. Хранение XML-данных в реляционных таблицах удобно, если вашему приложению нужно избавиться от таких ограничений XMLType-хранения, как ограничение на эволюцию XML-схемы или реплицирование данных. Реляционное хранение также широко используется приложениями, которые нуждаются в низко уровневом доступе к данным из XML- документов, пока не требуется защита полной иерархической структуры XML. Oracle Database 10 g предоставляет обширную поддержку для загрузки, экспортирования и обработки XML-данных в реляционных таблицах. Для загрузки XML-данных вы можете использовать утилиту XML SQL Utility (XSU), которая обеспечивает оба: Java и PL/SQL программных интерфейса, а также утилиты командной строки. Утилита TransX Utility (Translation XML), построенная на XSU, упрощает дальнейшее преобразование набора символов (character set) перед загрузкой данных, а XSQL Servlet предоставляет HTTP-интерфейсы. Если для вашего приложения недостаточно функциональности, предлагаемой данными утилитами, вы можете использовать их программный API в объединении с другими библиотеками XDK для построения собственного решения. Утилита XML SQL UtilityXSU предлагает API, базируемые на Java, утилиты командной строки и PL/SQ-пакеты, которые поддерживают загрузку XML-данных в реляционные таблицы, включая таблицы, содержащие столбцы XMLType. Мы в следующих разделах рассмотрим, как можно использовать эту функциональность. Каноническое отображениеПервое, что вам следует сделать перед использованием XSU, это понять, будет ли использоваться каноническое отображение XSU для отображения XML в реляционные таблицы и визуализировать результаты SQL-запросов в XML. В данном каноническом отображении элемент <ROWSET> является корневым элементом XML-документа, а его дочерние элементы <ROW> отображаются в столбцы данных в таблицах. Имена дочерних элементов для каждого элемента <ROW> отображаются в имена табличных столбцов или имена объектов, из которых возвращаются результаты. Атрибуты num элементов <ROW> являются номерами, по которым доступна заказанная информация. Далее следует пример отображения XML-схемы этой структуры метаданных: ><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" XSU предоставляет способы изменения имен элементов <ROWSET> и <ROW>. Например, таблица CUSTOMER_TBL определятся так: CREATE TABLE CUSTOMER_TBL ( XML-документ отображается в таблицу каноническим отображением, как показано далее: <ROWSET> ЗАМЕЧАНИЕ По умолчанию все имена таблиц, столбцов и объектов пишутся на верхнем регистре. Таким образом, если вы хотите правильно вставить XML-документ со смешанными регистрами, то вам необходимо специфицировать опции ignoreCase во время использования XSU. Чтобы надлежащим образом запустить XSU утилиту из командной строки, вам нужно установить следующие Java-пакеты в ваш Java CLASSPATH:
ЗАМЕЧАНИЕ Вам может понадобиться вставить пакет orai18n.jar в ваш Java CLASSPATH, когда оперируете XML с различными наборами символов. Иначе вы можете получить oracle.xml.sql.OracleXMLSQLException: "java.sql.SQLException: Non supported character set…" XSU зависит от синтаксического анализатора XML, чтобы построить DOM, а также зависит от JDBC-драйвера для подключения к базе данных Oracle и извлечения мета данных. После того как Java CLASSPATH установлен должным образом, вы можете запустить утилиту командной строки XSU с помощью java OracleXML, которая имеет две опции: getXML для запросов к базе данных и putXML для добавления данных в базу данных. ЗАМЕЧАНИЕ Операции обновления и удаления не включены в утилиту командной строки XSU, но они поддерживаются Java и API PL/SQL. Например, для добавления XML-данных в contact01.xml можно задействовать следующую команду: java OracleXML putXML -conn "jdbc:oracle:thin:@localhost:1521:orclX" -user "demo/demo" -fileName "customer1_xsu.xml" "customr_tbl" Данные добавлены в таблицу CUSTOMER_TBL в схеме demo. Для запроса содержимого таблицы и возвращения результатов в XML можно задействовать следующую XSU команду: java OracleXML getXML -conn "jdbc:oracle:thin:@localhost:1521:orclX" -user "demo/demo" "SELECT * FROM customer_tbl" Возвращается следующий XML-документ: <?xml version = '1.0'?> В этом случае данные XML-документа успешно загружены в база данных. Однако добавляемые XML-документы не всегда находятся в каноническом формате. Как следует обращаться с такими документами? Обычный прием - это использование XSLT-таблицы стилей для трансформирования XML-документа в канонический формат. С другой стороны, вы можете создать объектные представления в базе данных, отображающих входной XML-формат. Объектные представленияЕсли XML-документ не находится в каноническом формате, вы можете создать объектные представления или XMLType-представления, чтобы позволить XSU отображать XML-документы в таблицы базы данных. Как показано далее, контактная информация сохраняется в следующем contact.xml XML-документе: <Contact_List> Схема базы данных определяется, как показано далее: CREATE TYPE address_typ AS OBJECT( Используя каноническое отображение, XML-документ не может напрямую отобразится в столбцах таблицы, как документ, содержащий несколько уровней. Таким образом, для того, чтобы вставить XML-документ, нужно создать следующее объектное представление: CREATE TYPE contactinfo_type AS OBJECT( Далее вы можете запустить следующую команду для загрузки XML-файла в CUSTOMER_VIEW: java OracleXML putXML -conn "jdbc:oracle:thin:@localhost:1521:orclX" В данном примере contact_view используется база данных Oracle для отображения XML- данных в базовые таблицы. Однако, во многих случаях эти типы представлений не будут обновляемыми, когда они содержат многоуровневые таблицы соединения или объекты типа наследования. Далее для обращения с совокупностью данных в этих таблицах и объектов вы должны создать INSTEAD-OF-TRIGGERS для представлений. Деление XML-документов на фрагментыКогда сохраняете XML-документ, вы иногда не хотите отображать каждый XML-элемент в столбцах реляционной таблицы. Вместо этого, вы можете захотеть сохранить некоторые XML-фрагменты в XML CLOB или XMLType. Следующий пример иллюстрирует подход в использование XSLT для создания таких XML-фрагментов и вставки этих же XML-фрагментов в один столбец XMLType-таблицы, используя XSU. В примере добавляемый XML-документ представлен как: <Contact_List> Элемент <Description> содержит смешанный контент, который мы не хотим отображать (to map) в несколько столбцов таблицы. Таблицы contact_tbl определяется, как показано далее: CREATE TABLE contact_tbl( Для отображения элемента <Description> в столбец description, используя XSU, вам нужно задействовать следующую setCDATA.xsl таблицу стилей XSL: <xsl:stylesheet version="1.0" Это XSLT-преобразование трансформирует входящий XML-документ и включит все дочерние элементы <Description> в одну секций CDATA, так что каждая секция CDATA может быть сохранена с помощью XSU в столбце description. Вы можете модифицировать таблицу стилей XSL для вашего приложения, специфицируя различные match-атрибуты по следующему шаблону: <xsl:template match="Description">… </ xsl:template> XPath в match-атрибуте специфицирует корневой элемент для сохранения XML-фрагмента. ЗАМЕЧАНИЕ Так как XSLT требует, чтобы DOM был встроен в память, вам может потребоваться перед преобразованием разбиение большого документа. Утилита TransX UtilityКогда происходит заполнение базы данных Oracle многоязычными данными или преобразование данных, или когда происходит кодирование, требуется проверка достоверности каждого XML-файла. Традиционный путь решения - это переключение установки NLS_LANG, как будто вы переключаетесь на загрузку файлов с различными кодовыми таблицами. Параметр NLS_LANG определяет таблицу символов для загруженного в базу данных файла. Этот подход подвержен ошибкам, потому что кодовая информация поддерживается отдельно от самих данных. Постоянно переустанавливать NLS_LANG - очень скучная работа. При использовании TransX Utility, предусмотренной XDK, кодовая информация содержится вместе с данными в XML-документе в предопределенном формате. Таким образом, многоязыковые данные могут быть перемешены без переключения настройки NLS_LANG. TransX Utility поддерживает корректный набор символов на всем протяжении процесса транслирования данных и успешно загружает его в базу данных. Мы не будем детально рассматривать использование TransX Utility. Но мы рассмотрим некоторые примеры, чтобы вы смогли увидеть ее функциональные возможности. Пакет DBMS_XMLSTOREDBMS_XMLSTORE - это PL/SQL-пакет, который обеспечивает добавление XML-данных в таблицы базы данных. Эта C-базированная реализация обеспечивает лучшую производительность и системную управляемость, чем Java-базированный пакет DBMS_XMLSave. Этот пакет устраняет накладные издержки в начале работы Oracle JVM такие, как транслирование имен Java-классов при каждом вызове методов. Кроме того, DBMS_XMLSTORE построен на основании анализатора SAX, а не на анализаторе DOM. Соответственно, он лучше масштабирует большие XML-документы. Вы можете заметить это в следующем сопоставлении, используя эталонную схему SH: SQL> SELECT count(1) FROM sales; В предшествующем примере таблица sales эталонной схемы SH, описанная в Главе 8, используется для формирования большого XML-документа, который, когда анализируется, слишком велик для сконфигурированной памяти хранения Oracle JVM. Вы можете увеличить JAVA_POOL_SIZE, чтобы выделить больше памяти для обработки, однако, это может быть не достаточно, особенно, когда эта память выбирается из пула оперативной памяти базы данных. В Oracle Database 10 g вы можете воспользоваться пакетом DBMS_XMLSTORE для разрешения этой проблемы, как показано далее: DECLARE Рекомендуется использовать функцию SetUpdateColoumn() из DBMS_XMLSTORE всегда, когда это подходит, как было в предыдущем примере, потому как это позволяет программе DBMS_XMLSTORE узнать список столбцов, которые должны быть обновлены для использования явного SQL-связывания с XML-данными. Предыдущий пример использует следующее SQL-выражение при подготовке к добавлению данных: INSERT INTO sales(prod_id, cust_id, ..., amount_sold) values Это ускоряет процесс вставки данных, устраняя накладные расходы от парсинга (parsing - синтаксический анализ) SQL-предложений в базе данных. Использование внешних таблицПоявившийся в Oracle9 i механизм внешних таблиц предлагает возможность определения таблицы в базе данных, а хранение табличных данных отдельно от нее, вне базы данных. До Oracle Database 10 g внешние таблицы могли быть использованы только как таблицы для чтения. Другими словами, если вы создаете внешнюю таблицу для XML-файлов, эти файлы могут быть запрошены, а таблица может быть соединена с другими таблицами. Тем не менее, никакие DML операции: INSERT, UPDATE и DELETE не разрешены во внешних таблицах. ЗАМЕЧАНИЕ В Oracle Database 10g можно записывать данные во внешние таблицы, используя драйвер ORACLE_DATAPUMP вместо используемого по умолчанию ORACLE_DRIVER. В Oracle Database 10 g можно определить во внешней таблице столбцы VARCHAR2 и CLOB для сохранения XML-документов. В следующем примере показано, как создается внешняя таблица со столбцом CLOB для хранения XML-документов. Во-первых, вам нужно создать DIRECTORY для чтения фалов данных: CREATE DIRECTORY data_file_dir AS Затем надо использовать DIRECTORY для определения внешней таблицы: CREATE TABLE customer_xt (doc CLOB) Далее файл xml.dat customer1.xml Если таблица определена, то можно увидеть следующее: SQL> DESC customer_xt; Затем можно запросить XML-документ, как показано далее: SELECT XMLType(doc).extract('/Customer/EMAIL') FROM customer_xt; Тем не менее, запрос требует время работы на создание XMLType и XPath оценки, этот подход полезен, когда приложения нуждаются лишь в нескольких запросов к XML-данным и не хотят перегружать XML-данные в базу данных. В Oracle Database 10 g вы не можете создать внешнюю таблицу, которая содержит предопределенные типы XMLType-столбцов. Эволюция схемXML-схем развиваются, когда появляется новые требования для XML-данных. Ваши возможности отображать эти изменения в базе данных во многом зависит от памяти хранения. Если используются реляционные таблицы, то можно изменить структуру таблицы и обновить XML-представления для отражения нового отображения из XML в реляционные таблицы. Если используются CLOB XMLType, то новые XML-данные могут быть вставлены напрямую, так как эта память позволяет вам согласовано сохранять XML в разных XML-схемах. Однако для XML Schema, базируемых на XMLType, эволюция их схем - это очень дорогостоящий процесс, так как он требует обновления объектно-реляционной структуры XMLType. В Oracle Database 10 g этот тип развития ограничен для каждого выполняемого импорта/экспорта данных и использования функции CopyEvolution() из пакета DBMS_XMLSCHEMA. Наилучшая практикаЕсли нужно принимать XML-данные и сохранять их в базе данных, то первое, что нужно учесть, - это требует ли ваше приложение заготовки XML-структуры в базе данных. Как мы уже видели в Главе 8, вам нужно взвесить все "за и против" возможностей хранения XML и проанализировать, каким образом хранение повлияет на извлечение и обновление XML-данных. В дополнение, вам иногда нужно выбирать особенную модель XML-хранения для осуществления поддержки получения XML в сочетании с разработкой XML-схемы. После выбора для вашего приложения правильной модели XML-хранения в следующей секции представлены некоторые указания, что нужно знать, когда XML хранятся в Oracle Database 10 g. Обработка определений типов документовХотя DTD не используются для определения структуры памяти хранения для XMLType, Oracle XML DB разрешает все DTD-определения и объекты, определенные или упомянутые во вставленном XML-документе. Это выполняется в процессе вставки XMLType, когда анализируются (parsed) все пришедшие XML-документы. В этом процессе разрешаются все объекты, включая внешние и внутренние, определенные в DTD. Это означает, что все объекты перемещаются вместе со своими реальными значениями и, следовательно, все первоначальные (оригинальные) объектовые ссылки утрачиваются. Если вы захотите оставить эти ссылки, вам следует сохранить XML в CLOB, вместо CLOB XMLType. Потом вы можете всякий раз создать временный XMLType из этого CLOB, когда вам понадобится разрешить все объекты и использовать контент XML. Создание XML Schema-базируемых XMLTypes Вы можете создавать XML Schema-базируемые XMLTypes, используя функции конструирования XMLType или XMLType.CreateXML() функцию. Однако, когда вы используете эти функции для создания XML Schema-базируемых XMLTypes, XML-документ должен содержать XML-атрибуты SchemaLocation. Иногда XML-документ не содержит таких атрибутов. Как же вы сможете создать XML Schema-базируемый XMLType без изменения оригинального XML-документа? В Главе8 было показано, что можно использовать функцию XMLType.CreateSchemaBasedXML и специфицировать URL XML схемы, как показано ниже: INSERT INTO product(id, name, description) URL http://xmlns.oracle.com/xml/content.xsd является зарегистрированным URL XML схемы и будет использоваться для сохранения продуктового DESCRIPTION. Специфицирование пространства именЕсли сохраненный XML-документ имеет пространства имен (namespaces), то все XML-запросы к этому документу должны быть определены для пространства имен, так как <Namespace:Element> - это не одно и то же что <Element> в XML. Обе функции XMLType.existNode() и XMLType.extract() разрешают пользователю специфицировать пространство имен во втором параметре, как показано ниже: MEMBER FUNCTION existsNode(xpath in varchar2, nsmap in varchar2) В этом случае Xpath требует использования полностью квалифицированных (qualified) XML имен, которые содержат имя элемента и его пространство имен. Например, вы можете вставить XML-документ с двумя декларированными пространствами имен в XMLTypes, как показано ниже: CREATE TABLE temp (doc XMLType); Чтобы запросить этот документ, вы можете определить пространство имен и его префикс во втором параметре функции XMLType.extract() и квалифицировать XPath, используя префикс, как показано в следующем SQL-запросе: SELECT a.doc.extract('/a:foo/a:foo_type', Результатом будет: <foo_type xmlns="http://www.example.com" ЗАМЕЧАНИЕ Если вы не используете квалифицированное имя пространства имен в XPath после предоставленных пространств имен, вы получите [сообщение] ORA-31013: Invalid XPath expression error. Если у вас есть несколько пространств имен, то можно составить из них список, используя второй параметр функций XMLType.existNode() и XMLType.extract() и разделить их пробелами, как показано в следующем примере: SELECT a.doc.extract('/a:foo/a:lastupdate/@b:type', ВЫВОДЫ В этой главе рассматривались разнообразные опции XML-памяти и соответствующие им стратегии загрузки в Oracle Database 10 g . Таблица 9-1 показывает взаимодействие между XML-памятью хранения и функциональностью предложенных XML-утилит для загрузки данных. Вы можете выбрать одну из этих утилит или использовать SQL- или PL/SQL- интерфейсы для загрузки XML-документов в базу данных Oracle.
Таблица 9-1. Хранение XML-данных и утилиты загрузки данных Ссылки по теме
|
|