sql >> データベース >  >> RDS >> Mysql

継承構造を中心とした関係の設計

    同様の質問がありますここ メディアスーパータイプを使用し、CD、VCR、DVDなどのサブタイプを追加します。

    これは、たとえばBluRayサブタイプを作成する際に、BluRay固有のデータを含むテーブルを作成し、MediaTypesテーブルにエントリを追加するという点でスケーラブルです。既存のデータやコードに変更を加える必要はありません。もちろん、BluRayデータで機能するコードを追加する場合を除きます。

    あなたの場合、UsersはTeachersとStudentsのサブタイプテーブルを持つスーパータイプテーブルになります。

    create table Users(
        ID      int not null auto_generating,
        Type    char( 1 ) check( Type in( 'T', 'S' )),
        -- other data common to all users,
        constraint PK_Users primary key( ID ),
        constraint UQ_UserType unique( ID, Type ),
        constraint FK_UserTypes foreign key( Type )
            references UserTypes( ID )
    );
    create table Teachers(
        TeacherID int not null,
        TeacherType char( 1 ) check( TeacherType = 'T' )),
        -- other data common to all teachers...,
        constraint PK_Teachers primary key( TeacherID ),
        constraint FK_TeacherUser foreign key( TeacherID, TeacherType )
            references Users( ID, Types )
    );
    

    Studentテーブルの構成は、Teachersテーブルと似ています。

    教師と生徒の両方が他の教師と生徒を雇用する可能性があるため、この関係を含むテーブルはユーザーテーブルを参照します。

    create table Employment(
        EmployerID    int not null,
        EmployeeID    int not null,
        -- other data concerning the employment...,
        constraint CK_EmploymentDupes check( EmployerID <> EmployeeID ),
        constraint PK_Employment primary key( EmployerID, EmployeeID ),
        constraint FK_EmploymentEmployer foreign key( EmployerID )
            references Users( ID ),
        constraint FK_EmploymentEmployee foreign key( EmployeeID )
            references Users( ID )
    );
    

    私が理解しているように、通知は雇用主ごとにグループ化されています:

    create table Notifications(
        EmployerID    int not null
        NotificationDate date,
        NotificationData varchar( 500 ),
        -- other notification data...,
        constraint FK_NotificationsEmployer foreign key( EmployerID )
            references Users( ID )
    );
    

    クエリは十分に単純である必要があります。たとえば、ユーザーが雇用主からのすべての通知を表示したい場合:

    select  e.EmployerID, n.NotificationDate, n.NotificationData
    from    Employment  e
    join    Notifications n
        on  n.EmployerID = e.EmployerID
    where   e.EmployeeID = :UserID;
    

    もちろん、これは最初のスケッチです。改良が可能です。しかし、あなたの番号のポイントに:

    1. 雇用表は、雇用者と従業員を関連付けています。ユーザーを雇用主にするかどうかの唯一のチェックは、自分自身を雇用することはできませんが、そうでない場合は、どのユーザーも従業員と雇用主の両方になることができます。
    2. Usersテーブルは、各ユーザーを教師('T')または学生('S')のいずれかに強制します。 「T」として定義されたユーザーのみをTeachersテーブルに配置でき、「S」として定義されたユーザーのみをStudentsテーブルに配置できます。
    3. Employmentテーブルは、Usersテーブルにのみ結合し、TeachersテーブルとStudentsテーブルの両方には結合しません。しかし、これは、教師と生徒の両方が、パフォーマンス上の理由ではなく、雇用者と従業員の両方になることができるためです。一般に、初期設計中のパフォーマンスについて心配する必要はありません。この時点での主な関心事は、データの整合性です。リレーショナルデータベースは、結合に非常に適しています。 もし パフォーマンスの問題が発生し、修正する必要があります。まだ存在しておらず、存在しない可能性のある問題を解決するためにデータを再構築しないでください。
    4. では、これを試してみて、どのように機能するかを確認してください。



    1. MySQLはどのようにデータを保存しますか

    2. OracleDatabase18cでのCDBフリートの管理

    3. SpringBatch-Postgresでメタデータテーブルを作成して実際のデータをmysqlにロードすることができません

    4. SQLServerの地理データ型を理解する方法