C#でLiteDBを永続Dictionaryとして使う ― SSDを非揮発疑似メモリとして使う ―

コンピュータ

以前書いた基礎記事:
https://maywork.net/computer/cshap-litedb/
では、LiteDBの基本的な使い方を紹介しました。

今回は少し視点を変えて、
LiteDBを「永続Dictionary」=SSD上の疑似メモリとして使う
という発想で整理してみます。

1. LiteDBは「永続Dictionary」である

例えば次のコード。

_db = new LiteDatabase(dbPath);
_collection = _db.GetCollection<Entry>("kv_" + typeof(TValue).Name.ToLower());
_collection.EnsureIndex(x => x.Key, true);

これは実質、以下を意味します。

  • GetCollection:コレクション(≒テーブル)を取得(存在しなければ自動作成)
  • EnsureIndex:インデックスが無ければ作成(2回目以降は基本的に何もしない)
  • true:ユニーク制約(Key重複禁止)=主キー的な扱い

中身の型は例えばこういうイメージです。

public class Entry
{
    public string Key { get; set; }
    public TValue Value { get; set; }
}
要点
構造的には Dictionary<string, TValue> に非常に近い(ただし保存先がSSDで、アプリ終了後も残る)。

2. メモリ階層として考える

現代のPCでは、ストレージは明確な階層構造になっています。

速度 揮発性 ざっくり用途
CPUキャッシュ 超高速 揮発 極小・超頻出
RAM 高速 揮発 作業領域(高速)
SSD 中速 非揮発 永続・高速I/O
HDD / NAS 低速 非揮発 アーカイブ・大容量

LiteDBはこの中で、SSDをアプリレベルで扱うメモリ層として機能します。
つまり「RAMとHDD/NASの間」のレイヤーを作れるイメージです。

Memory Dictionary (RAM)
        ↓
LiteDB (SSD)
        ↓
元データ(HDD/NASなど)

RAMにあれば即返す、無ければSSD(LiteDB)から読む、それも無ければ再生成…
という二層キャッシュ構造が自然に組めます。

3. 単なるKVSとの違い

Dictionaryは基本的に「Keyで引く」ことが中心ですが、LiteDBはドキュメントDBなので
Value内部に対しても検索できます。

var results = _collection.Find(x => x.Value.Age > 20);

「Key-Valueとして扱える」のに「Valueで条件検索できる」。
この二面性が、単純な永続KVSより便利なポイントです。

4. オブジェクトをそのまま保存できる

LiteDBはBSONを使うため、.NETのPOCOであれば比較的そのまま保存できます。
例えば以下のような要素が扱いやすいです。

  • ネストしたオブジェクト
  • List<T> などのコレクション
  • Dictionary / Enum / DateTime

RDBのようにテーブル設計を意識せずに、まず「C#の型」を中心に組めるため、
個人ツール・小規模アプリでは設計がかなり楽になります。

5. SSDを疑似メモリとして使うという発想

SSDはRAMよりは遅いものの、現代の環境では十分高速です。
その結果、
巨大で電源断でも消えないDictionaryとして実用的に扱えます。

特に、次のような用途に向いています。

  • 画像メタ情報(サイズ、DPI、ハッシュ、タグ等)の保存
  • サムネイルキャッシュの管理(キー → パス/状態)
  • 処理済みフラグ管理(変換済み、OCR済み、エラー履歴など)
  • 「一度計算したら次回は引くだけ」にしたい結果のキャッシュ
使い方のコツ
大きいバイナリ(画像そのもの等)は別ファイルで持ち、LiteDBには
「キー・メタ情報・パス・状態」など“管理情報”を置くのが扱いやすいです。

6. 注意点

  • 書き込み頻度が極端に高い設計はSSD寿命に影響し得る(ログ的な連続書き込みは要設計)
  • 巨大オブジェクトの頻繁なUpsertはコスト増になりやすい(粒度を小さく)
  • トランザクションは便利だが、常用しすぎるとオーバーヘッドになる場合がある

目的は「RAMの代替」ではなく、「RAMでは持ちきれない量を、アプリ側で制御しながら永続化して引ける層」を作ること。
つまり“疑似非揮発メモリ”としての運用が最適です。


まとめ

LiteDBは軽量NoSQLというだけでなく、
SSDをアプリレベルで扱う非揮発メモリ層として使えます。

  • Dictionary感覚で使える
  • 永続化される
  • Valueでも検索できる
  • テーブル設計より「C#の型」中心で組める

個人ツールや小規模アプリでは、SQLiteより自然にハマるケースも多いはずです。

コメント