対象読者
- データベースの設計でなんだか自分のやり方があっているか不安がある
- データベース設計を学び始めた初学者の人
- 悪い例を知りたい人
早速3つ紹介。
① 非正規化を優先的に考えてしまう
非正規化は非常に高度な内容です。
何かの列の集計結果や選択条件となるカラムが別テーブルにある場合、
結合しないといけなかったり、
結合が複数ある場合は、テーブル分割をあえてせずに一つのテーブルにいろんな情報を詰め込みたい場合があります。
そうすることで結合処理をなくし、
欲しいデータが素早く手に入るようになります。
(結合処理はSQL文の中でも非常に重い処理なのでパフォーマンス向上にはつながる)
しかし、SQL文が複雑になってでもまずは正規化を守り、整合性のとれたDB設計とすることを優先しましょう。
まだ複雑な結合が起こったほうが良くて、
テーブル全体での冗長性がなく整合性のとれた構造の方がマシということです。
というのも、
あえてデータを冗長化して複数のテーブルに散らばす = 更新コストが正規系の時より増加する
ということだからです。
当然ですよね。
データを複数テーブルに散らばめたことにより、複数テーブルの更新をするためにその分確認しないといけないテーブルの数が増えるためです。
正規化であればデータの冗長性は排除され、そのデータはこのカラムさえ見れば良い、他のデータはこのカラムを参照するのでここだけ変更すれば参照先では何も変更しなくてよい、といった具合でした。
なので、繰り返しで恐縮ですが慣れないうちや、正規化と非正規化のトレードオフをハンドリングできないうちは正規化を優先するようにしましょう。
あくまでここで訴えているのは、非正規化を 優先的 に考えてはいけないということです。
パフォーマンス向上のために非正規化をすべき場面があることも念頭に置きましょう。
② 列名は変数としてとらえて値を入れる(最悪)
- 列名は変数ではない
- 複数の意味を込めてはいけない
- 別の意味のデータは必ず別カラムにする
例えば以下の様なテーブルを見てください。
サンプル(悪い例:列の意味が途中で変わる)
CREATE TABLE profiles (
id BIGINT PRIMARY KEY,
"身体情報1" INT NULL
);
レコード例(説明用)
| id | 身体情報1 |
|---|---|
| 1 | 170 |
| 2 | 165 |
| 3 | 182 |
| 4 | 29 ←←途中から年齢...かな??!! |
| 5 | 31 |
| 6 | 16 |
※ id=1〜3 は「身長(cm)」のつもり、id=4〜6 は「年齢(年)」を入れてしまっている例。
列1を見てください。途中まで体重だったものが年齢っぽいものが入っていますね。仮に誰かが途中から体重カラムに年齢を入れ始めたとしましょう。
もしこれを見て
【は?なにしてんの?】
と思ったなら正常な感覚です。
もし普通のプログラミング言語的な感覚で列も変数的に使えるのかな、
などと思ったら危険信号なので何度も見返してほしいです。
具体的な状況を考えればどうしてこれがいけないかは容易に想像つくはずです…
上司「この列、途中から意味が変わるからコーディングする際に気を付けてね」
自分「.........??!!」
たまったもんじゃありません。
身長 を表すならそもそも【身体情報1】などという列名ではなく
【身長】 など一意に意味が定まるカラム名にしましょう。
繰り返しになりますが、列は変数名ではありません。
静的で基本的には変更しない、変数よりずっと静的なものです。
違う意味のデータは一つのカラムに入れず、しっかりと分割して設計をしましょう。
③ 不適切なキー
これはものすごく単純な話です。
- データ型に可変長文字列をするな
- そもそもキーは永遠に不変です!!
- 可変長である意味がない&むしろ可変であると危険
- キーは固定長のコード列が望ましい
補足
なぜこれらがバッドなのか。
以下の2つになります。
- 設計変更が難しくなる(特に非正規化)
- 可読性が下がる(今回挙げた例全部当てはまる)
これらによりデータベース設計がぐちゃってしまうと、それに引きずられてアプリケーションを実現するためのコードも複雑化します。
データ構造がアプリケーションコードを決めるのであって、その逆ではない という言葉もあるぐらいです。(比喩ではなく現実そうですが)
バッドノウハウはほかにもいろいろありますので、実務や学習を進める際にぜひとも出会ったデータベースの構造を問い直してみるいいきっかけになればと思います。
参考
- 達人に学ぶDB設計徹底指南書