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


10

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

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

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

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

回答:


14

関心のビジネスコンテキストのあなたの説明の私の解釈によると、あなたが扱っているスーパータイプサブタイプ1つの構造()俳優監督脚本は、(B)の実体サブタイプある、そのエンティティのスーパータイプ、および(C)上記のサブタイプは相互に排他的ではありません

このようにして、そのようなシナリオを正確に反映するリレーショナルデータベースの構築に関心があり、そのように機能することを期待している場合、次のコメントの説明は、前の点に関して非常に重要です。問題のデータベースの(1)概念的および(2)論理レベルの表現の両方:

  • […]それぞれ独自の列のセットを持つ、それぞれのユーザータイプごとの追加のテーブル。

  • […]関連するユーザータイプは4つだけです。この数は増加する可能性がありますが、確率は低く、そのような場合は非常に小さい数になる可能性があります。

以下のセクションでは、これらすべての側面とその他のいくつかの重要な要素について詳しく説明します。

ビジネスルール

まず、対応する概念スキーマを定義します-これを後続の参照として使用して、正確な情報要件を確実に満たすようにスキーマを適合させることができるようにするために、特に重要なビジネスルールをいくつか作成しました。

  • A 人は一から二-または-3を実行してもよい(すなわち、1対のすべて)の役割2。言い換えると、
    • 俳優
    • ディレクター
    • ライター
  • A 人は、ゼロまたはオン経由でログインできるのUserProfile
  • 俳優一から二-または-3を提供するURL 3
  • 俳優は 1つのでグループ化されている人種
  • アン人種のグループは、ゼロ・ワン・オア・多くの俳優
  • ライターは 1つのに基づいています場所
  • A 場所ゼロ一又は、それ以上の塩基である作家

解説IDEF1X図

次に、図1に示すIDEF1X 4ダイアグラムを作成しました。これは、上記のすべての公式を、関連する他のルールとともにグループ化したものです。

図1-映画の人物の役割と連絡先の詳細のIDEF1Xダイアグラム

示されているように、Personスーパータイプには(i)独自のボックスがあり、(ii)すべてのサブタイプに適用されるプロパティまたは属性を持ち、(iii)それをすべてのサブタイプのボックスに接続する線を示します。

次に、すべてのサブタイプは(a)専用のボックスに表示され、(b)適用可能なプロパティのみを保持します。スーパータイプのPRIMARY KEY、PERSONID、移行5ロール名とサブタイプに6 アクターIDDirectorId、およびWriterIdそれぞれ。

また、PersonUserProfileエンティティタイプと結合しないようにしました。これにより、すべてのコンテキストへの影響、関連付け、または関係などを分離できます。PersonIdプロパティは、ロール名UserIdでUserProfileに移行しました

あなたは質問の本文で

また、すべての俳優には、他のオンライン俳優プロファイルのURLを少なくとも1つ含める必要があります。現在、含めることができる3つがありますが、この数は増える可能性があります。

... URLはそれ自体がエンティティタイプであり、この引用に従って、Actorサブタイプに直接関連付けられています。

そして、コメントで、あなたはそれを指定します

[…]俳優にはヘッドショット(写真)がありますが、作家にはありません[…]

…その後、他の機能の中でも、ActorエンティティタイプのプロパティとしてHeadshotを含めました。

人種場所のエンティティタイプ、もちろん彼らは、より複雑な組織を伴ってもよい(例えば、俳優 1、明確な割合で二つ以上の異なる民族グループに属していてもよい、とライターは記録を必要な場所に基づいてもよいです国、行政区域、郡など)ですが、ビジネスコンテキストのニーズは、ここでモデル化された構造でうまくカバーされているようです。

当然、必要なだけ調整を行うことができます。

例示的なSQL-DDL論理設計

したがって、上記のIDEF1Xダイアグラムに基づいて、次のような論理DDLレイアウトを作成しました(テーブル、列、および制約に関して特に重要だと考えるいくつかの特性を説明するコメントとしてノートを提供しました)宣言):

