7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 14

ElixirでACID対応の軽量ファイルベースデータベース: CubDB v2.0

Last updated at Posted at 2024-12-11

はじめに

Nervesでファームウェアを構築していると、時々「データを保存しておきたい」と思う場面が出てきます。そんなときに役立つのが、ファイルベースのシンプルなデータベース CubDB v2.0 です。

CubDB v2.0 の特徴

  • 簡単で柔軟: ファイルベースのデータベースで、初心者でも理解しやすい API を提供。
  • ACID トランザクション対応: データの整合性を保証し、安全な操作が可能。
  • MVCC (マルチバージョン同時実行制御): 複数のプロセスが同時にデータを操作しても、衝突なく処理可能。
  • 新しい機能:
  • 堅牢性: 不意のクラッシュや障害時でもデータを保護。
  • 軽量設計: 外部のデータベースサーバーが不要で、小規模プロジェクトやNervesデバイスにも最適。

CubDB v2.0 と DETS の比較

以下の表では、CubDB v2.0 と Erlang 標準の DETS の違いを比較しています。それぞれの特徴を知ることで、どちらが特定の用途に適しているか判断しやすくなります。CubDB は Elixir で書かれたファイルベースのデータベースで、ACID トランザクションやスナップショット機能がサポートされています。一方、DETS は Erlang 標準のデータベースで、CubDB に比べるとシンプルですが制限も多いです。

特徴 CubDB v2.0 DETS
言語 Elixir で実装 Erlang で実装
ACID 対応 されている されていない
データ要害防止 中断の地点でも安全 安全性に制限あり
スナップショット 便利な API を提供 サポートされていない
メンテナンス性 活発なメンテナンスとコミュニティ メンテナンス減少中

公式 FAQ では CubDB と他のデータベースとの比較 も紹介されています。

IEx で CubDB を使ってみる

インストールして開始

# cubdbをインストール
Mix.install([:cubdb])

# データの保存先とプロセス名を指定してcubdbサーバーを起動
data_dir = Path.join(System.tmp_dir!(), "database")
{:ok, db} = CubDB.start_link(data_dir: data_dir)

データの操作

CubDB.put(db, :feeling, "awesome")
#=> :ok

CubDB.get(db, :feeling)
#=> "awesome"

CubDB.delete(db, :feeling)
#=> :ok

CubDB.get(db, :feeling)
#=> nil

トランザクション

CubDB.put(db, :number, 123)
#=> :ok

CubDB.put(db, :word, "元氣")
#=> :ok

CubDB.transaction(db, fn tx ->
  number = CubDB.Tx.get(tx, :number)
  word = CubDB.Tx.get(tx, :word)

  tx = CubDB.Tx.put(tx, :number, word)
  tx = CubDB.Tx.put(tx, :word, number)

  {:commit, tx}
end)
#=> :ok

CubDB.get(db, :number)
#=> "元氣"

CubDB.get(db, :word)
#=> 123

Nerves ファームウエアに搭載

cubdbを依存関係リストに追加して、mix deps.getコマンドでインストール。

mix.exs
  defp deps do
    [
      {:cubdb, "~> 2.0"},
    ]
  end

アプリ起動時にcubdbサーバーを起動する。

lib/hello_nerves/application.ex
defmodule HelloNerves.Application do
  @moduledoc false

  use Application

  def start(_type, _args) do
    opts = [strategy: :one_for_one, name: HelloNerves.Supervisor]

    children = [
      {CubDB, [
        # Nervesで書き込める場所`/data`配下の任意のディレクトリーを指定
        data_dir: "/data/database",
        # CubDBプロセスに名前をつける
        name: HelloNerves.Database]}
    ]

    Supervisor.start_link(children, opts)
  end
end

同じデータディレクトリで複数の CubDB プロセスを起動しないようにしてください。1 つのデータディレクトリには、必ず 1 つの CubDB プロセスだけを使用してください。詳細については、公式ドキュメントをご覧ください。

後は IEx での試運転同様に Nerves ファームウエアで自由に読み書きできます。

:tada::tada::tada:

おわりに

CubDB v2.0 は、Elixir 開発者にとって便利な選択肢だと思います。
まだ試していない機能も多いので、ぜひ皆さんにも試していただき、フィードバックをいただければと思います。

toukon-qiita-macbook_20230912_091808.jpg

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?