一般的な会員制ウェブサービスでは
ユーザー仮登録 => メールアドレス認証 => ログイン処理
という手続きを行う。
これを実現するためにユーザーテーブルにユーザーの登録状態や認証状態などのカラムが追加されることが多い。
しかし、ユーザーテーブルにこれらが集約された設計では、ユーザーの状態を考慮しないクエリを発行してしまうことによるバグが発生しやすい。またクエリの条件が増え複雑になりやすい。
そこで、仮登録、ユーザー、認証、トークンの4つにテーブルを分割することで、その類のバグを減らすことができ、仮登録や認証を実装する際にも様々な恩恵が受けられる。
仮登録テーブル(仮登録時にレコードが追加される。)
- メールアドレス
- パスワード
- 認証トークン
- 仮登録日付
ユーザーテーブル(メールの確認処理が終わると追加される)
- ユーザーID
- メールアドレス
認証テーブル
- ユーザーID
- パスワード
トークンテーブル(JWTなど永続化不要な仕組みを使う場合は不要)
- ユーザーID
- 認証トークン
- 認証トークン有効期限
この設計にすると認証時のSELECTで余計な情報を取ってきてしまったり、仮登録の人は除かなきゃとか考えなくて良くなる。
あと仮登録と認証の部分だけやっぱキーバリューストアにしようとかもあとから簡単にできる。
ユーザーの退会を考えるとユーザーの状態を意識しないといけないが、それでも全部ユーザーテーブルに突っ込むよりはずっといいと思う。