2010年9月17日金曜日

オープンソース NoSQL データベース OrientDB を使ってみる #1

今回は OrientDB という オープンソースの NoSQL データベースを紹介致します
※OrientDB は開発が活発なプロジェクトであるため、記載した機能等が将来変更される可能性があります
 (実際、このエントリ書いてる最中にバージョン上がるし、実行ファイル名変わるし…)

OrientDB は今年(2010年)5月に公開された、新しいプロダクトです
(なお、ベースとなった Orient ODBMS ( C++ にて実装) は1999年にリリースされており、これは10年近くの実績があります)
開発者は Luca Garulli というイタリアの方で、 JDO 1.0 、 2.0 のエキスパートメンバーのひとりです
現在のところ Luca 1人で開発していますが、将来的にはコミュニテイとして開発者を増やしたいとのことです
(そのため、 Wiki のドキュメント整備まで手が回らないのか、情報が最新版と一致していない箇所があります)

OrientDB は DBMS の分類では CouchDB や MongoDB と同じ、ドキュメント指向データベースですが、データ間の関連(リレーション)はグラフデータベースのように扱うといった、複数の DBMS の特徴を備えたものとなっています
この他にも OrientDB には以下のような特徴があります

・100% Java にて記述されている
・軽量である(本体のみで約1MB)
・高速である(一般的なコンピュータ(※1)にて200,000件/秒の登録が可能(※2))
・グラフデータベースのスタックとして Tinkerpop を採用
 (Gremlin などの対応プロダクトが利用可能)
・データ操作には、Java API 、HTTP Restful API、 SQL ライクな構文をサポート
・スキーマレス、スキーマフル、複合の複数のスキーマタイプを選択可能
・ACIDトランザクションのサポート
・組込モード、サーバーモードの2つの動作モードをサポート
・ライセンスは Apache License 2.0
※1 … DELL Notebook model XPS M1530 with Intel(r) Core Duo T7700 2.40Ghz, 3 GB RAM and HD 5.400rpm, O.S. MS Windows Vista, JRE 1.6.0_20
※2 … インメモリでの処理時

また、 OrientDB を基盤とした OrientKV というキー・バリューストアのプロダクトがあります
(OrientDB、OrientKV(Key/Value Server) とは別に Orient Object(Object Database) というプロダクトもあるのですが、 OrientDB のコア機能として含まれているようなのでここでの説明は割愛しています)
OrientKV は本体が軽量、データ処理が高速であるという OrientDB の良い部分を引き継ぎ、且つ複数ノードにデータを分散させて格納する、分散キー・バリューストアとしての運用が設定にて簡単に実現できるという特徴があります
OrientKV の詳細に関しては別エントリにてご紹介したいと思います

次に OrientDB のインストールと、実際の動作についてです
以下の説明は下記環境にて行っています
Windows、Linux をご利用の方は、各環境に合わせて読み替えていただければと思います
(Windows 環境では .sh ファイルを .bat ファイルと読み替えるなど)

・Mac OS X 10.6.4
・Java(TM) SE Runtime Environment (build 1.6.0_20-b02-279-10M3065)

OrientDB のインストールはパッケージのダウンロード、及び展開のみで完了します
コチラのリストより最新版(2010年09月17日現在)である "orientdb-0.9.22.zip" をダウンロードし、適当な場所に展開します

展開後、 "config" ディレクトリ内にある "orient-server-config.xml" ファイルを開き、9行目、10行目ほどにあるリスナのポート番号をご使用の環境に合わせ、変更します
(デフォルト値として設定されている、"2424-2430"(9行目)、"2480-2490"(10行目)の範囲内のポート番号が使用可であれば、特に変更は必要ありません)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<orient-server>
<network>
<protocols>
<protocol implementation="com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary" name="binary"/>
<protocol implementation="com.orientechnologies.orient.server.network.protocol.http.ONetworkProtocolHttpDb" name="http"/>
</protocols>
<listeners>
<listener protocol="binary" port-range="2424-2430" ip-address="127.0.0.1"/>
<listener protocol="http" port-range="2480-2490" ip-address="127.0.0.1">
<!-- 〜中略〜 -->
</orient-server>

また、 "bin" ディレクトリ内に移動し、下記ファイルに実行権限を付与します

$ cd ./bin
$ chmod +x ./server.sh ./console.sh

以上でインストール、及び初期設定は完了です

("bin" ディレクトリ内に移動したままの状態で)下記コマンドを実行し、サーバの起動を行ないます
(サーバを停止する場合は Ctrl + C にて停止します)

$ ./server.sh

