SQLite FTSのcontent_rowid:整数化のメリット・デメリットと代替手段を比較

2024-06-28

SQLite における FTS における content_rowid が整数である必要がある理由

content_rowid は、FTS における各文書の固有 ID です。この ID は、検索結果を整理したり、文書を更新したりするために使用されます。

content_rowid が整数である必要がある 理由は以下のとおりです。

  1. 効率性: 整数は、浮動小数点よりもメモリと CPU の消費量が少なく、比較および計算が速くなります。FTS は大量の文書を処理する必要があるため、効率的なデータ構造を使用することが重要です。
  2. 一意性: content_rowid は、各文書の一意の識別子である必要があります。整数を使用すると、重複する ID を簡単に回避できます。
  3. 整合性: content_rowid は、他の SQLite テーブルの主キーと一致する必要があります。多くの場合、主キーは整数型であるため、content_rowid も整数型にする必要があります。

content_rowid が整数であることの利点

  • 検索結果の高速化
  • メモリと CPU の使用量の削減
  • データベースの整合性の向上
  • 文書の数が非常に多い場合、大きな整数を扱う必要が生じる可能性があります。
  • 整数以外の ID を使用したい場合は、独自の ID 管理システムを実装する必要があります。

FTS における content_rowid は、検索結果の整理、文書の更新、およびデータベースの整合性のために使用される重要な識別子です。content_rowid が整数である必要がある理由は、効率性、一意性、および整合性です。




    CREATE TABLE tbl (
      a TEXT NOT NULL PRIMARY KEY
    );
    
    CREATE VIRTUAL TABLE fts USING fts5(
      a,
      content=tbl,
      content_rowid=guid
    );
    
    INSERT INTO tbl (a) VALUES ('This is a text document.');
    INSERT INTO tbl (a) VALUES ('Another text document.');
    
    SELECT * FROM fts WHERE a MATCH 'document';
    

    このコードは、以下のことを行います。

    1. tbl という名前のテーブルを作成します。このテーブルには、a という名前のテキスト列があります。
    2. fts という名前の仮想テーブルを作成します。このテーブルは、FTS を使用して a 列を全文検索することができます。
    3. tbl テーブルに 2 つの文書を挿入します。
    4. a 列に "document" という単語が含まれる文書をすべて選択します。

    このコードを実行すると、以下の結果が表示されます。

    rowid | a
    -------+--------
    1      | This is a text document.
    2      | Another text document.
    

    この例では、content_rowid 列は自動的に生成されます。ただし、独自の content_rowid 列を作成することもできます。

    CREATE TABLE tbl (
      a TEXT NOT NULL PRIMARY KEY,
      rowid INTEGER NOT NULL UNIQUE
    );
    
    CREATE VIRTUAL TABLE fts USING fts5(
      a,
      content=tbl,
      content_rowid=rowid
    );
    
    INSERT INTO tbl (a, rowid) VALUES ('This is a text document.', 1);
    INSERT INTO tbl (a, rowid) VALUES ('Another text document.', 2);
    
    SELECT * FROM fts WHERE a MATCH 'document';
    

    このコードは、上記のコードと同じ結果を生成します。

    補足

    • このコードは、SQLite 3.8.2 以降で使用できます。
    • FTS は、多くの全文検索エンジンよりも高速で効率的です。
    • FTS は、テキスト列、BLOB 列、および仮想テーブルを検索に使用できます。

    FTS について詳しくは、SQLite のドキュメントを参照してください。




    FTS における content_rowid の代替方法

    カスタム ID 管理システムを使用する

    独自の ID 管理システムを実装することで、content_rowid に整数以外の値を使用することができます。この方法は、content_rowid に UUID やその他のランダムな値を使用したい場合に役立ちます。

    CREATE TABLE tbl (
      a TEXT NOT NULL PRIMARY KEY,
      uuid UNIQUE NOT NULL DEFAULT (uuid_gen_random())
    );
    
    CREATE VIRTUAL TABLE fts USING fts5(
      a,
      content=tbl,
      content_rowid=uuid
    );
    
    INSERT INTO tbl (a) VALUES ('This is a text document.');
    INSERT INTO tbl (a) VALUES ('Another text document.');
    
    SELECT * FROM fts WHERE a MATCH 'document';
    

    FTS5 以外の全文検索エンジンを使用する

    これらのエンジンを使用するには、それぞれのドキュメントを参照してください。

    注意事項

    • カスタム ID 管理システムを使用する場合は、content_rowid と文書ID の間のマッピングを維持する必要があります。
    • FTS5 以外の全文検索エンジンを使用する場合は、FTS5 と同じ機能を提供しない場合があります。

    content_rowid が整数である必要があるという制限を回避するには、いくつかの方法があります。どの方法を使用するかは、ニーズと要件によって異なります。


    sqlite


    INTEGER型とTINYINT型でブール値を格納

    ブール値 は、真偽を表す値であり、SQLite では以下の方法で格納できます。INTEGER 型として格納0 は FALSE1 は TRUE例:INTEGER 型とほぼ同じですが、TINYINT 型は 1 バイトのみ使用するため、メモリ使用量を抑えられます。...


    AndroidにおけるSQLiteの外部キー制約とON DELETE CASCADE

    ON DELETE CASCADEオプションは、親テーブルのレコードが削除された時に、子テーブルの関連レコードも自動的に削除する機能を提供します。このオプションは、データの整合性を保ち、複雑なSQLクエリを避けるのに役立ちます。例えば、ユーザーテーブルと注文テーブルがあるとします。注文テーブルには、ユーザーID列があり、ユーザーテーブルのID列を参照します。この場合、ユーザーテーブルからユーザーを削除すると、注文テーブルからそのユーザーに関連するすべての注文も自動的に削除されます。...


    1 行のクエリ結果をタブ区切りで出力

    方法 1: .mode コマンドを使用するSQLite コマンドラインツールを開き、データベースファイルを指定します。以下のコマンドを実行して、出力モードを "line" に変更します。クエリを実行します。クエリ結果はタブ区切りで出力されます。...


    【図解あり】SQLiteにおける外部キー制約:サンプルコードで分かりやすく解説

    SQLiteは軽量で使い勝手の良いデータベースとして人気がありますが、バージョン3. 6.19以前では外部キー制約をサポートしていませんでした。外部キー制約は、リレーショナルデータベースにおいてデータの整合性を保つために重要な機能です。しかし、SQLite 3.6.19以降では、外部キー制約をサポートするようになりました。...