テーブルの生成・削除。
成果物
一覧
create table
create temp table
create table if not exists
create table 名 as select ...
create table (...) without rowid
drop table
drop table if exists
create table
0.sql
create table T( A integer, -- 整数 B real, -- 不動小数 C numeric, -- 数値 D text, -- 文字列 E blob -- バイナリ ); select sql from sqlite_master;
create temp table
スキーマ名temp
にテーブルを作成する。
temp
1_temp.sql
create temp table T( A integer, -- 整数 B real, -- 不動小数 C numeric, -- 数値 D text, -- 文字列 E blob -- バイナリ ); .echo on .databases select sql from sqlite_master; select sql from main.sqlite_master; select sql from temp.sqlite_master; .echo off
temporary
1_temporary.sql
create temporary table T( A integer, -- 整数 B real, -- 不動小数 C numeric, -- 数値 D text, -- 文字列 E blob -- バイナリ ); .echo on .databases select sql from sqlite_master; select sql from main.sqlite_master; select sql from temp.sqlite_master; .echo off
create table if not exists
2.sql
create table T(A integer); create table if not exists T(A integer); select sql from sqlite_master;
CREATE TABLE T(A integer)
エラーにならない。
エラーになる
if not exists
せずに同名のテーブルをcreate
しようとするとエラー。
2_error.sql
create table T(A integer); create table T(A integer);
Error: near line 2: table T already exists
create table 名 as select ...
3.sql
.echo on create table T as select 1, 0.1, 'A', x'FF'; select sql from sqlite_master; .headers on select * from T; .echo off
create table T as select 1, 0.1, 'A', x'FF'; select sql from sqlite_master; CREATE TABLE T("1","0.1","'A'","x'FF'") .headers on select * from T; 1|0.1|'A'|x'FF' 1|0.1|A|� .echo off
型はアフィニティによって決まる。よくわからん。
create table (...) without rowid
4.sql
create table T( A integer primary key ) without rowid; select sql from sqlite_master;
SQLite3固有。without rowid
にするとクラスタ化インデックスになる。これは指定した主キーをソートして、その順に取り出すときに高速化する。つまり主キーが必須になる。
主キーの自動挿入不可
4_0.sql
create table T( A integer primary key, B text ) without rowid; insert into T(B) values('A'); select * from T;
Error: near line 5: NOT NULL constraint failed: T.A
クラスタ化インデックス
クラスタ化インデックスは辞書順にソートすることに意義がある。よって主キー値はランダムな数値でなく、ユーザが考慮して値をセットすべき。だからエラーが出るのは妥当。なのだと思う。たぶん。
だが、残念なお知らせがあった。without rowid
テーブルの1レコードあたりのサイズは、データベースページのサイズの約1/20未満にする必要があるという。
試しに私の環境でデフォルトのページサイズを確認してみた。
pragma page_size;
4096
設定は以下のようにする。
pragma page_size = 4096;
ただし、ページサイズは512
〜65536
の間で、かつ2のn乗にする必要がある。
たとえばページサイズ4KiBのときは4096B/20=204.8B
で約204
Byteまで。1列でなく1行のサイズが、だ。少なすぎる。使い物にならない。
SQLite3がデフォルトで使用する文字セットはUTF-8である。UTF-8で日本語を使ったとき、ほとんどの場合は1文字は3Byteである。ただし4,6,8Byteになる場合もある。204/3=68
文字。なんと、1行あたり68文字分のデータしか入れられない。つぶやきさえ入らない。しかも主キーも合わせたサイズ。
どんなときに有効か?
たとえば.param init
ドットコマンドで作成されるsqlite_parameters
テーブルはwithout rowid
である。これはkey
とvalue
列のみ。1行あたり少ないデータになるだろうし、主キーであるkey
を辞書順にソートするのも一定の価値がありそう。こういうときに使うのだろう。
あとはマジックナンバーに名前を付けるときとか? C言語の#define
プリプロセッサ的な。
drop table
5.sql
create table T(A integer); drop table T; select sql from sqlite_master;
何も出ない。テーブルは削除された。
drop table if exists
6.sql
create table T(A integer); drop table T; drop table if exists T; select sql from sqlite_master;
何も出ない。テーブルは削除された。エラーも出ない。
エラーになる
存在しないテーブルを削除しようとするとエラーになる確認。
6.sql
create table T(A integer); drop table T; drop table T; select sql from sqlite_master;
Error: near line 3: no such table: T
削除するときはif exists
をつけたほうがいい。
他
テーブル作成において、他にも関係するものが多数ある。
所感
次回以降、他の要素についてやる。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- SQLite 3.29.0
- MeCab 0.996ユーザ辞書
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux
前回まで
- SQLite3学習 俯瞰まとめ
- SQLite3学習 環境構築まとめ
- SQLite3学習 インタフェースまとめ(C言語、CLI、対話モード、Tcl...)
- SQLite3学習 ドットコマンドまとめ
- SQLite3学習 JSON拡張まとめ
- SQLite3学習 FTSまとめ(ICU, MeCab)
- SQLite3学習 再帰クエリ(WITH RECURSIVE)
- SQLite3学習 R-Treeモジュール
- SQLite3学習 Geopoly(2次元ベクタ画像の生成)
- SQLite3学習 拡張関数(generate_series)
- SQLite3学習 拡張ライブラリ数学関数(extension-functions.c)
- SQLite3学習 謎と名前
- SQL文の分類(DDL,DML,TCL,DCL)
- SQL構文 alter(rename)
- SQL構文 alter(add column)概要
- SQL構文 alter(add column)制約
- SQL構文 alter(add column)sqlite_master変更しても反映されない
- SQL構文 alter(add column)スキーマ再定義(テーブル再作成による定義変更)
- SQL構文 analyze
- SQL構文 attach/detach
- SQLite3構文 begin,end,commit,rollback,savepoint(deferred,immediate,exclusive)
- SQLite3構文 コメント
- SQLite3構文 create/drop
- SQLite3構文 index(create/drop)