Image
Top
Navigation

チュートリアル13 : クラスを作成する

チュートリアル12 : データベースを作成するからの続きです。

———- Orient Studio(GUIツール)を利用する場合 ———-

前回に、ドキュメントデータベース(doc-test1)を一個作成して、存在するクラスの一覧を見てみました。

Orient Studio

DBを作成した直後ですから、データベース管理用のクラスだけが表示されています。

クラスを作成する

クラスは、リレーショナルDBの世界で言えば、テーブルに当たります。ただ、OrientDBはオブジェクト指向が基本コンセプトになっているので、
それ風の性質も一杯持っているのですが、それはおいおいとして、とりあえずクラスを作成しましょう。

今回は”Student”というクラスを作成してみます。

Orient Studio

  • name クラスの名前
  • Super Class スーパークラス(親クラス)を指定する場合。オプション。
  • Alias クラスのエイリアス(別名)。オプション。
  • Abstract 抽象クラスとして作成する場合のみチェック。

OrientDBはオブジェク指向のコンセプトを持っていますので、スーパークラスを指定して、その定義を継承することができます。
抽象クラスとして作成する場合は、データ実体を持てません。

“save”をクリックすると、クラスが保存されます。

Orient Studio

一覧に、”Student”というクラスが追加されています。

クラス名部分をクリックしてみましょう。

Orient Studio

続いて、”New Property”をクリックしてみます。

Orient Studio

なるほど、ここで、プロパティを定義、つまりスキーマを定義するんですね。
OrientDBはスキーマフル(スキーマ指定をすること)でも、スキーマレスでも、さらにその両方をミックスしたやり方でも利用することができます。

せっかくなので、ここではスキーマレスで利用してみましょう。

とりあえずデータを登録してしまいましょう。

SQL入力エリアで以下を実行します。
insert into Student (name1, name2, gender) values (‘山田’, ‘太郎’, ‘M’)

Orient Studio

ちゃんと登録できますね。

クラスに、スキーマ定義しても(スキーマフル)、しなくても(スキーマレス)良いとすると、スキーマ定義にはなんのメリットがあるのでしょうか?
実は、スキーマを定義すると、制約とインデックスが使えるようになります。

今度は、”Student2″というクラスを作成して、以下の3つのプロパティを定義してみましょう。

プロパティ
name1 string
name2 string
gender string

プロパティの定義はこんな感じ。

Orient Studio

3つのプロパティ定義後はこんな感じです。

Orient Studio

これに以下のデータを登録します。

insert into Student2 (name1, name2, gender) values ('山田', '太郎', 'M')

Orient Studio

これも登録できました。

スキーマ定義したクラスStudent2に対して、定義していないプロパティをインサートしようとするとどうなるんでしょうか?

insert into Student2 (name1, name2, gender, address) values ('河野', '一郎', 'M', '東京都')

Orient Studio

フツーに出来ちゃいますね。

2件のデータを検索してみるとこうなります。

Orient Studio

さて、さきほどの、プロパティ定義の画面で、Student2クラスのname1プロパティを必須項目(mandatory制約)を指定してみます。

Orient Studio

ここでname1プロパティが無いレコードを登録しようとしてみます。

insert into Student2 (name2, gender, address) values ('一郎', 'M', '東京都')

Orient Studio

やはり、エラーで怒られました。

———- コンソールを利用する場合 ———-

データベースへ再接続する

前回に、ドキュメントデータベース(doc-test1)を一個作成しました。

まずそれにコンソールから接続してみます。


orientdb> connect remote:localhost/doc-test1 admin パスワード

Connecting to database [remote:localhost/doc-test1] with user 'admin'...OK

クラスを作成する

クラスは、リレーショナルDBの世界で言えば、テーブルに当たります。ただ、OrientDBはオブジェクト指向が基本コンセプトになっているので、
それ風の性質も一杯持っているのですが、それはおいおいとして、とりあえずクラスを作成しましょう。

コンソールで、データベース中のクラスの一覧を表示してみます。



orientdb {doc-test1}> classes


CLASSES
----------------------------------------------+------------------------------------+------------+----------------+
 NAME                                         | SUPERCLASS                         | CLUSTERS   | RECORDS        |
