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

MySQL-スーパータイプ/サブタイプの設計

    始める前に、「ガス」はセダンの一種ではなく、燃料またはエンジンの一種を表すことを指摘したいと思います。この道を進み続ける前に、よく考えてください。 (データベース設計では、ほとんどの人が考えるよりも意味論が重要です。)

    あなたがやりたいことはかなり単純ですが、必ずしも簡単ではありません。この種のスーパータイプ/サブタイプ設計(排他的アークとも呼ばれます)の重要なポイントは、セミトラックなどに関する行を参照するセダンに関する行を作成できないようにすることです。

    MySQLは、CHECK制約を強制しないため、コードをより冗長にします。幸運ですね;アプリケーションでは、CHECK制約を追加のテーブルと外部キー制約に置き換えることができます。コメントは、上記のSQLを参照しています それら。

    create table vehicle_types (
      veh_type_code char(1) not null,
      veh_type_name varchar(10) not null,
      primary key (veh_type_code),
      unique (veh_type_name)
    );
    
    insert into vehicle_types values
    ('s', 'Semi-truck'), ('c', 'Car');
    

    これは、他のプラットフォームでCHECK制約として実装するようなものです。コードの意味がユーザーに明らかな場合は、これを行うことができます。ユーザーは、「s」がセミを表し、「c」が車を表すこと、またはビュー/アプリケーションコードがユーザーからコードを隠すことを知っているか理解することを期待します。

    create table vehicles (
      veh_id integer not null,
      veh_type_code char(1) not null,
      other_columns char(1) default 'x',
      primary key (veh_id),
      unique (veh_id, veh_type_code),
      foreign key (veh_type_code) references vehicle_types (veh_type_code)
    );
    

    UNIQUE制約により、列のペア{veh_id、veh_type_code}を外部キー参照のターゲットにすることができます。つまり、「車」の行は、誤って「半」の行を参照できない可能性があります。

    insert into vehicles (veh_id, veh_type_code) values
    (1, 's'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'c'), 
    (6, 'c'), (7, 'c');
    
    create table car_types (
      car_type char(3) not null,
      primary key (car_type)
    );
    
    insert into car_types values
    ('Van'), ('SUV'), ('Sed');
    
    create table veh_type_is_car (
      veh_type_car char(1) not null,
      primary key (veh_type_car)
    );
    

    他のプラットフォームでCHECK制約として実装する他の何か。 (以下を参照してください。)

    insert into veh_type_is_car values ('c');
    

    これまでに1行だけ。

    create table cars (
      veh_id integer not null,
      veh_type_code char(1) not null default 'c',
      car_type char(3) not null,
      other_columns char(1) not null default 'x',
      primary key (veh_id ),
      unique (veh_id, veh_type_code, car_type),
      foreign key (veh_id, veh_type_code) references vehicles (veh_id, veh_type_code),
      foreign key (car_type) references car_types (car_type),
      foreign key (veh_type_code) references veh_type_is_car (veh_type_car)
    );
    

    veh_type_codeのデフォルト値と、veh_type_is_carへの外部キー参照により、このテーブルのこの行は車に関するもののみであり、のみであることが保証されます。 車である参照車両。他のプラットフォームでは、列veh_type_codeをveh_type_code char(1) not null default 'c' check (veh_type_code = 'c')として宣言します。 。

    insert into cars (veh_id, veh_type_code, car_type) values
    (2, 'c', 'Van'), (3, 'c', 'SUV'), (4, 'c', 'Sed'),
    (5, 'c', 'Sed'), (6, 'c', 'Sed'), (7, 'c', 'Sed');
    
    create table sedan_types (
      sedan_type_code char(1) not null,
      primary key (sedan_type_code)
    );
    
    insert into sedan_types values
    ('g'), ('d'), ('h'), ('e');
    
    create table sedans (
      veh_id integer not null,
      veh_type_code char(1) not null,
      car_type char(3) not null,
      sedan_type char(1) not null,
      other_columns char(1) not null default 'x',
      primary key (veh_id),
      foreign key (sedan_type) references sedan_types (sedan_type_code),
      foreign key (veh_id, veh_type_code, car_type) references cars (veh_id, veh_type_code, car_type)
    );
    
    insert into sedans (veh_id, veh_type_code, car_type, sedan_type) values 
    (4, 'c', 'Sed', 'g'), (5, 'c', 'Sed', 'd'), (6, 'c', 'Sed', 'h'),
    (7, 'c', 'Sed', 'e');
    

    gas_sedans、diesel_sedansなどのセダンを参照する追加のテーブルを作成する必要がある場合は、「veh_type_is_car」と同様の1行のテーブルを作成し、それらに外部キー参照を設定する必要があります。

    本番環境では、ベーステーブルの権限を取り消し、

    を使用します。
    • 挿入と更新を行うための更新可能なビュー、または
    • 挿入と更新を行うためのストアドプロシージャ。


    1. SQLクエリを高速化する方法は?インデックス?

    2. SQL Server数学関数(完全なリスト)

    3. mysql auto_increment by 5?

    4. SQLServerでのアラートと演算子の使用