はじめに
有名なあの本を読んだ備忘録です。
ありふれた内容ですが、こんな記事いくらあってもいいですからね!
1章 ジェイウォーク(信号無視)
概要
一つの列に複数の値をもたせるのはやめましょう。
product_id | product_name | account_id |
---|---|---|
1 | table | 123, 456 |
2 | chair | 456, 789 |
対策
2章 ナイーブツリ-(素朴な木)
別途
3章 IDリクアイアド(とりあえずID)
概要
主キー名はわかりやすく命名しましょう。
また、必ずしもid列は必要ありません。
対策
例えば、交差テーブルの主キーは複合キーをつかう。
create table Contacts (
product_id bigint unsigned not null,
account_id bigint unsigned not null,
foreign key (product_id) references Products(product_id),
foreign key (account_id) references Accounts(account_id),
primary key (product_id, account_id)
);
4章 キーレスエントリ(外部キー嫌い)
概要
外部キー制約を使って参照整合性を担保しましょう。
キーレスエントリでは柔軟性が高まりますが、さまざまな代償が伴います。
5章 EAV (Entity Attribute Value)
概要
汎用的な属性テーブルを使用するのはやめましょう。
issue_id | attr_name | attr_value |
---|---|---|
1 | severity | 5 |
2 | sponsor | example_inc |
3 | status | NEW |
対策
- 半構造化データに対してはNoSQLを使いましょう
- 例えば下記のようなサブタイプのモデリングを行いましょう
「クラステーブル継承」の例
Bugs
とFeatureRequest
はIssues
を継承しています。
メモ
blob, clob, text型などをLOB(Large Object)という。
処理が重くなりがちなので基本避ける。
Jsonなどの半構造化データはこの型をつかう。
6章 ポリモーフィック関連
概要
一つのエンティティに対して、複数の親を設定するのはやめましょう。
2つ以上の親に対して外部キーを設定できないからです。
対策
7章 マルチカラムアトリビュート (複数列属性)
概要
複数の列を定義するのはやめましょう。
product_id | product_name | tag1 | tag2 | tag3 |
---|---|---|---|---|
1 | table | white | NULL | NULL |
2 | chair | NULL | long | NULL |
3 | paper | NULL | NULL | 100 |
対策
従属テーブルを作成する。
上の例で言うと、tagを新たなテーブルとして作成し、productテーブルから参照させます。
8章 メタデータドリブル(メタデータ大増殖)
概要
スケーラビリティを求めて、内容の同じテーブルや列をコピーするのはやめましょう。
create table Bugs_2008 (...);
create table Bugs_2009 (...);
create table Bugs_2010 (...);
対策
- 水平パーティショニング
DBエンジンのパーティション機能を使う。
テーブルは物理的に分割されているが、あたかも1つのテーブルかのようにSQLステートメントを実行できる。
create table Bugs (
bug_id serial primary key,
...,
date_reported DATE
) partition by hash (year (date_reported))
partitions 4;
-
垂直パーティショニング
列でテーブルを分割できる。1部の列がサイズが大きい場合や、滅多に使用されない場合に活用できる。
例えば、BLOB列とTEXT列はサイズ可変で、通常は非常に大きいサイズであることが考えられる。
これらの列を分割して保存することで、他の列に効率的にアクセスできる。
クエリの際の列名に*
を使わないように注意。 -
従属テーブルの導入
概要の例でいうと、プロジェクトごとに年別の列を持たせる代わりに、プロジェクトと年の組み合わせが1行となる従属テーブルを新たに定義しましょう。
create table ProjectHistory (
project_id bigint,
year smallint,
primary key (project_id, year)
foreign key (project_id) references Projects(project_id)
);
おわりに
まだまだ続きます。