../surrealdb

SurrealDBのTutorialsをやってみる

SurrealDBはRustで書かれたdocument-graphなデータベース。GithubのRepo。初めてならGetting startedから始めろと言われたので、そこから始める。

Getting started

インメモリでデータベースを始めるには以下のようにする。

surreal start memory -A --user root --pass root

SurrealDBのクエリにはSurrealQLという言語を使う(スニペットに色がついていなくて申し訳ない)のだが、ここではそれのためのかっこいいGUIのSurrealistを使う。

左側五分の一程度の縦分割の画面とその他横分割の3つの画面です。横の上にはクエリが書ける場所があり下にはリザルトが出てくる場所があります
surreal start

以下のクエリを実行する。

CREATE account SET
  name = 'ACME Inc',
  created_at = time::now()
;

そうすると以下のようなJSONまがいなものJSONが出力される。

[
  {
    created_at: '2024-08-28T07:57:08.126Z',
    id: account:7tc1347h7y04vkxrv0v6,
    name: 'ACME Inc'
 }
]

上のクエリは、accountというテーブルに新しいレコードを作成するもの。(テーブルにはスキーマフルとスキーマレスがあるよう。)主キーのidは指定しなければランダムだが、table:idのように指定して発行することもできる。

CREATE author:john SET
  name.first = 'John',
  name.last = 'Adams',
  name.full = string::join(' ', name.first, name.last),
  age = 29,
  admin = true,
  signup_at = time::now()
;

また、table:idの形で指定することで、リンクできる(document-graph要素)。

CREATE article SET
  created_at = time::now(),
  author = author:john,
  title = 'Lorem ipsum dolor',
  text = 'Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.',
  account = (SELECT VALUE id FROM account WHERE name = 'ACME Inc' LIMIT 1)[0]
;

SELECTはSQLのように一つのテーブルから取得することも、複数のテーブルから指し示しているデータをまとめて取得することもできる。

画面の構成は上の画像と同じで、複数のテーブルからSELECTさせる文とその結果が書かれています
SELECT

DELETEはテーブルからレコードをREMOVEはレコード以外のものを削除するための文。

Tutorials

チュートリアルは複数用意されているようだが、今回は(ちょっとSQLライクに考えられる)Define a Schemaをやってみる。テーブルの定義とフィールドの作成は別。

DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD firstName ON TABLE user TYPE string;
DEFINE FIELD lastName ON TABLE user TYPE string;
DEFINE FIELD email ON TABLE user TYPE string
  ASSERT string::is::email($value);

string::is::emailが面白い。文字列のバリデーションのための関数(あとからもうちょい詳しくみたい)はstringのドキュメントのisモジュールの部分で見れる。かなり豊富。time::now()も関数。

レコードの追加について、ドキュメントは先ほどとは違い、CREATE table CONTENTを使っている。ドキュメントを見た限りCONTENTSETの違いは書き方だけのようだ。CONTENTはすでにJSONまたはSurrealQLの形式になっているときに便利と書いてあった。

CREATE user CONTENT {
    firstName: 'John',
    lastName: 'Doe',
    email: '[email protected]',
};

メールアドレスではない形で追加しようとすると怒られる。

CREATE user CONTENT {
    firstName: 'John',
    lastName: 'Doe',
    email: 'JohnDoe.com',
};

ちゃんと先ほど設定したASSERT string::is::email($value);が働いているようだ。

画面の構成は上の画像と同じで上のクエリを実行しようとした結果、Assertが失敗したとリザルト欄に書かれています
CREATE(失敗)

スキーマに存在しないフィールドを記載した場合は無視される。Tutorialsにはスキーマレスの方法も書かれていた。基本的にはGetting startedでやった通りなのだが面白いことをやっていた。意外となんでもレコードのIDにできるのだ。レコードのIDにできる型はTypes of Record IDsに書かれている。temperature:{ location: 'London', date: time::now() }のようにオブジェクトベースのIDも作れるようだ。 これは構造や責任範囲をちゃんと考えて作らないととんでもないことになりそうだ。

関数

組み込みの関数はドキュメントで見れるほか、v2からは匿名関数も作れるようになるようだ。HTTPリクエストを送ったり、SHA256を取ったりできる。

Futures

あとドキュメントを見ていたら、Futuresという機能もあった。挿入時ではなく、SELECTされてリターンされる時に計算される。例示されていたのは、現在が誕生日に18年足した日よりも遅いかを判定して成人を判定することができるみたいなものだった。

終わり

結構面白いDBだと思う。RustのSDKもある。見た感じ非同期やserdeなどを活かしてORM的な使い方もできるようになっていてけっこう使いやすそうだった。すべて正確な記述ができている自信がないので詳しくはドキュメントを見てみてほしい。かなり高機能な分、どのくらいの責任をDBに任せるのかはしっかり考える必要がありそうだ。

Tags /Database/