web-dev-qa-db-ja.com

複数のユーザータイプとその連絡先情報のデータベース構造のモデリング

さまざまなタイプのユーザーを格納するデータベースを設計しています。主に(ただし、これに限定されません)、俳優、監督、作家になります。現在、関連するユーザータイプは4つだけです。この数が増加する可能性はありますが、確率は低く、そのような場合は非常に小さい数になります。

計画は、サイトへのログインのみを担当するusersテーブル(nameemail、およびpassword列に加えて、1つまたは2つの他の承認されているかどうか、updated_atなど)、およびそれぞれのユーザータイプごとに追加のテーブルがあり、それぞれに固有の列のセットがあります。たとえば、俳優だけが民族の列を持ち、ディレクターだけが経歴の列を持ち、ライターだけが場所を提供する必要があります。ただし、この複雑なデータベースを以前に管理したことがないので、いくつかの側面を整理する方法を考えています。

第一に、ユーザーは上記のタイプのいずれか、または任意の組み合わせにすることができます。だから私は(例えば)director_userテーブルとdirector_idおよびuser_id列。これで、ロールタイプなどですべてのユーザーをフィルタリングできるようになりますか?

第二に、ほとんどのユーザーはTwitterプロフィールと電話番号を選択できます。また、すべての俳優には、他のオンライン俳優プロファイルのURLを少なくとも1つ含める必要があります。現在、含めることができる3つがありますが、この数は増える可能性があります。可能なプロファイル/連絡方法ごとに個別のテーブルがデータを編成するための最適な方法であると私は思いますか?

10
verism

これを次のようにテーブル間で分割する必要があります(概念を提示するために必要な列のみを表示し、必ずしもすべての列を表示する必要はありません)。

Users
ID   Username   FirstName   LastName   PasswordHash ...
 1   'Joe1'      'Joe'      'Smith'
 2   'Freddy'    'Fred'     'Jones'

Roles
ID   RoleType ....
 1   'Writer'
 2   'Director'
 3   'Actor'

User_Roles
User_ID   Role_ID ...
1         1
1         2
2         2
2         3

これにより、さまざまなユーザー列をすべて持つユーザーが満載のテーブル、ロールのテーブル、および2つを接続するためのリンクテーブルが提供されます。

User_Rolesのエントリから、Joe1がライターであり、ディレクターでもあることがわかります。そして、フレディは監督と俳優の両方です。

これにより、システムを変更せずに後で役割を追加することもできます。プロデューサーやエディターなどのレコードを挿入するだけです。

したがって、アクターのすべてのユーザー名を見つけるには、いくつかの選択肢があります。

 Select Distinct Username
   from Users
  Where User_ID in (select User_ID from User_Roles where Role_ID = 3)

または、role_ID番号がわからない場合は、次のようにします。

 Select Distinct Username
   from Users
  Where User_ID in (Select User_ID from User_Roles where Role_ID = 
                       (Select ID from Roles where RoleType = 'Actor')
                   )

または、これを行うこともできます。

select u.Username, r.RoleType
  from Users u
 inner join User_Roles ur on ur.User_ID = u.ID
 inner join Roles r on r.ID = ur.Role_ID
 where r.RoleType = 'Actor'

(このバージョンでは、Where r.Role_ID = 3でも同じ結果が得られます。)

ただし、最初のクエリと、知っているWHERE句を使用します。大規模なシステムでは、数値データは「より簡単」でほとんどのSQLエンジンがインデックスを処理するのに効率的であるため、Role_IDを知ることは、通常、テキストよりも速く実行されます。

連絡方法や写真などについては、同様の方法で行います。

Attributes
ID    MethodText    ...
1     'TwitterID'
2     'URL'
3     'CellPhone'
4     'Email'
5     'PictureLink'

Role_Attributes
Role_ID  Attribute_ID isRequired
3        5             1
3        4             1
3        3             0

User_Attributes
User_ID  Attribute_ID  AttributeData
1         4            '[email protected]'
1         1            '@joe'
1         3            '555-555-5555'
1         5            'www.example.com/pics/myFace.png'

...等々。これらは、ユーザーと同じ方法でロールにリンクします。

これは、各役割が0から多くの属性を持っていることを示しています。次に、各ユーザーは0から多くの属性を持ち、それらの属性のデータを持ちます。

これにより、コードを書き直すことなく、時間の経過とともに新しい属性を追加できます。新しいルールに一致するように、attributesおよびrole_attributesテーブルを更新するだけです。また、ユーザーごとに同じデータを再入力しなくても、役割間で属性を共有できます。 2つの役割で写真が必要な場合は、1つの写真をアップロードするだけで、その要件を満たすことができます。

2
CaM