-- You should determine which are the most fitting 
-- data types and sizes for all your table columns 
-- depending on your business context characteristics.

-- Also, you should make accurate tests to define the 
-- most convenient INDEX strategies based on the exact 
-- data manipulation tendencies of your business needs.

-- As one would expect, you are free to utilize 
-- your preferred (or required) naming conventions. 

CREATE TABLE Person ( -- Represents the supertype.
    PersonId       INT      NOT NULL,
    FirstName      CHAR(30) NOT NULL,
    LastName       CHAR(30) NOT NULL,
    BirthDate      DATE     NOT NULL,
    GenderCode     CHAR(3)  NOT NULL,
    TwitterProfile CHAR(30) NOT NULL,
    PhoneNumber    CHAR(30) NOT NULL,
    EmailAddress   CHAR(30) NOT NULL,  
    CreatedDateTime DATETIME NOT NULL,
    --
    CONSTRAINT Person_PK  PRIMARY KEY (PersonId),
    CONSTRAINT Person_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
        FirstName,
        LastName,
        GenderCode,
        BirthDate
    ),
    CONSTRAINT Person_AK2 UNIQUE (TwitterProfile), -- ALTERNATE KEY.
    CONSTRAINT Person_AK3 UNIQUE (EmailAddress)    -- ALTERNATE KEY.
);

CREATE TABLE Ethnicity ( -- Its rows will serve a “look-up” purpose.
    EthnicityId     INT      NOT NULL,
    Name            CHAR(30) NOT NULL,  
    Description     CHAR(30) NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Ethnicity_PK PRIMARY KEY (EthnicityId),
    CONSTRAINT Ethnicity_AK UNIQUE      (Description)   
);

CREATE TABLE Actor ( -- Stands for one of the subtypes.
    ActorId         INT      NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    Headshot        CHAR(30) NOT NULL, -- May, e.g., contain a URL indicating the path where the photo file is actually stored. 
    EthnicityId     INT      NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Actor_PK            PRIMARY KEY (ActorId),
    CONSTRAINT ActorToPerson_PK    FOREIGN KEY (ActorId)
        REFERENCES Person (PersonId),
    CONSTRAINT ActorToEthnicity_PK FOREIGN KEY (EthnicityId)
        REFERENCES Ethnicity (EthnicityId)   
);

CREATE TABLE Director ( -- Denotes one of the subtypes
    DirectorId      INT       NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    Bio             CHAR(120) NOT NULL,  
    Etcetera        CHAR(30)  NOT NULL,
    CreatedDateTime DATETIME  NOT NULL,
    -- 
    CONSTRAINT Director_PK         PRIMARY KEY (DirectorId),
    CONSTRAINT DirectorToPerson_PK FOREIGN KEY (DirectorId)
        REFERENCES Person (PersonId)   
);

CREATE TABLE Country (
    CountryCode     CHAR(2)  NOT NULL,
    Name            CHAR(30) NOT NULL,  
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Country_PK PRIMARY KEY (CountryCode),
    CONSTRAINT Country_AK UNIQUE      (Name)   
);

CREATE TABLE Location ( -- Its rows will serve a “look-up” purpose.
    CountryCode     CHAR(2)  NOT NULL,
    LocationCode    CHAR(3)  NOT NULL,
    Name            CHAR(30) NOT NULL,  
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Location_PK PRIMARY KEY (CountryCode, LocationCode),
    CONSTRAINT Location_AK UNIQUE      (CountryCode, Name)   
);

CREATE TABLE Writer ( -- Represents one of the subtypes.
    WriterId        INT      NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    CountryCode     CHAR(2)  NOT NULL,
    LocationCode    CHAR(3)  NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT Writer_PK           PRIMARY KEY (WriterId),
    CONSTRAINT WriterToPerson_PK   FOREIGN KEY (WriterId)
        REFERENCES Person (PersonId),
    CONSTRAINT WriterToLocation_PK FOREIGN KEY (CountryCode, LocationCode)
        REFERENCES Location (CountryCode, LocationCode)  
);

