Create Branch

ユーザーロール管理の設計で悩んだこと

Published on 2025年9月27日

つぶやき

はじめに

ヒューマンビートボックスのプラットフォーム開発で、ユーザーの役割管理をどう設計するかで悩みました。

「異なる特性を持つユーザーロールを、どのようにデータベースで管理するべきか?」

一見シンプルな問題ですが、実は設計思想が大きく問われる課題でした。

想定するユーザーロール

プラットフォームでは3つのロールを想定

  • artist:アーティスト名が必須
  • Audience(仮):実名または匿名での参加
  • Organizer:企業名や組織名での運営

重要なポイント:各ロールでname属性の意味合いが全く異なる

検討した設計パターン

パターン1:単一テーブル管理

user {
  id
  email  
  password
  role (enum: artist, audience, organizer)
  name -- 全ロール共通?
  artist_name -- humanbeatboxer専用(nullable)
  company_name -- organizer専用(nullable)
}

一見シンプルですが...

  • 各ロール固有の属性が増えると破綻
  • NULLカラムが大量発生
  • 単一責任原則に違反

パターン2:エンティティ分割(採用)

-- 共通の基本情報
user {
  id
  email
  password
  role
}

-- 各ロール固有の情報を分離
artist {
  id
  user_id
  name (アーティスト名)
}

audience {
  id
  user_id  
  name (実名 or 匿名)
}

organizer {
  id
  user_id
  name (企業名や組織名)
}

分割設計を選んだ理由

1. 責務の明確な分離

問題意識

基本的に、共有できるものは、userで持たせて、特性の異なるものは、それぞれのサブクラスで持たせている

  • User:認証・共通情報の管理
  • 各ロールエンティティ:ロール固有の情報管理

2. 拡張性の確保

新しい属性が追加される場合:

  • 分割設計:該当ロールのテーブルのみ修正
  • 単一設計:userテーブル全体に影響

3. データの整合性

各ロールで同じnameでも意味が違うため、分離することで:

  • バリデーションルールを個別設定可能
  • 誤った用途での使用を防止

設計判断で悩んだポイント

Userエンティティでroleを持つべきか?

当初の疑問

userでroleを持つべきか?rolesを持つ場合、各エンティティを管理する必要がなくなる?

検討した選択肢

A. Userのみで管理

user { id, email, password, role, name }

→ 各ロールの特性に対応できない

B. 完全分離

user { id, email, password }
-- roleはそれぞれのテーブルの存在で判断

→ ロール判定が複雑

C. 基本情報 + 分離(採用)

user { id, email, password, role }
-- + 各ロール固有テーブル

→ 共通処理とロール固有処理のバランス

ロール情報の管理方法

roleの値をどこで管理するか?

選択肢1:マスターテーブル

roles { id, name, description }

選択肢2:定数管理

enum UserRole {
  artist = 'artist',
  AUDIENCE = 'audience', 
  ORGANIZER = 'organizer'
}

判断:一旦定数で管理し、将来的な要件に応じてマスターテーブル化を検討

実際の使い分け

ロール共通の処理

// userエンティティを使用してroleで判定
if (user.role === UserRole.artist) {
  // 共通ロジック
}

ロール固有の処理

// 各ロールエンティティにアクセス
const artist = await artistRepository.findByUserId(user.id);
console.log(artist.name); // アーティスト名

学んだこと

設計は将来への投資

各roleに属性の異なる値が出てきた場合、対応できなくなる

短期的には設計コストがかかるが、長期的な変更容易性を重視した判断。

完璧を求めすぎない

全ての将来要件を予測するのは不可能。現在の要件を満たしつつ、拡張可能な構造を選択。

データ設計の影響範囲

ユーザー管理は多くの機能に影響するため、慎重な設計判断が必要。

まとめ

最終的な設計方針

  1. 共通情報はUserエンティティで管理
  2. ロール固有情報は専用エンティティで分離
  3. ロール値は定数管理(将来的にマスター化も検討)

重要な気づき 同じ属性名でも、ビジネス的な意味が異なる場合は分離することで、保守性と拡張性を両立できる。


これらのエンティティのインスタンス生成をどう管理するかについて、こちらで投稿しているのでぜひ読んでみてください。

hirotobeat