Пост 16. Oracle RDBMS External tables, как способ прочитать данные из NoSQL.
Доброго времени суток!
Продолжаю рассказывать об интеграции Oracle NoSQL Database и Oracle RDBMS.
Сегодня речь пойдет о новой возможности появившейся во второй версии Oracle NoSQL database - возможность чтения NoSQL данных из реляционки.
Осуществляется это через механизм Oracle RDBMS External Tables. Если в двух словах внешняя таблица - это технология, которая позволяет читать файл с файловой системы сервера базы данных. Лежит, например, csv файл на серваке, описываю я его в базе данных (create table my_tab_ext ...), а потом могу прочитать эти даные обыкновенным select (очень удобный и быстрый способ загружать данные, например). В Oracle 11.2g добавили пропроцессор. В этом случае,я так же описываю поток данных, только прежде чем прочитать файл могу провеси над ним некие преобразования. Например лежит у меня заархивированный csv, до того как гнать поток данных в базу, необходимо его распаковать. Все это возможно с помощью препроцессора (в этом случае препроцессором будет команда unzip).
Ноу-хау NoSQL v2 заключается в создании програмы пропроцессора.
Наверное я Вас окончательно запутал? Вот тут действительно лучше один раз увидеть.
Давайте разберем конкретный пример. Наберитесь терпения и шаг за шагом внимательно прочтите последовательность действий.
-Создание необходимых директорий
SQL> CREATE DIRECTORY ext_tab AS '/home/oracle/nosql/data/';
SQL> CREATE DIRECTORY nosql_bin_dir AS '/home/oracle/nosql/bin/';
SQL> CREATE DIRECTORY ext_tab AS '/home/oracle/nosql/data/';
SQL> CREATE DIRECTORY nosql_bin_dir AS '/home/oracle/nosql/bin/';
-Назначение пользователю Oracle RDBMS необходимых прав:
SQL> GRANT READ, WRITE ON DIRECTORY ext_tab TO nosql;
SQL> GRANT READ, EXECUTE ON DIRECTORY nosql_bin_dir TO nosql;
В файл препроцессора nosql_stream прописываем переменные окружения:
export KVHOME= ...
export CLASSPATH= ...
Cам файл необходимо взять из архива дистрибутива Oracle NoSQL Database.
В моем случае я его переложил в /home/oracle/nosql/bin/nosql_stream
2) Подготовим данные в NoSQL базе, которые мы потом будет считывать из Oracle.
Загрузим данные в формате “/profile/Имя/Фамилия/-/phone/:номер телефона” (несколько строчек).
Если не знаете как это делать смотрите вот здесь
3) Cоздайте свой собственный formatter, который будет преобразовывать входную пару ключ-значение в формат внешней таблицы (string с разделителями, указанными при создании внешней таблицы). Java код ниже:
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.kv.Key;
import oracle.kv.KeyValueVersion;
import oracle.kv.KVStore;
import oracle.kv.Value;
import oracle.kv.exttab.Formatter;
public class b_NewFormatter implements Formatter {
private static final String USER_OBJECT_TYPE = "profile";
public b_NewFormatter() {
}
@Override
public String toOracleLoaderFormat(final KeyValueVersion kvv,
final KVStore kvStore) {
final Key key = kvv.getKey();
final Value value = kvv.getValue();
final String sValue = new String(value.getValue());
final List<String> majorPath = key.getMajorPath();
final List<String> minorPath = key.getMinorPath();
final String objectType = majorPath.get(0);
if (!USER_OBJECT_TYPE.equals(objectType)) {
throw new IllegalArgumentException("Unknown object type: " + key);
}
final String Name = majorPath.get(1);
final String Surname = majorPath.get(2);
final String atr = minorPath.get(0);
final StringBuilder sb = new StringBuilder();
sb.append(Name).append("|");
sb.append(Surname).append("|");
sb.append(atr).append("|");
sb.append(sValue).append("|");
return sb.toString();
}
private String readString(final DataInput in)
throws IOException {
if (!in.readBoolean()) {
return null;
}
return in.readUTF();
}
}
4) В Oracle RDBMS создаем внешнюю таблицу
CREATE TABLE profile_external (name VARCHAR2(64),
surname varCHAR2(64),
atr VARCHAR2(64),
sValue varchar2(256))
ORGANIZATION EXTERNAL
(type oracle_loader
default directory ext_tab
access parameters (records delimited by newline
preprocessor nosql_bin_dir:'nosql_stream'
fields terminated by '|')
LOCATION ('profile.dat'))
PARALLEL;
В моем примере:
[oracle@localhost ~]$ cat /home/oracle/nosql/conf/config2.xml
<config version="1">
<component name="publish" type="params">
<!-- Fill in appropriate values for
oracle.kv.exttab.connection.url and oracle.kv.exttab.connection.user
-->
<property name="oracle.kv.exttab.connection.url"
value="jdbc:oracle:thin:/@//localhost:1521/XE"
type="STRING"/>
<property name="oracle.kv.exttab.connection.user"
value="nosql" type="STRING"/>
<property name="oracle.kv.exttab.tableName" value="profile_external"
type="STRING"/>
<!-- If you use a wallet to access your Oracle Instance, uncomment
this and fill in a suitable value for the
oracle.kv.exttab.connection.wallet_location
property. -->
<!--
<property name="oracle.kv.exttab.connection.wallet_location"
value="PATHNAME TO YOUR WALLET DIRECTORY" type="STRING"/>
-->
</component>
<component name="nosql_stream" type="params">
<!-- Fill in appropriate values for
oracle.kv.kvstore and oracle.kv.hosts
-->
<property name="oracle.kv.kvstore"
value="kvstore"
type="STRING"/>
<property name="oracle.kv.hosts"
value="LOCALHOST:5000"
type="STRING"/>
<property name="oracle.kv.batchSize"
value="100"
type="INT"/>
<property name="oracle.kv.depth"
value="PARENT_AND_DESCENDANTS"
type="STRING"/>
<property name="oracle.kv.parentKey"
value="/profile"
type="STRING"/>
<property name="oracle.kv.formatterClass"
value="Answers_part3.b_NewFormatter"
type="STRING"/>
<!-- Other properties that are not needed for the cookbook example. -->
<!--
<property name="oracle.kv.subRange"
value="I/login/"
type="STRING"/>
<property name="oracle.kv.consistency"
value="tIme(10 seconds, 10 seconds)"
type="STRING"/>
<property name="oracle.kv.keyDelimiter"
value="|"
type="STRING"/>
<property name="oracle.kv.variableSizeBytes"
value="0"
type="INT"/>
<property name="oracle.kv.timeout"
value="10 seconds"
type="STRING"/>
-->
</component>
</config>
6) Используя утилиту publisher создаем конфигурационный файл на который указывает внешняя таблица
[oracle@localhost ~]$ cat /home/oracle/nosql/sh/publish_config.sh
#!/bin/bash
source ~/.bash_profile
java -classpath $KVHOME/lib/*:$ORACLE_HOME/jdbc/lib/ojdbc6.jar oracle.kv.exttab.Publish -config /home/oracle/nosql/conf/config2.xml -publish
7) Добавьте в конфиг препроцессора (/home/oracle/nosql/bin/nosql_stream) путь к новому Formatter.
[oracle@localhost ~]$ cat /home/oracle/nosql/bin/nosql_stream
#!/bin/bash
export PATH=$PATH
export KVHOME=/home/cloudera/nosql/kv-2.0.23
export CLASSPATH=$KVHOME/lib/kvstore-2.0.23.jar:$KVHOME/lib/kvstore-ee-2.0.23.jar:/home/cloudera/nosql/kv-2.0.23/examples/:/home/oracle/nosql/jar/DeveloperDay.jar
/usr/java/jdk1.7.0_02/bin/java oracle.kv.exttab.Preproc $*
8) Пишем SQL для доступа к данным!
select * from profile_external
Вот вроде бы и все. Если внимательно выполнить шаг за шагом здесь описанное - все получится. Если будут вопросы - не стесняйтесь их задавать!
Комментариев нет:
Отправить комментарий