導入
「価格にマイナスは入れさせたくない」「在庫を省いたら 0 にしておきたい」。列に入る値の中身そのものにルールを付けられるのが、CHECK 制約と DEFAULT です。アプリで毎回チェックする代わりに、DB を最後の砦にします。
説明
CHECK ― 条件を満たす値だけ許す。CHECK (条件) を列に付けると、その条件が真になる値しか入りません。
price INTEGER NOT NULL CHECK (price >= 0)
初期表示の最後の INSERT(価格 -50)は、CHECK (price >= 0) に反するのでエラーになり、入りません。
DEFAULT ― 省いたときの初期値。DEFAULT 値 を付けると、INSERT でその列を省略したとき、自動でその値が入ります。上の stock INTEGER NOT NULL DEFAULT 0 なら、在庫を書かずに入れた鉛筆は stock が 0 になります。
flowchart TB
C["CHECK (price >= 0)<br/>→ ルール違反の値は入れない"]
D["DEFAULT 0<br/>→ 省略したら 0 を入れる"]
NOT NULL(空を許さない)・UNIQUE(重複を許さない)・CHECK(条件)・DEFAULT(既定値)――これらを組み合わせて、「そのテーブルに入ってよいデータの形」を宣言します。制約は多いほど堅牢ですが、厳しすぎると運用しづらいので、業務ルールに合わせて選びます。
やってみよう
初期表示のコードを実行し、鉛筆(正常)は入るが、価格 -50 の不良品で CHECK constraint failed のエラーが出ることを確認しましょう。次に SELECT * FROM product2; で、鉛筆の stock が(省略したのに)0 になっていることも見てください。DEFAULT が効いています。
演習
score というテーブルを作ってください。列は id(主キー)、name(TEXT)、point(INTEGER、0 以上 100 以下だけを許す CHECK、既定値 DEFAULT 0)。
ヒント1を見る
範囲は CHECK (point >= 0 AND point <= 100) と書けます。既定値は DEFAULT 0。
ヒント2を見る
CREATE TABLE score (id INTEGER PRIMARY KEY, name TEXT, point INTEGER DEFAULT 0 CHECK (point >= 0 AND point <= 100));