----------------------------------------------+------------------------------------+------------+----------------+
 OFunction                                    |                                    | 7          |              0 |
 OIdentity                                    |                                    | -          |              0 |
 ORestricted                                  |                                    | -          |              0 |
 ORIDs                                        |                                    | 6          |              0 |
 ORole                                        | OIdentity                          | 4          |              3 |
 OSchedule                                    |                                    | 8          |              0 |
 OTriggered                                   |                                    | -          |              0 |
 OUser                                        | OIdentity                          | 5          |              3 |
----------------------------------------------+------------------------------------+------------+----------------+
 TOTAL = 8                                                                                                     6 |
----------------------------------------------+------------------------------------+------------+----------------+
orientdb {doc-test1}>

今表示されているのはデータベース作成直後に存在するクラスです。たとえばOUserは、このデータベースのユーザ情報が格納されています。

ここで新しくStudentというクラスを作成してみましょう。

create class Student

なお、クラス名等では大文字小文字は区別されません。この後にSTUDENTとかstudentというクラスを作成しようとしても、already exists in current databaseと言ってエラーになります。

データを作成する

乱暴ですがいきなりデータを登録してみましょう。


orientdb {doc-test1}> insert into Student (name1, name2, gender) values ('山田', '太郎', 'M')

Inserted record 'Student#9:0{name1:山田,name2:太郎,gender:M} v1' in 0.003000 sec(s).

orientdb {doc-test1}>

うまくいきましたね。登録されたデータを見るにはBrowseコマンドかSQLのselectを利用します。

orientdb {doc-test1}> browse class Student


----+----+-----+-----+------
#   |@RID|name1|name2|gender
----+----+-----+-----+------
0   |#9:0|山田 |太郎 |M
----+----+-----+-----+------

ちゃんと登録されています。
項目も定義していないのに、なぜデータが登録されるのかというとOrientDBがスキーマレスで利用可能なデータベースだからです。
でもOrientDBはスキーマも使用できます(スキーマフル)。

クラスStudent2を作成して、スキーマを利用して項目(プロパティ)を定義してからデータを登録してみましょう。


orientdb {doc-test1}> create class Student2

Class created successfully. Total classes in database now: 10

orientdb {doc-test1}> create property Student2.name1  string

Property created successfully with id=1

orientdb {doc-test1}> create property Student2.name2  string

Property created successfully with id=2

orientdb {doc-test1}> create property Student2.gender string

Property created successfully with id=3

そちらにも同じデータを登録してみましょう。


orientdb {doc-test1}> insert into Student2 (name1, name2, gender) values ('山田', '太郎', 'M')

Inserted record 'Student2#10:0{name1:山田,name2:太郎,gender:M} v1' in 0.003000 sec(s).

orientdb {doc-test1}> browse class Student2

----+-----+-----+-----+------
#   |@RID |name1|name2|gender
----+-----+-----+-----+------
0   |#10:0|山田 |太郎 |M
----+-----+-----+-----+------

@RID以外、まったく同じ結果ですね。@RIDはそのレコードを一意で表すレコードIDで後で説明します。
それと最初の#記号の下の数字は表示するときの連番にすぎません。ただしこれを使って、レコードの詳細情報を表示することができます。


orientdb {doc-test1}> display record 0

--------------------------------------------------
ODocument - Class: Student2   id: #10:0   v.1
--------------------------------------------------
               name1 : 山田
               name2 : 太郎
              gender : M

スキーマ定義したクラスStudent2に対して、定義していないプロパティをインサートしようとするとどうなるんでしょうか?


orientdb {doc-test1}> insert into Student2 (name1, name2, gender, address) values ('河野', '一郎', 'M', '東京都')

Inserted record 'Student2#10:1{name1:河野,name2:一郎,gender:M,address:東京都} v1' in 0.002000 sec(s).

orientdb {doc-test1}> browse class Student2

----+-----+-----+-----+------+-------
#   |@RID |name1|name2|gender|address
----+-----+-----+-----+------+-------
0   |#10:0|山田 |太郎 |M     |null
1   |#10:1|河野 |一郎 |M     |東京都
----+-----+-----+-----+------+-------

