http://www.sqlite.org/withoutrowid.html WITHOUT ROWID 最適化について

SQLite は常に暗黙的な rowid カラムを持っていることになっている。これはカラムとして明示することもできるし、interger primary key として定義されたフィールドは暗黙的な rowid の代わりにすることができる。SQLite ではこの rowid が基本のプライマリキーになっている。

適当な数値をプライマリキーにしたい場合はこれで全く問題ないが、複合キーだったり文字列をプライマリキーにしたい場合、その表面上のプライマリキーとは別に rowid カラムができる。このケースでは表面上のプライマリキーを使って SELECT しようとすると、表面上のプライマリキーのインデックスを探したうえで、さらに rowid のインデックスを探すことになる。つまり、このケースのプライマリキーとは単に UNIQUE なインデックスでしかない。

そこそこ最近(3.8.2・2013年)からは WITHOUT ROWID をテーブル定義時に指定することで、暗黙的な rowid 生成を抑制して、プライマリキー指定した定義を「真のプライマリキー」とすることができる。

これによって

  • インデックスを辿る回数が減るのでパフォーマンスがあがる
  • 表面上のプライマリキー→rowid のインデックスがなくなるのでDBサイズが減る
  • インデックスが減るので挿入時の負荷が減る

と良いことがある。一方デメリットで気になるのは

  • 古い SQLite (3.8.2 より前) で該当DBを読もうとすると malformed database schema で怒られて読めない
  • sqlite3_last_insert_rowid() が使えない
  • インクリメンタルblob I/Oが使えない (大きなカラムを少しずつ読める低レベルな仕組み)
  1. トップ
  2. tech
  3. SQLite で「PRIMARY KEY」を《真のプライマリキー》とするには
▲ この日のエントリ