2013-07-01 6 views
7

私は次のデータベースを作成する必要があります。車のために、私はのみ3つのサブタイプを持っている必要がありながら、半トラック用のMySQL - スーパータイプ/サブタイプのデザイン

enter image description here

私は、余分なサブタイプを必要としないとセダンにも私は4つのサブタイプが必要です。 SELECTの場合は、JOIN(正規化されたデータベース)を使用しますが、INSERTを行う簡単な方法を見つける必要があります。

  • 準決勝カー・テーブルの

    • 車両テーブルに共通の情報
    • セミトラックの店舗固有の情報は3つのサブタイプ
    • バン、SUVにリンクされている車やcar_typeフィールドの特定のフィールドを持ち、セダン(と私はそれらが必要ならば他のタイプ)は1つのテーブルにある必要がありますCAR_TYPE
    • しかし、セダンタイプのために、私は別のテーブルに含まれるべきであるかもしれない追加のサブタイプを持つ必要があります。これらのサブタイプはSuvsとVansでは必要ありません(実際のSUVでは、バンはセダンと同じサブタイプを持つことができますが、私の場合はそうではありません)。

    このデータベースは、ダイアグラムのとおりに作成する必要があります。

    • 車種:

      はこれまでのところ、私の最初のアプローチは、以下の表持つことである、...、veh_id、veh_type(セミ、車を)other_fields

    • Vehicle_semis:veh_id、...、 other_semis_fields
    • Vehicle_car:veh_id、car_type(バン、SUV、セダン)、
    • Car_type other_car_specific_fields:car_type_id、タイプ
    • Sedan_type:sedan_type_id、タイプ

    私の問題は、これが正しいアプローチであるかどうかわからないことです。テーブル間の関係を作成する方法を正確にはわかりません。

    アイデア?

    ありがとうございました!

    UPDATE:次の図は、@マイクの答えに基づいています

    enter image description here

    +0

    最初のステップは、デザインがそれぞれのケースごとに非常に異なるため、このデータベースの主な(最も使用されている)操作は何かを判断することです。それは将来的に成長するでしょうか?もしそうならどれくらい?何人のクライアントがデータベースに問い合わせますか?どのくらいの頻度で ?これらはあなたが知る必要があるちょっとした質問です – Stephan

    +0

    @Stephan - データは将来的には100kに成長するでしょう。私の主な操作はREADです。クライアントに関しては、かなり多くの人がdbで作業するでしょう! – Cristian

    +0

    あなたが意図したスキーマ内の問題は、データが「非常に」正規化されているために読み込まれています...あなたが以前にいくつかのセダンを取得しなければならない場合、それは多くのユーザーにとっても問題ではありません。私はInnoDBエンジンを使用することをお勧めします.URLアプリケーションの2つの重要な機能があります:トランザクションサポートと行レベルロック – Stephan

    答えて

    7

    私が始める前に、私は 『ガス』は、燃料や種類のいずれかを記述していることを指摘したいですエンジンの、一種のセダンではない。あなたがこの道を歩いて行く前に、一生懸命考えましょう。 (セマンティクスは、ほとんどの人が考えるよりもデータベース設計において重要です。)

    あなたがしたいことは、かなりシンプルですが、必ずしも簡単ではありません。この種のスーパータイプ/サブタイプ設計(排他的アークとも呼ばれます)の重要な点は、セダンについての行がセミ・トラックなどについて行を参照することを不可能にすることです。

    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}一対の外部キー参照のターゲットとすることができます。つまり、「car」行は誤って「semi」行を参照することはできません。

    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をと宣言しています。あなたがなどgas_sedans、diesel_sedans、としてセダンを参照する追加のテーブルを構築する必要がある場合

    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'); 
    

    は、その後、あなたは「veh_type_is_car」と彼らに設定外部キー参照に似て1行のテーブルを構築する必要があります。

    製造において、私はベーステーブル上の権限を取り消すと、いずれかの挿入および更新、または挿入および更新を行うための

  • ストアドプロシージャを実行するために

    • 更新可能なビューを使用すると思います。
  • +0

    この答えにはとても感謝している。それはまさに私が必要なものです!私が完全に理解していないことの1つは、 "cars_type_is_car"で、 "cars"テーブルの "veh_type_code"と同じコード "c"を持ちます。より良いコーディングやクエリを手助けするだけですか?車両と車との関係にはコード「c」も含まれています。なぜそのテーブルを追加するのですか? – Cristian

    +0

    @Cristian:そのテーブルを参照する "車"には外部キーがあります。その行が車に関するものであれば、その列には「*のみ」の「c」が表示されます。つまり、「車」のセミトラックの列が「車」の車の列にリンクされないようにします。 –

    +0

    さて、それを得ました。私は、 "c"だけを "cars"テーブルにすることも、コードでも実装できることを保証する役割を担っていると思います。 mysqlとコードの両方でそれを持つのは大変なことでしょうか?残酷? – Cristian

    3

    私は、次の3つのタグの下に「情報」タブにあなたを参照してください。

    最初の二つは、クラス/サブクラスに対応するために2つの主要なデザインパターンを記述(別名タイプ/サブタイプ)状況を示します。三つ目は、スーパークラス・テーブルに割り当てられたサブクラス・テーブルに伝播される単一のプライマリ・キーを使用する方法を示しています。

    あなたが提出した質問に完全には答えられませんが、全体の話題を少し明るく説明しています。 SQLの継承を模倣するこのトピックは、SOとDBAの両方の領域で何度も何度も繰り返されています。

    +0

    ありがとう!読むための大きなリソース。 – Cristian