DB設計についての話(その2)

前回の記事でDB設計について書きましたが今回はその続きとなります。

idをどうするか

MySQL等を使っているとidカラムをAUTO_INCREMENTにして連番にしているテーブルを見たことがある人がほとんどだと思います。

しかしAUTO_INCREMENTは便利な反面、DBの機能に依存することになります。

クリーンアーキテクチャを採用している場合は特にデータストアとしてDBを使うかどうかに依存しないようにすることが肝要です。

つまり、idの仕様をDBの機能に依存するのではなく、アプリケーション側で決めるということです。

その為、重複しないidとしてUUIDや、ソート可能なULIDを採用するのが望ましいと言えます。

PHPであればsymfony/uidを使えば簡単に生成できます。

インデックス

インデックスをどこに貼るかもパフォーマンスに大きく関わってきます。

インデックスを貼るカラムを決めるにはまず「どのようなSQLが発行されるか」を想定することが必要だと思います。

  • WHERE句はどのようになるのか
  • 他テーブルとJOINするのか、するのであればどのカラムで結合するのか
  • GROUP BYは使うのか、使うのであればどのカラムでグルーピングするのか
  • ORDER BYは使うのか、使うのであればどのカラムで並び替えるのか

これらの観点でインデックスをどこに設定すべきかが見えてくると思います。

特にGROUP BYやORDER BYはインデックスの設定されていないカラムで行うとパフォーマンスへの影響が大きくなります。

また、複合インデックスの場合は順番も大事です。

例えば以下のようなテーブルがあったとします。

CREATE TABLE `users` (
  `id` CHAR(26) PRIMARY KEY COMMENT 'id',
  `last_name` VARCHAR(10) NOT NULL COMMENT '',
  `first_name` VARCHAR(10) NOT NULL COMMENT '',
  INDEX `idx_last_name_first_name` (`last_name`, `first_name`)
);

このテーブルに対してSELECTする際に、

SELECT
  *
FROM
  `users`
WHERE
  `last_name` = '山田'
  AND `first_name` = '太郎';

↑のSQLならばインデックスが効きますが、

SELECT
  *
FROM
  `users`
WHERE
  `first_name` = '太郎'
  AND `last_name` = '山田';

↑だとインデックスが効きません。

インデックスを設定した順番にWHERE句で絞り込むように注意する必要があります。

まとめ

以上DB設計についての話でした。

前回書いたテーブルの正規化がしっかりできていればどこにインデックスを設定するか掴みやすくなるのではと思います。

ユニークキーや外部キー制約等についてはまた次回以降書きたいと思います。