最後に実際にデータの登録、参照、更新、削除を行ないたいと思います
OrientDB のデータに対しては、 Java API 、REST API 、同梱のクライアントアプリケーションの "Console" 、そして Web ベースのクライアントアプリケーションである "OrientDB Studio" から操作可能となっています
上記の中ではJava API の動作が一番安定していますが、使いやすさから今回は "Console" での操作を紹介します
(Java API での動作は次回紹介したいと思います)
なお、 "OrientDB Studio" はバグや未実装の機能が多く、 orientdb-0.9.22 のバージョンでは実用するには厳しい状態です

("bin" ディレクトリ内に移動したままの状態で)下記コマンドを実行し、"Console" の起動を行ないます
(起動後はプロンプトの入力待ち状態が ">" となります)

$ ./console.sh

起動後、まず "help" と入力します
下記のように各コマンドとその説明が表示されます

> help

AVAILABLE COMMANDS:

* get Return the value of a property
* classes Display all the configured classes
* set Change the value of a property
* delete Delete records from the database
* insert Insert a new record into the database
* connect Connect to a database
* update Update records in the database
* info Display information about current status
* properties Return all the configured properties
* disconnect Disconnect from the current database
* create database Create a new database
* create cluster Create a new cluster in the current database. The cluster can be physical or logical.
* remove cluster Remove a cluster in the current database. The cluster can be physical or logical.
* load record Load a record in memory and set it as the current one
* display record Display current record's attributes
* grant Grant privileges to a role
* revoke Revoke privileges to a role
* create link Create a link from a JOIN
* create class Create a class
* create property Create a property
* select Execute a query against the database and display the results
* script Execute a script against the current database. If the database is remote, then the script will be executed remotely.
* create index Create an index on a property
* create index Create an index on a property
* browse class Browse all the records of a class
* browse cluster Browse all the records of a cluster
* clusters Display all the configured clusters
* dictionary keys Display all the keys in the database dictionary
* dictionary get Loookup for a record using the dictionary. If found set it as the current record
* dictionary put Insert or modify an entry in the database dictionary. The entry is composed by key=String, value=record-id
* dictionary remove Remove the association in the dictionary
* export database Export a database
* compare databases Compare two databases
* import database Import a database into the current one
* export record Export the current record in the requested format
* help Print this help
* exit Close the console

コマンドの最後にある通り、 "exit" コマンドを使用すると、"Console" アプリケーションを終了することができます

次に "connect" コマンドを実行し、データベースに接続します
"connect" コマンドは以下のように入力します

connect <接続モード>:<データベースパス> <ユーザー名> <ユーザーパスワード>
・"接続モード" には "local" と "remote" があり、ローカルデータベースへの接続は "local" 、ローカル、またはリモートにて起動しているサーバーへの接続には "remote" を使用してください
・"データベースパス" はデータベースまでのパスとなります
 接続モードによりパスの指定が異なり、 "local" ではデータベースまでのファイルパス、 "remote" ではサーバーのアドレスとデータベース名となります
・"ユーザー名" 、 "ユーザーパスワード" はデータベースに設定されているユーザー名、パスワードとなります
 データベース作成時、デフォルトで下記ユーザーが作成されます

  ・ユーザー名:admin / パスワード : admin … データベースに対して、書き込み、読み込み権限を持ちます
  ・ユーザー名:writer / パスワード : writer … データベースに対して、書き込み限を持ちます
  ・ユーザー名:reader / パスワード : reader … データベースに対して、読み込み権限を持ちます

今回はユーザーは "admin" 、データベースは、デフォルトで作成されている "demo" データベースを利用します
使用するコマンドは下記のようになります

> connect remote:localhost/demo admin admin

"Connecting to database [remote:localhost/demo] with user 'admin'...OK" と表示され、入力待ち状態となったら接続成功です
接続に失敗する場合は、ポート番号が衝突していないか、確認してみてください

次にデータを登録しますが、その前にまずクラスの作成を行う必要があります
クラスは RDBMS の表と似た概念になり、データ集合のモデルとなるものです
なお、 OrientDB のクラスは、(上記特徴にも書いたとおり)スキーマレス、スキーマフル、両者の混在という設定が可能です
クラスの作成には "create class" コマンドを使います
"create class" コマンドは以下のように入力します

create class <クラス名>
・"クラス名" は作成するクラス名を指定します
 (クラスの識別として大文字小文字は区別されます)

使用するコマンドは下記のようになります

> create class Person

"Class created successfully with id=xx"(xx はユニークな ID、データベース上にあるクラスの ID が表示されます) と表示されれば、クラスの作成は完了です。
ここで、大きなバグがあるのですが、クラスを作成しても即時反映がされません
"exit" コマンドで接続解除をして、 "console.sh" でコンソールを再起動し、 "connect" コマンドで接続しなおしてください
再接続後、"classes" コマンドを実行すると、既存のクラスに加えて、先程作成したクラス名が表示されるのがわかります