CREATE TABLE UserProfile (
    UserId          INT      NOT NULL, -- Must be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
    UserName        CHAR(30) NOT NULL,
    Etcetera        CHAR(30) NOT NULL,
    CreatedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
    CONSTRAINT UserProfile_AK UNIQUE      (UserName), -- ALTERNATE KEY.
    CONSTRAINT UserProfileToPerson_PK FOREIGN KEY (UserId)
        REFERENCES Person (PersonId)    
);

CREATE TABLE URL (
    ActorId       INT      NOT NULL,
    Address       CHAR(90) NOT NULL,
    Etcetera      CHAR(30) NOT NULL,
    AddedDateTime DATETIME NOT NULL,
    -- 
    CONSTRAINT URL_PK        PRIMARY KEY (ActorId, Address), -- Composite PRIMARY KEY.
    CONSTRAINT URLtoActor_FK FOREIGN KEY (ActorId)
        REFERENCES Actor (ActorId)
);

したがって、(1)上記の論理レイアウトのすべての特異な側面は、(2)関心のあるビジネス環境の特異な特徴7- エドガーフランクコッド博士によるリレーショナルフレームワークの精神と一致して- から非常に正確な意味を持っています。なぜなら:

  • ベーステーブルは、個々のエンティティタイプを表します。
  • は、それぞれのエンティティタイプの単一のプロパティを表します。
  • 含まれるすべてのが、INT、DATETIME、CHARなどの特定の適切に区切られたセットaに属していることを保証するために、各に対して特定のデータ型が固定されています(MySQLが最終的にDOMAINを組み込むことを期待しましょう近未来バージョンでのサポート)。
  • すべてのテーブルに保持される行の形式のアサーションが概念レベルで決定されたビジネスルールに準拠することを保証するために、複数の制約が(宣言的に)構成されます。
  • それぞれの行は、明確に定義された意味論、例えばを伝えることが意図されて、Person行が読み込まれます

    PersonId rで識別されるPerson はFirstName sとLastName によって呼び出され、tBirthDate uで生まれ、GenderCode を持ちv、TwitterProfile wでツイートし、PhoneNumber x経由で連絡され、EmailAddress経由で連絡yされ、CreatedDateTimeに登録されましたz

このようなレイアウトは非常に有利です。JOIN句を使用して複数のテーブルから列を収集するSELECT操作など、連続して非常に正確な意味を持つ新しいテーブルを導出できるためです(セクションを参照)。下記の「ビュー」というタイトルの)。

この構成では、(i)サブタイプのインスタンスを表す行は、(ii)相補的なスーパータイプの発生を示す行を区別する同じPRIMARY KEY値によって識別されることは言及しません。したがって、次のことに注意するのは適切なことではありません。

  • (a)システム生成およびシステム割り当てのサロゲート8を保持するための追加の列のアタッチ(b)サブタイプを表すテーブルは(c)完全に不要です。

この論理設計では、新しいサブタイプがビジネスコンテキストに関連するものとして定義されている場合、新しいベーステーブルを宣言する必要がありますが、それは他の種類のエンティティタイプが重要であると見なされた場合にも発生するため、状況は次のようになります。事実、普通。

ビュー

たとえば、ActorDirector、またはWriterに対応するすべての情報を「フェッチ」するために、いくつかのビュー(つまり、派生テーブルまたは表現可能なテーブル)を宣言して、1つのリソースから直接選択し、毎回の結合について; たとえば、以下でVIEWを宣言すると、「完全な」アクター情報を取得できます。

--
CREATE VIEW FullActor AS

    SELECT P.FirstName,
           P.Lastname,
           P.BirthDate,
           P.GenderCode,
           P.TwitterProfile,
           P.PhoneNumber,
           P.EmailAddress,
           A.Headshot,
           E.Name AS Ethnicity
         FROM Person P
         JOIN Actor A
           ON A.ActorId     = P.PersonId
         JOIN Ethnicity E
           ON E.EthnicityId = A.EthnicityId;
