論理設計の『やってはいけない』
戦略の失敗を戦術で取り返すことはできない
という有名な言葉があるらしい。システム開発における戦略は設計で、プログラミングは戦術に相当する。つまり、プログラムの品質を決めるのは設計になる。そんな設計において品質を致命的なレベルで損なってしまうバッドノウハウ(アンチパターン)を学ぶ。
非スカラ値(第一正規形未満)
第一正規系未満(セルにデータは1つ)のテーブルも存在する。例えば、下記のような非スカラ値のテーブルを考える。
社員ID | 社員名 | 子 |
---|---|---|
000A | 加藤 | 達夫 信二 |
000B | 藤本 | |
001F | 三島 | 淳 陽子 清美 |
上記は1つのセルに複数のデータが入っているので、正規系でない。この場合、『子』列を追加するか、『家族』エンティティを追加するのが正規化の流れだった。
その他の対処として、SQLの配列型を用いるというものもある。イメージ的には下記のようなテーブルにする。
社員ID | 社員名 | 子 |
---|---|---|
000A | 加藤 | {達夫,信二} |
000B | 藤本 | |
001F | 三島 | {淳,陽子,清美} |
配列型にすることで、セルに入れるデータを1つにできた(非スカラ値を含むテーブルを作った)。ただ、上記のデータは、データベースを扱うアプリーケーションやミドルウェアとの整合性が悪く、設計コストが増加してしまうので用いるべきではない。
『そもそもスカラ値の基準って🤔』という問いに対しては、『意味的に分割できる限り、なるべく分割したもの』というのが回答になるとのこと。理由は、SQLでは結合は簡単だが分割は難しいということが背景にある。 例えば、『坂之上田村麻呂』というデータを姓と名に分けるときに、どこまでが名前かがわからないため、最初から分けて管理していれば苦労しないという感じ。
ダブルミーニング
ダブルミーニングは、同一の列に複数の意味を持つ状態になっていることをいう。具体的には、次のテーブルの列2のような、最初体重データで、途中から年齢に変わっているようなものを指す。
年度 | 学生名 | 列1 | 列2 |
---|---|---|---|
2001 | A | 170 | 62 |
2001 | B | 168 | 55 |
2001 | C | 155 | 60 |
2002 | D | 164 | 19 |
2002 | E | 173 | 21 |
2002 | F | 166 | 20 |
テーブル作成者の意図としては、以降では年齢しか使わないので、『まぁいいだろう』というような感じで対応した。今後、このテーブルを引き継ぐ人は、ある年の前後では扱っているデータが違うということを覚えておかないといけなくなる。
テーブルのデータは変数ではなく、実世界にある色々な実体(エンティティ)の写像であるので、静的なものという認識を持っておく。
単一参照テーブル
単一参照テーブルは『あらゆるタイプのマスターテーブルを、1つのテーブルにまとめてしまった』もの。例えば、次のようなテーブルは、『識別ID』+『名称』という組み合わせになっている。
会社コード | 会社名 |
---|---|
C001 | A商事 |
C002 | B建設 |
部署コード | 部署名 |
---|---|
B001 | 開発 |
B002 | 経理 |
よって、まとめてしまえということで、次のようなテーブルにする。
コードタイプ | コード値 | 会社名 |
---|---|---|
comp | C001 | A商事 |
comp | C002 | B建設 |
depart | B001 | 開発 |
depart | B002 | 経理 |
上記のテーブルは、あるときは会社名のテーブルであり、あるときは部署名のテーブルとなるような感じで、テーブル全体の意味が変わる。単一参照にすることでテーブル数は少なくなるが、テーブル内で管理するデータ数は大きくなりSQLのパフォーマンスは劣化する。 メリデメを考慮すると、用いるべきでないノウハウになっている。
テーブル分割
一般的にパフォーマンス向上のために実施されることがあり、『水平分割』と『垂直分割』の2パターンがある。
水平分割
例えば、次ようなテーブルがある。
年度 | 会社コード | 売上(億円) |
---|---|---|
2001 | C001 | 50 |
2001 | C002 | 43 |
2002 | C001 | 77 |
2002 | C002 | 62 |
水平分割をすると、次の2つのテーブルになる。
年度 | 会社コード | 売上(億円) |
---|---|---|
2001 | C001 | 50 |
2001 | C002 | 43 |
年度 | 会社コード | 売上(億円) |
---|---|---|
2002 | C001 | 77 |
2002 | C002 | 62 |
年度ごとで扱うデータが減るためパフォーマンスを向上できた。ただ次の観点からRDBMSでは原則禁止になっている。
- 分割する意味的な理由がない:正規化に沿っていない
- 拡張性に乏しい:全データの総なめ検索などに弱い
- 他の代替手段がある:パーティションやインデックスなどの方法がある
垂直分割
水平分割の列バージョン。結局のところ、水平分割と同様の観点により使うべきでない。
テーブル分割の代替手段
テーブル分割の代替手段として次の2種類がある。
列の絞り込み
データマートという元テーブルから欲しいデータを抽出した小さいテーブルをコピー生成する。元テーブルを破壊しないため、使い勝手は良いが、データ同期のタイミングが課題になっている。
サマリテーブル
元テーブルから事前に集約を行った結果のテーブルを作っておく。何か集約したデータのリクエストが来たら、サマリテーブルのデータを返す。ただ、この手法もデータ同期のタイミングが課題になっている。
不適切なキー
主キーや外部キーに、可変長文字列(VARCHAR)は用いない。理由は、キーが果たすべき不変姓を備えていないため。キーは識別子であるので、コロコロ変わってしまっては困る。よって可変長文字列のようなタイプは適切でない。
キーには固定調文字列の『コード』列が望ましい。
ダブルマスター
ダブルマスターは、この本の中での呼び方で、同じ役割を果たすはずのマスターテーブルが2つ存在することをいう。
例えば次のような顧客テーブルがあるとする。
顧客コード | 顧客名 |
---|---|
C001 | 山田太郎 |
C002 | 田中太田 |
C003 | 中島義仁 |
顧客コード | 顧客名 |
---|---|
C001 | 山田太郎 |
C002 | 田中太田 |
K001 | 小島正雄 |
上2つは、あるシステムを統合する際に、両者のデータベースの構成が上記のようになっているような時に起こる。必要な情報が複数のテーブルに散らばっていると、それを結合するのにコストが高くなってしまう。