Database Specialist Examination study materials
Database Specialist Examination study resources

Database Specialist Examination common mistakes

Database Specialist Examination · Understand the traps and how to avoid them.

Mistake 1

概念データモデルを書く段階で、実装先のテーブル名・データ型・インデックス・外部キー制約をER図に書き込み、業務上の实体と関連を表すモデルではなく物理設計図にしてしまう。

実務のER図がDBMSに作るテーブル定義と同一だと誤解し、概念モデルの目的(業務用語での合意形成)を意識していない。

What to do instead

概念モデルではエンティティタイプ・関連・カーディナリティ・任意性・業務ルールだけを書き、データ型やインデックスは論理/物理設計に分離する。用語集とリポジトリで業務用語を標準化し、関係者レビューで検証する。

Mistake 2

第3正規形までで正規化を止め、候補キーが複数ある表のBCNF違反や、独立した多値属性(4NF)・結合従属性(5NF)を見落とす。

1NF〜3NFの手順だけを暗記し、関数従属性をすべての候補キーについて確認する習慣がない。

What to do instead

全ての関数従属性を列挙し、候補キーごとに決定項がスーパーキーかを確認してBCNFを判定する。独立した多値事実は別表に分離し、最後に性能上の非正規化を行う場合も理由と整合性維持方法を記録する。

Mistake 3

代理キーを主キーにしただけで自然キーに一意制約を置かず、同じ業務キーの重複を許す。また現在値だけを設計し、価格改定や所属変更などの履歴・時間軸を表現できない。

代理キーは性能と安定性に便利だが、業務上の一意性を別途保証する必要があること、時間変化する属性の扱いを設計要件として捉えていない。

What to do instead

業務キーにはUNIQUE制約または一意制約を必ず設定し、代理キーは内部識別子として使う。履歴が必要な属性は、有効期間(開始日・終了日)やイベント表、または版管理で時間軸をモデル化し、重複期間を防ぐ制約を設計する。

Mistake 4

「WHERE status <> '完了'」でNULLの行も含まれると期待する、「NOT IN (SELECT ...)」の副問い合わせにNULLが混じって結果が空になる、「COUNT(*)」と「COUNT(列)」を同じと考える。

SQLの三値論理(TRUE/FALSE/UNKNOWN)とNULLの伝播を、プログラミング言語の二値論理の感覚で扱うため。

What to do instead

NULLを含み得る列には「IS NULL」「IS NOT NULL」を明示し、必要なら「COALESCE」で既定値に置換する。「NOT IN」はNULLを含む副問い合わせでUNKNOWNになるため、「NOT EXISTS」か副問い合わせ側で「WHERE col IS NOT NULL」を付ける。「COUNT(列)」はNULLを数えないことを意識して使い分ける。

Mistake 5

GROUP BYに含まれない列をSELECTしてよいと考える、集約条件をWHEREに書く、集約と非集約の混在したSELECTを書く。

SQLの論理評価順序(FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY)を意識せず、実行結果の見た目で覚えている。

What to do instead

集約前の行フィルタはWHERE、集約後のグループフィルタはHAVINGに分ける。SELECTする非集約列はGROUP BY列か、関数従属が保証された列だけにする。必要ならサブクエリで集約してから結合する。

Mistake 6

READ COMMITTEDやREPEATABLE READで発生し得る異常(ダーティリード、非再現リード、ファントムリード)を取り違え、REPEATABLE READならファントムは起きないと断定する。

分離レベル名と防止できる異常の対応を表で丸暗記し、MVCCとロックの実装差を理解していない。

What to do instead

標準SQLの分離レベル表を基準に、各レベルで許容される異常を整理する。対象DBMSの実装(MVCCのスナップショット、ギャップロック、SERIALIZABLEの扱い)を確認し、2セッションで同時実行テストをして挙動を検証する。

Mistake 7

チェックポイントを境にREDO/UNDO対象を単純化し、チェックポイント時点で未完了だったがその後コミットしたトランザクションのREDOを漏らす、またはチェックポイント時に未完了のまま障害時に至ったトランザクションのUNDOを忘れる。

チェックポイントを「それ以前は全部不要」と単純化し、トランザクションの開始・コミット・チェックポイントの時系列を図で追えていない。

What to do instead

WALとARIESの考え方に沿って、分析→REDO→UNDOの順にタイムラインを描く。チェックポイント時にアクティブだったトランザクションは、その後コミットしていなければUNDO対象、コミット済みならREDO対象として区別する。障害時刻とバックアップ時刻を使ったPITR手順を練習する。

Mistake 8

検索条件に使われる列すべてに単一索引を張る、または複合索引の列順を問わず作れば速くなると考える。更新が多い表でも索引を増やし続ける。

索引の効果を「あると速い」と一般化し、選択性・カーディナリティ・複合索引の左端プレフィックス・書き込みコストを評価していない。

What to do instead

WHERE句・JOIN条件・ORDER BYを洗い出し、選択性の高い列を先頭にした複合索引を検討する。実行計画で索引使用を確認し、不要な索引は削除する。更新コストと領域も含めて評価する。

Mistake 9

アプリケーションからDBへ固定の管理者アカウントで接続し、SQLを文字列連結で組み立てる。監査ログや権限分離を設計しない。

機能実装を優先し、最小権限・SQLインジェクション対策・監査を非機能要件として設計に組み込んでいない。

What to do instead

用途別のDBロールを作成し、最小権限を付与する。プレースホルダ(バインド変数)を使い、動的SQLが必要な場合はホワイトリストで識別子を検証する。接続情報は秘密管理に置き、監査ログと失敗ログインの監視を設計する。

Mistake 10

データウェアハウスをOLTPと同じ正規化方針で設計し、粒度(grain)やディメンション・ファクトの定義を曖昧にしたままETLを書き始める。

分析用途では非正規化されたスタースキーマや履歴・集計粒度が重要であることを、業務DBの設計経験の延長で捉えている。

What to do instead

最初に分析の問いと集計粒度を決め、ファクト(事象)とディメンション(文脈)を定義する。ETLでは抽出時点・変換ルール・遅延到着・再実行時の冪等性を設計し、データ品質チェックとリネージを記録する。