> classes
CLASSES:
--------------------+------+------------------------------------------+-----------+
NAME    | ID | CLUSTERS         | ELEMENTS |
--------------------+------+------------------------------------------+-----------+
ORole    |  0| orole         |   3 |
OUser    |  1| ouser         |   3 |
Account    |  2| account         |  1005 |
Company    |  3| company         |   9 |
Profile    |  4| profile         |   9 |
Whiz    |  5| whiz          |  1000 |
Address    |  6| address         |  164 |
City    |  7| city          |  55 |
Country    |  8| country         |  55 |
Animal    |  9| animal         |   0 |
AnimalRace   | 10| animalrace        |   3 |
OGraphVertex  | 11| ographvertex        |  102 |
OGraphEdge   | 12| ographedge        |  101 |
Person    | 13| person         |   0 |
--------------------+------+------------------------------------------+-----------+
TOTAL                  2509 |
----------------------------------------------------------------------------------+

作成したクラスにスキーマを定義することが可能ですが、今回はスキーマレスで使用します

OrientDB ではデータ操作に、 RDBMS のように SQL に似た構文を使用することができます
データの登録には "INSERT" 文を使います

INSERT INTO <クラス名>|cluster:<クラスタ名> (<フィールド名>[,]*) VALUES (<フィールド値>[,]*)
・"クラス名"にはデータを登録するクラスの名前を記述します
・"クラスタ名" にはデータを格納するクラスタ名を記述します
 (クラスタは今回使用しませんので、説明は省略します)
・"フィールド名"をキーに"フィールド値"が登録されます

以下のデータを登録してみます

> insert into Person (name, surname) values ('Marty', 'McFly')

実行後、 "Inserted record Person@19:0{name:Marty,surname:McFly} in X sec(s)."(Xは秒数(環境により異なります)) のように表示されたら登録成功です
登録されたデータを確認する簡単な方法は "browse class" コマンドを使用することです

> browse class Person

---+--------+--------------------+--------------------
#| REC ID |NAME    |SURNAME   
---+--------+--------------------+--------------------
0| 19:0|Marty    |McFly   
---+--------+--------------------+--------------------

また、 SQL のように "SELECT" 文を使用することもできます
("browse class" コマンドと異なり、抽出する条件や並び順などを指定できます)

SELECT FROM <対象> [WHERE <条件>*] [ORDER BY <フィールド名>* [ASC|DESC]*]
・"対象"には検索する"クラス名"、"クラスタ名"、及び"レコードID"が指定可能です
 ("クラスタ名"、"レコードID"については今回使用しませんので、説明は省略します)
・"条件"には、データを抽出する条件を指定します(省略可能です)
・ORDER BY 句を使用した場合、指定した "フィールド名" 順に昇順( "ASC" )、降順( "DESC" )に並べ替えます

先程登録したデータを検索します

> select from Person where name = 'Marty' order by surname

---+--------+--------------------+--------------------
#| REC ID |NAME    |SURNAME   
---+--------+--------------------+--------------------
0| 19:0|Marty    |McFly   
---+--------+--------------------+--------------------

次はデータの変更(更新)を行ないます

update <クラス名>|cluster:<クラスタ名> set [[,] <フィールド名> = <フィールド値>]* [where <条件>]
・"クラス名"にはデータを更新するクラスの名前を記述します
・"クラスタ名" には更新するデータが格納されたクラスタ名を記述します
 (クラスタは今回使用しませんので、説明は省略します)
・"フィールド名"の値を"フィールド値"にて更新します
・"条件"には、更新対象となるデータの条件を指定します(省略可能ですが、対象が全件となります)

登録したデータを更新します

> update Person set name = 'George' where name = 'Marty'

実行後、 "Updated 1 record(s) in X sec(s)." (Xは秒数(環境により異なります))のように表示されたら更新成功です
"browse class" コマンドを使用すると、変更が確認できます

> browse class Person

---+--------+--------------------+--------------------
#| REC ID |NAME    |SURNAME   
---+--------+--------------------+--------------------
0| 19:0|George    |McFly   
---+--------+--------------------+--------------------

最後にデータの削除を行ないます

DELETE FROM <クラス>|cluster:<クラスタ> [WHERE <条件>]
・"クラス名"にはデータを削除するクラスの名前を記述します
・"クラスタ名" には削除するデータが格納されたクラスタ名を記述します
 (クラスタは今回使用しませんので、説明は省略します)
・"条件"には、削除対象となるデータの条件を指定します(省略可能ですが、対象が全件となります)

更新したデータを削除します

> delete from Person where surname = 'McFly'

実行後、 "Delete 1 record(s) in X sec(s)."(Xは秒数(環境により異なります)) のように表示されたら削除成功です
"browse class" コマンドを使用すると、データが存在しないことが確認できます

> browse class Person

以上で、"Console" アプリケーションを使用した OrientDB の操作方法になります
次回は、 Java API を利用した OrientDB の操作方法を紹介したいと思います

0 件のコメント: