SQLite3のメモ
特徴
- SQL92の機能の多くを実装。トランザクション、ビュー、トリガーのサポートもあり。
- サーバではなくライブラリ。
- 要するにファイル。
- セットアップ不要。
- 設定ファイルがない。
などなど。
格納されるデータの型
以下のいずれかになる。
- NULL – NULL用
- INTEGER – 符号付整数。値の大きさに応じて1, 2, 3, 4, 6, 8 bytes で保存される。
- REAL – 浮動小数点数。8-byte IEEE floating point number。
- TEXT – 文字列。databaseの文字コードで保存される(UTF-8, UTF-16BE or UTF-16LE)。
- BLOB – バイナリ。そのまま保存。
Booleanはない。
Date、Time、Datetimeもない(数値か文字列で対応する)。
カラムの型
以下のいずれか。
- TEXT
- NUMERIC
- INTEGER
- REAL
- NONE
INTやBLOB、VARCHAR、CHARなどよそでよくある型を指定できるが、上のいずれかに読み替えられる(Type Affinity)。
NONEがもっともSQLiteらしいというか、何でもありなカラムの型。
カラムの型を指定しておくと、ある程度の変換がされる。ある程度。
INTEGERとNUMERICは何が違うのかというとほとんど一緒でCASTのときちょっと違う。
使ってみると
カラムの型を指定しなくてもまったく問題ない。何の補正もされないだけで、以下のようになる。
/* 型の指定なしでテーブルが作れる */ create table test1 (id, a, b); /* この3行、区別される */ insert into test1 (id, a) values (1, '整数'); insert into test1 (id, a) values ('1', '文字列'); insert into test1 (id, a) values (1.0, '実数'); /* 確認すると、INTEGER型とTEXT型とREAL型 */ select id, typeof(id) from test1; id|typeof(id) 1|integer 1|text 1|real /* 抽出の条件にも影響がある */ select id, a from test1 where id = '1'; id|a 1|文字列 select id, a from test1 where id = 1; id|a 1|整数 1|実数
カラムの型を指定したとしても、必ずその型になるわけではない。INTEGERを指定しても、なるべく整数にしてくれるだけで、文字列でもエラーなく格納される。型を指定したらMySQLのような挙動になるわけでもない。
/* 型の指定をしておくと */ create table test2 (id integer, a, b); /* このようにデータを入れた場合 */ insert into test2 (id) values (1); insert into test2 (id) values ('1'); insert into test2 (id) values (1.0); insert into test2 (id) values ('テストです'); /* 可能な限りINTEGER型にしてくれて、どうしようもないときそのまま */ select id, typeof(id) from test1; id|typeof(id) 1|integer 1|integer 1|integer テストです|text
各カラムの型に対して、各種のデータを格納しようとしたときの挙動。
CREATE TABLE t1( t TEXT, -- text affinity by rule 2 nu NUMERIC, -- numeric affinity by rule 5 i INTEGER, -- integer affinity by rule 1 r REAL, -- real affinity by rule 4 no BLOB -- no affinity by rule 3(型の指定なしと同じ) ); -- 文字列を格納すると INSERT INTO t1 VALUES('500.0', '500.0', '500.0', '500.0', '500.0'); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; text|integer|integer|real|text -- REALを格納すると DELETE FROM t1; INSERT INTO t1 VALUES(500.0, 500.0, 500.0, 500.0, 500.0); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; text|integer|integer|real|real -- INTEGERを格納すると DELETE FROM t1; INSERT INTO t1 VALUES(500, 500, 500, 500, 500); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; text|integer|integer|real|integer -- BLOBはいつでもBLOBで格納される DELETE FROM t1; INSERT INTO t1 VALUES(x'0500', x'0500', x'0500', x'0500', x'0500'); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; blob|blob|blob|blob|blob -- NULLはNULL DELETE FROM t1; INSERT INTO t1 VALUES(NULL,NULL,NULL,NULL,NULL); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; null|null|null|null|null
演算子
|| * / % + - << >> & | < <= > >= = == != <> IS IS NOT IN LIKE GLOB MATCH REGEXP AND OR
- + ~ NOT
関数
集計など基本的な関数はある。
データに日付型がないためか、日付計算関数もない。
now()もないのでdatetime()などを使う。
select date(), datetime(), time(); date()|datetime()|time() 2013-09-07|2013-09-07 17:36:59|17:36:59
php経由で使ってみると
以下のように、使い方に少々気をつける必要がありそう。
//create table test1 (id, a); $db = new PDO('sqlite:/tmp/db.sqlite3'); //数値のつもりでinsert文 $db->exec("insert into test1 (id, a) values (1, '数値のつもりでinsert文')"); //プリペアドステートメントで $s = $db->prepare("insert into test1 (id, a) values (?, ?)"); $s->execute(array('2', '文字列つもりで')); $s->execute(array(3, '数値のつもりで')); $s->execute(array(4.0, '実数のつもりで')); /* その後結果を確かめてみると select id, typeof(id) from test1; id|typeof(id)|a 1|integer|数値のつもりでinsert文 2|text|文字列つもりで 3|text|数値のつもりで 4|text|実数のつもりで */
コメント