プログラマのためのSQL
https://www.seshop.com/static/images/product/15685/L.png
うるう年
数値型拡張
MONEY型
文字列型
WITH
クエリの先頭で使い、ビューを定義
そのクエリ限定で利用できるビュー
永続的かどうか
COMMITが成功した時に永続化される、ROLLBACKをすればトランザクション開始前に戻る
トレードオフ
数万件のINSERTのうち1件だけ整合性違反があってもすべてROLLBACKするか
細かくトランザクションを分割するか
セッション終了時点で一貫性が保たれていればよい
トランザクションは他のトランザクションから独立していること
直列で実行した時と同じ結果になること
一貫した状態に復元できること
複数のユーザーが1つのデータベースで干渉しあわずに利用する(トランザクションを実行する)にはどうすればよいか
一度に1人ずつ使えば干渉しない…とはいうものの
同時に使いたい
検索のみなら複数人で同時に利用してもACID特性は保たれる
更新が入ると注意しなければならない
1つのトランザクションが別のトランザクションに影響を与えるパターンが5つある
同時実行されたトランザクションの干渉度合いの定義
デフォルト
トランザクションの衝突は起こるものとしての制御方針
問題が起こる前に回避
使用前に必ずロックする
粒度の高いロックが増えてコストが高いと判断されると、ロック粒度を自動的に上げる
問題が起きてから解決
キャラクタセット
自動インクリメント列をキーとして使う
値が妥当かどう検証するか?
いわゆる「試験環境」「本番環境」「開発環境」
述語
述語論理
真理値を戻り値とする関数
標準SQLはすべてのデータ型にNULLを許容しなければならない NULLに相当するブール値にUNKNOWN
IPアドレスをどう格納するか
CHAR(39)
4桁 * 8個とコロン7個
バイナリ形式
SMALLINT
だが、ベンター依存も多い
DATE
TIME
DAY
HOUR
MINUTE
SECOND
文字列型
CHARACTER(n)、CHAR(n)が実装されたのはSQL-89 VARYING CHARACTER(n)、VARCHAR(n)が実装されたのはSQL-92 1~n個までの印字可能な文字
NATIONAL CHARACTER(n)、NVARCHAR(n)が実装されたのはSQL-92 Unicodeの印字可能な文字を格納する
NULLはNULLが現れる列の行に余計なビットフラグを持つことで実装されている
「永久」や「最大期間」は9999-12-31という文字列で表現していた
DELETE
WHEREなしのDELETEを実行しようとすると本当にやってよいか確認してくるDBMSもある そうなんだっけ?
テーブルに対する削除の順序
1. WHERE句の条件に合致する行に削除フラグを立てる
制約違反があればロールバック
2. 実際に削除する
ユーザーから非表示にしておいて、後でクリーンアップ、インデックス再編成するケースもあるらしい
UPDATE
条件にあった行は、個別にではなく1つの部分集合としてマークされる
部分集合はテーブルから削除され、新たな行が挿入される
そうなの?
更新対象が0行でも妥当な更新とみなす
19.1 文字列パターンのトリック
だが、これは次のように書いた方が早い。
マジで?
文字列は常に左から右へパースする
オプティマイザはORのコードにはWHERE句の述語を別々に扱うが、IN述語の場合はひとまとまりにして扱う IN述語のコードはインデックスが使えなくなる可能性がある
39.5 IN述語には要注意