--

もちろん、「完全な」ディレクターライターの情報を取得するために、同様のアプローチをとることができます。

--
CREATE VIEW FullDirector AS

    SELECT P.FirstName,
           P.Lastname,
           P.BirthDate,
           P.GenderCode,
           P.TwitterProfile,
           P.PhoneNumber,
           P.EmailAddress,
           D.Bio,
           D.Etcetera
         FROM Person P
         JOIN Director D
           ON D.DirectorId = P.PersonId; 

--
CREATE VIEW FullWriter AS

    SELECT P.FirstName,
           P.Lastname,
           P.BirthDate,
           P.GenderCode,
           P.TwitterProfile,
           P.PhoneNumber,
           P.EmailAddress,
           L.Name AS Location,
           C.Name AS Country
         FROM Person P
         JOIN Writer W
           ON W.WriterId     = P.PersonId
         JOIN Country C
           ON C.CountryCode  = W.CountryCode
         JOIN Location L
           ON L.LocationCode = W.LocationCode;   
--

MySQL 5.6で実行されているこのSQL Fiddleで説明されているすべてのDDLステートメントとDMLビューを投稿したので、それらを「実際に」見て、テストできます。


文末脚注

1一部の概念モデリング手法では、スーパータイプとサブタイプの関連付けは、スーパークラスとサブクラスの関係と呼ばれます

2 人には実際にはより多くの役割が存在する可能性があると述べましたが、明らかにした3つの役割は、いくつかの重要な影響を明らかにするシナリオを説明するには十分です。

3ただし、ご指摘のとおり、将来、アクターは最終的に1 対多のURLを提供する可能性があります

4 情報モデリングの統合定義IDEF1X)は、1993年12月に米国国立標準技術研究所(NIST)によって標準として確立された、非常に推奨されるモデリング手法です。これは、(a)データの関係モデルの唯一の創始者、つまりEF Codd博士によって作成された初期の理論的研究に基づいています。(b)PP Chen博士によって作成されたエンティティ関係ビュー。また、(c)Robert G. Brownが作成した論理データベース設計手法についても説明します。

5 IDEF1X標準では、キーの移行を「親またはジェネリック[スーパータイプ]エンティティの主キーを子またはカテゴリエンティティ[サブタイプ]に外部キーとして配置するモデリングプロセス」と定義しています

6 IDEF1Xでは、ロール名は、それぞれのエンティティタイプのスコープ内で保持する意味を表すために、FK属性に割り当てられる独特のラベルです。

7当然のことながら、仮想の概念プロパティ(および論理列)Director.EtceteraおよびUserProfile.Etceteraは除きます。これらは、対応する概念エンティティタイプに適用されるプロパティ(および列)を追加する可能性を公開するために使用した単なるプレースホルダーです。 (および論理テーブル)。

8たとえば、MySQLで「実行中」のデータベースのテーブルにAUTO_INCREMENT属性を持つ追加の列を追加します。


2

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

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            'Joe@Example.com'
1         1            '@joe'
1         3            '555-555-5555'
1         5            'www.example.com/pics/myFace.png'

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

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

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


ああ、それはある意味で理にかなっていると思います...しかし、私はどのようにしているかははっきりしていません-たとえば-たとえば、すべての俳優とそのユーザー名をリストします(俳優-yデータが別のテーブル)。
ヴェリズム2017

私の編集を参照してください。クエリの例を追加しました。
CaM 2017

とても助かります、ありがとう。私の質問では完全に明確ではなかったと思います-すみません。各タイプ(Actor、Directorなど)のテーブルには、そのユーザータイプにのみ関連する独自の固有の属性セットがあることを明確にすべきです。たとえば、俳優にはヘッドショット(写真)がありますが、ライターにはありません。これについてもっと明確にしないでください。
ヴェリズム2017

連絡方法は素晴らしい解決策のようです。
ヴェリズム2017

1
写真などの要件を満たすために、属性に変更しました。これで、より適切になります。
CaM 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.