登録できちゃいますね。
クラスに、スキーマ定義しても(スキーマフル)、しなくても(スキーマレス)良いとすると、スキーマ定義にはなんのメリットがあるのでしょうか?
実は、スキーマを定義すると、制約とインデックスが使えるようになります。それと、スキーマレスの場合、個々のレコード中に項目名を含むので若干データ量が増えるというデメリットもありますが、そこらの詳細については、後々説明していきます。

ここでは、サンプル的に、制約を定義してそれを検証してみましょう。

制約を定義する

構文

    ALTER PROPERTY <class>.<property> <attribute-name> <attribute-value>

Where:
class はクラス名です
property はプロパティ名称を変更します
attribute-name, は attribute 名称を変更します
attribute-value, は attribute 値を変更します

まず、Student2クラスのname1プロパティを必須項目(mandatory制約)を指定してみます。


orientdb {doc-test1}> alter property Student2.name1 mandatory true

Property updated successfully

ここでname1プロパティが無いレコードを登録しようとしてみます。


orientdb {doc-test1}> insert into Student2 (name2, gender, address) values ('一郎', 'M', '東京都')

Error: com.orientechnologies.orient.core.exception.OCommandExecutionException: Error on execution of command: sql.insert into Student2 (name2, gender, address) values ('一郎', 'M', '東京都')

Error: com.orientechnologies.orient.core.exception.OValidationException: The field 'Student2.name1' is mandatory

The field ‘Student2.name1’ is mandatoryだと怒られました。

さて、スキーマを定義していないStudentクラスでは本当に制約は使えないのでしょう。


orientdb {doc-test1}> alter property Student.name1 mandatory true

Error: com.orientechnologies.orient.core.exception.OCommandExecutionException: Property 'Student.name1' not exists

今度は、Property定義が無いよと言って怒られました。

さて、前に出てきた@RIDとは何でしょうか?

レコードID(RID)

OrientDBでは、レコードID(RID)と呼ばれる、各レコードにユニークなIDを持っていて、レコード登録時に自動採番号されます。 レコードIDは二つの部分で構成されます。
レコードIDは二つの部分で構成されます。

#<cluster-id>:<cluster-position>
  • cluster-id これは、クラスターを示すIDです。データベース毎に最大32,767件(2の15乗)のクラスターが持てます。
  • cluster-position これはクラスター中のレコードのIDです。クラスター単位で9,223,372,035,000,000,000件 (2の63乗)のレコードが持てます。

ここでクラスターという概念が初めて登場しました。しかし、ここでクラスターについて説明し出すと話が難しくなるので、いったん忘れます。
とりあえず、デフォルトではスキーマ(=テーブル)と1対1で存在する物理的な場所に関する概念、と考えて置いて下さい。

なんにしろ、OrientDBの、データベース中のレコードの最大件数は、上記の2の15乗×2の63乗なります。302,231,454,903,657,000,000,000です。
だれも試した人はいないでしょうが。

レコードIDはデータベース中の物理的な位置です。なので、レコードIDでレコードを検索するのは非常に高速です。
レスポンス時間はほとんどゼロに近く、データベースが非常に大規模になってもその速度は変わりません。

レコードIDを利用してコンソール上でデータを表示するには、load recordコマンドを利用します。


orientdb {doc-test1}> load record #9:0

--------------------------------------------------
ODocument - Class: Student   id: #9:0   v.1
--------------------------------------------------
               name1 : 山田
               name2 : 太郎
              gender : M

OK

ここに表示されたv.1とは何でしょう。OrientDBは、MVCC対応で、更新されるたびに、内部的なレコードバージョンをカウントアップします。
これは楽観的排他制御のためにも利用されます。

クラスをDROPする

構文

    DROP CLASS <class-name>

Where:
class-name クラス名.

クラスのプロパティを表示する

info class <class-name>

orientdb {doc-test1}> info class student2

Class................: Student2
Default cluster......: student2 (id=12)
Supported cluster ids: [12]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 gender                        | STRING      | null                          | false     | false    | false    |           |           | default  |
 name1                         | STRING      | null                          | false     | false    | false    |           |           | default  |
 name2                         | STRING      | null                          | false     | false    | false    |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+

このページに登場したコマンド類のリファレンス

チュートリアル14 : SQLを使うへ続きます。