graphics.hatenablog.com

技術系テクニカルアーティストのあれこれ

テクニカルアーティストのためのデータベース入門 (6) テーブル制約

前回の続き。DBの中身をきれいに保つための設定集。
f:id:hal1932:20161010165611p:plain

graphics.hatenablog.com

データを記録するときのルール設定

間違ったデータがDBの中にはいらないようにするための設定。

not null

空っぽのデータを保存しようとしたらエラーにするルール。

たとえば冒頭の図だと、textures.width と textures.height に not null がついてるけど、これは、「テクスチャは画像、画像には必ず幅と高さが必要」というルールが設定されていることになる。幅と高さは、テクスチャにとって必須の属性である、と。

基本的には、その項目がないとデータのまとまりとして意味をなさないときに使う。

unique

テーブル内の他のデータと重複する値を保存しようとしたらエラーになるルール。

たとえば冒頭の図だと、files.path に unique がついてるけど、これは、「同じパスのファイルは1個しか記録できない」というルールが設定されていることになる。たとえば非金属モデルのメタルネスに真っ黒な共通テクスチャを割り当てる場合なんかでも、その共通テクスチャの ID を複数のモデルに設定すればいいだけで、モデル側と 1 対 1 にするために同じテクスチャデータを何個も登録してやる必要はない。あとは、違うモデルに同じ名前がついてるとプログラム的に困る場合なんかは、models.name を unique にして事故防止のために使うこともできる。

同じ内容のデータが何個もあっても意味がないときや、重複するとトラブルにつながるようなときに使う。

auto increment

ルールというよりも便利機能。重複しない数値を自動で割り当ててくれる。

例えば冒頭の図だと、各テーブルの id にこれがついてる。files に記録されてる各データに通し番号が降ってあれば、models にその番号を記録することで、どのモデルがどのファイルに紐付いてるかを特定できる。「識別子」ともいう。

数値自体に意味はないけどとにかく唯一の数値を割り当てておきたい、みたいなときに使う。

primary key

ルールというよりも目印に近い。日本語でいうと主キー。機能的には not null と unique を足したようなもの。

例えば冒頭の図だと、各テーブルの id にこれがついてる。そのテーブルの中で、すべての項目に割り当てられた唯一の ID に使う。つまり「識別子」で、例えば「1番のモデル」「3番のテクスチャ」みたいに、それぞれのデータを識別するための通し番号。そういう役割なので、auto increment と一緒に使われることがとても多い。

このテーブルにあるデータを識別するための ID はこれですよ、という目印のために使う。

テーブルをまたぐデータの整合性

片方のデータが変わったときに、もう片方のデータも自動で変えてもらうための設定。外部キーともいう。

片方が更新されたときの挙動を update に、削除されたときの挙動を delete に設定しておく。例えば references textures.id on update cascade on delete set null だと、textures.id が更新されたときに cascade という操作を、削除されたときに set null という操作を、データベースエンジンが自動で行ってくれる。

set null

その名のとおり null を設定する。

冒頭の図では、textures の file_id に references file.id on delete set null が設定されてる。これは、file の id が削除されたら textures の file_id を自動で null にする、というもの。primary key が設定された項目が削除されるというのは、その id を持つデータ自体が削除されるということ。つまり、テクスチャは file_id を通じてファイルを参照しているけど、ファイルが削除されたらその参照を自動で切ってしまう。

もっとも、「ファイル的に存在していないテクスチャ」なんてものに意味があるかどうかは微妙なところで、もしかしたら、ファイルが削除されたらテクスチャのほうも消してしまったほうがいいかもしれない。そういうときは on delete cascade を使うようにする。

cascade

cascade は日本語でいうと「次に繋げる、連鎖させる」という意味、つまり、片方に対して行われた変更を、もう片方にも連鎖させる。

冒頭の図では、model_texture_maps の model_id に references models.id on update cascade on delete cascade が設定されてる。これは、models の id が更新されたら、それにあわせて model_id も更新後してしまう。削除されたら、そのモデルを参照しているデータ自体を消してしまう。

model_texture_maps というのは、その名の通り、「モデルとテクスチャの対応表」として使われる。モデル1とテクスチャ2が紐付いてる、みたいな。対応表なのだから、片方が消えてしまってはデータとしての意味がない。だから消してしまおう、というもの。

restrict

restrict は日本語では「制限する」という意味になる。つまり、片方のデータの更新や削除に対して制限を加えるための機能。

冒頭の図では使ってないけど、例えば model_texture_maps の texture_id に references texture.id on delete restrict を設定すると、model_texture_maps の texture_id に対応する textures のデータを削除できなくなる。どういうことか。model_texture_maps はモデルとテクスチャの対応表なのだから、model_texture_maps に id が書き込まれているということは、そのテクスチャはモデルから参照されている、ということになる。というわけで、「モデルから参照されているテクスチャは削除できない」という制限がかかることになる。

以上、ERの説明はここまで。