次世代のデータベース 「EdgeDB」 を試してみる

152件のシェア(すこし話題の記事)

What is EdgeDB?

EdgeDBとは、次世代データベースと言われている新しいデータベースです。
公式サイト曰く、

  • NoSQLデータベースのシンプルさを持つ
  • リレーショナルモデルの強力なクエリー(EdgeQL)やGraphQLで問い合わせ可能
  • 厳密さ、一貫性、パフォーマンスを兼ね備えている

とのことです。
PostgleSQLをベースとして構築されており、データ整合性が保証されていたり、
構造化された複雑なデータを扱うことができたりもします。
また、EdgeDB独自の高度なクエリが使えたりするなど、
NoSQLデータベースとRelationalデータベース両方の特徴をもったデータベースになります。

なお、EdgeDBはApache2ライセンスで開発されており、先日alpha版がリリースされました。

EdgeDB Features

公式では、EdgeDBは下記の特徴を持つと記述しています。

  • EdgeDBの設計
    EdgeDBは、リアクティブで柔軟性の高いアプリケーションを構築するための最新のアプローチをサポートするように設計されています。
    また、EdgeDBのデータモデルと強力なクエリ言語のおかげで、複雑なデータ構造も簡単に扱うことができます。

  • EdgeQL(Edge Query Language)
    EdgeQLとはEdgeDBのクエリ言語で、効率的&直感的&学ぶのが容易です。 EdgeQLは、データモデルのネストやフィルタリング、ソート、Aggregationをサポートしています。

  • アクセス方法
    EdgeDBは、言語バインディング用の高性能プロトコル(どれのことかわからず。。。)と、HTTP/GraphQL APIをサポートしています。

  • Schemaへのアクセス
    スキーマとメタデータへクエリでアクセス可能

  • Schema Migrations
    EdgeDBではSchemaのマイグレーションをサポートしているので、言語/frameworkに関係なくマイグレーション可能

  • 堅牢なアーキテクチャ
    EdgeDBはPostgreSQL上に構築されており、ACID特性/パフォーマンス/信頼性という強みを継承しています。

ではEdgeDBをためしてみましょう。 

環境

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.12.6
  • Docker : 18.09.2

EdgeDBは現時点でalpha版なので動作が不安定になる場合があります。
なんかおかしいとおもったら再起動したりしてください。

setup

ここから自分の環境にあったEdgeDBをダウンロードしてインストールしてもいいのですが、
今回はDockerを使ってEdgeDBを動かしてみます。
EdgeDBのイメージを取得してrunして、コンテナにログインしましょう。

% docker pull edgedb/edgedb
% docker run --name edb -it --rm -p 5656:5656 -v <path/your/data_dir>:/var/lib/edgedb/data edgedb/edgedb

#コンテナにログイン
% docker exec -it edb /bin/bash
root@xxxxxx:/#

コンテナにログインしたら、最初にEdgeDBのAdmin用パスワードを設定します。

#パスワード設定
root@xxxxxx:/# edgedb --admin alter role edgedb --password

edgedbコマンドでシェルを起動します。
下記のように表示されれば準備完了です。

root@xxxxxx:/# edgedb -u edgedb
Password:
EdgeDB 1.0.alpha.1
Type "\?" for help.

edgedb> 

Try EdgeDB

では、EdgeDBのシェルを使っていろいろとコマンドを実行してみます。
まずはデータベースを作成しましょう。

edgedb> CREATE DATABASE my_edge;
CREATE

データベースが作成できたらそのデータベースを選択します。(mysqlのuseみたいな感じ)

edgedb> \c my_edge
my_edge>

次に、スキーマを定義します。
ここではEdgeDBの推奨するSDL(EdgeDB schema definition language)をつかって
スキーマを定義します。
※ SDL = EdgeDBスキーマの定義に使用される高水準言語

まずは新しいトランザクションブロックを開始します。
これを明示的にしなくてもコマンドが正常実行された場合は自動コミットされ、
エラー発生の場合はロールバックされるようです。

my_edge> START TRANSACTION;
START TRANSACTION

そしてスキーマのマイグレーションを行います。
ここでは、「companies」 というスキーマを作成してみましょう。
CREATE MIGRATIONは、
特定のモジュールに対する新しいスキーマのマイグレーションを定義します。
CREATE MIGRATION(とそれに続くCOMMIT MIGRATION)は、
トランザクションブロック内で実行する必要があるとのことです。

my_edge> CREATE MIGRATION companies TO {
........      type Company {
........          required property name -> str;
........          multi link member -> Person;
........      }
........      type Person {
........          required property name -> str;
........          property age -> int64;
........      }
........  };
CREATE MIGRATION

Company型とPerson型を定義し、
CompanyとPersonに1対多の関連(multi link member)をもたせています。

MIGRATIONが成功したらCOMMITしてトランザクションを完了します。

my_edge> COMMIT MIGRATION companies;
COMMIT MIGRATION
my_edge> COMMIT;
COMMIT TRANSACTION

スキーマができたら次はデータを登録してみましょう。
Companyとそれに関連する複数のPersonを同時に登録しています。
※以下のSDLも↑とおなじくシェルで実行してます

INSERT Company {
    name := 'Classmethod.inc',
    member := {
        (INSERT Person {
            name := 'taro',
            age := 20,
        }),
        (INSERT Person {
            name := 'hanako',
            age := 25,
        }),
        (INSERT Person {
            name := 'syuta',
            age := 30,
        }),
    }
};

#結果
{Object { id: <uuid>'24b33f22-5f90-11e9-b182-ff56b28985db' }}

SELECTをつかって会社情報を取得。

SELECT Company {
    name
};

#結果
{Object { name: 'Classmethod.inc' }}

少し条件を付与して検索してみます。
今度は会社名とそれに紐づくmember情報を取得します。
また、会社名でフィルタをかけています。

SELECT Company {
 name,
 member: {
  name,
  age
 }
}
FILTER .name ILIKE '%method%';

#結果
{
    Object {
        name: 'Classmethod.inc',
        member: {
            Object { name: 'taro', age: 20 },
            Object { name: 'hanako', age: 25 },
            Object { name: 'syuta', age: 30 }
        }
    }
}

memberの数をcountしたりもできます。

SELECT Company {
  name,
  num_members := count(Company.member)
};

#結果
{Object { name: 'Classmethod.inc', num_members: 3 }}

Updateはこんな感じです。

UPDATE Person
FILTER .name = 'taro'
SET {
    age := 50
};

SELECT Person {
  name,
  age
}
FILTER Person.name = 'taro';

# 結果
{Object { name: 'taro', age: 50 }}

EdgeQLでは他にもいろいろとできるので、公式ドキュメントで確認してみてください。
https://edgedb.com/docs/edgeql/overview

参考サイト