SQLiteでは、主キーカラムが INTEGER型の場合、ROWID のエイリアスになるという特徴があります。
ROWIDのエイリアスになると次の動作をします。
1. 主キー列に登録した値 = ROWID値
2. 主キー列にもROWIDの制約がかかる
以下では、それぞれの動作を検証します。
検証1. 主キー列に登録した値 = ROWID値
検証では簡単に次のテーブルを使用します。ID列が INTEGER型の主キー列です。
1 2 3 4 |
create table test ( ID INTEGER PRIMARY KEY, NAME TEXT ); |
このテーブルに一行登録します。
1 |
insert into test ( ID, NAME ) values ( 100 , 'Aさん' ); |
追加したデータを取得すると、次のように ROWID と ID が同じ値になっています。
1 2 |
sqlite> select ROWID, ID, NAME from test; 100|100|Aさん |
また、ID を 200 で更新すると、ROWID も同じ値になります。
1 2 3 |
sqlite> update test set ID = 200 where ID = 100; sqlite> select ROWID, ID, NAME from test; 200|200|Aさん |
逆に ROWID の値を300 で更新した場合も、ID の値も同じ値に更新されていることが分かります。
1 2 3 |
sqlite> update test set ROWID = 300 where ID = 200; sqlite> select ROWID, ID, NAME from test; 300|300|Aさん |
このことから、INTEGER型の主キー列 が ROWID のエイリアスになっていることが分かります。
検証2. 主キー列にもROWIDの制約がかかる
ROWIDの制約とは、登録できる最大整数 が 9223372036854775807 になるという点です。
あまりないケースかも知れませんが、主キー列にも同じ制約がかかることを知っていて損はないと思います。
検証1 と同じテーブルに ROWID が登録できる最大整数と同じ値を ID に登録します。
1 2 3 |
sqlite> insert into test ( ID, NAME ) values ( 9223372036854775807 , 'Bさん' ); sqlite> select ROWID, ID, NAME from test where ID = 9223372036854775807; 9223372036854775807|9223372036854775807|Bさん |
無事に登録することができました。
次に、最大整数 +1 の 9223372036854775808 を ID に登録します。
1 2 |
sqlite> insert into test ( ID, NAME ) values ( 9223372036854775808 , 'Cさん' ); Error: datatype mismatch |
残念ながら、ROWID の制約でエラーになってしまいました。
ちなみに、INTEGER列 でも 主キー制約がない場合、ROWID の制約に縛られないため、次のように最大整数を超える値も登録することができます。
1 2 3 4 |
create table test2 ( ID INTEGER, NAME TEXT ); |
1 2 3 |
sqlite> insert into test2 ( ID, NAME ) values ( 9223372036854775808 , 'Cさん' ); sqlite> select ROWID, ID, NAME from test2; 1|9.22337203685478e+18|Cさん |