2011-12-26 33 views
1

これは状況です。複合主キーと外部キーとしてのユニークキー

  • 大学には複数の教員がいます。
  • 各学部には複数の部門があります。

私は重複した教員や部署を望んでいません。そこで以下の3つの表を定義しました。

CREATE TABLE university (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    long_name VARCHAR(255) UNIQUE NOT NULL, 
    name VARCHAR(255) NOT NULL, 
    country VARCHAR(45) NOT NULL, 
) Engine=InnoDB; 

CREATE TABLE school_faculty (
    id INT UNIQUE NOT NULL AUTO_INCREMENT, 
    name VARCHAR(45), 
    universityID INT, 
    PRIMARY KEY (name, universityID), 
    FOREIGN KEY (universityID) REFERENCES university (id) 
) Engine=InnoDB; 

CREATE TABLE department (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    name VARCHAR(45) NOT NULL, 
    schoolfacultyID INT NOT NULL, 
    FOREIGN KEY (schoolfacultyID) 
     REFERENCES school_faculty (id) 
) Engine=InnoDB; 

これが間違っている場合や、より良い方法がある場合は教えてください。私はそれに苦労していて、まったく無力です。

+0

投稿の冒頭にある2つの箇条書きに基づいて、これまでのところ正しいようです。 – TetonSig

+2

適切な[サンプルコード](http://sscce.org/)(ここではSQL文)は、任意の特別なスキーマやサンプルデータ形式よりも有用です。あなたのサンプルに 'CREATE TABLE'を使ってください。 – outis

+0

が更新されました:テーブル構造が添付されました – stanchen

答えて

0

okと思われます。

ちょうどfalculty/department名のテーブルを持ち、あなたのdepartment/falcultyテーブルを(universityID、facultyNameID)に変換することで、もう少し正常化することができます。しかし、そのレベルの正規化はおそらく過剰です。物理学やバスケットウィービングの教員が全大学に1つ多く存在する可能性は非常に高いですが、テーブルに「物理学」という言葉を複数コピーして使用する余分なバイト数は、銀行を破ることはありません。

同じことが部門にも適用され、同じことが「おそらく問題ではない」と同じです。

+0

私は、教員や部署が重複することを望んでいます。自動増分ユニークキーがプライマリキーで、他の2つの列がコンポジットプライマリキーであるテーブルを持つのはなぜいいのか分かりません。 (この場合、教職員テーブル) – stanchen

+0

代理キーと呼ばれています。これらの部門IDを他の場所の外部キーとして使用する場合は、完全な大学/教員/部門キーセットをドラッグするのではなく、その1つのIDフィールドの周りを移動する方が簡単です。 –

+0

私は同意します!それは代理キーを持つ私のポイントです。元の投稿をテーブル構造のイメージに更新しました。だから私の設計によれば、それは適切に構造化されていますか?もっと良い方法? – stanchen

-1

school_facultyテーブル以外は問題ありません。

CREATE TABLE school_faculty (
    id PRIMARY KEY AUTO_INCREMENT, 
    name VARCHAR(45), 
    universityID INT, 
    UNIQUE (name, universityID), 
    FOREIGN KEY (universityID) REFERENCES university (id) 
) Engine=InnoDB; 

コンポジットキーではなく、PKとして整数列を使用することをお勧めします。 InnoDBテーブルでは、PKはclustered indexなので、PKの最小データ型を使用すると、MySQLはインデックスごとにより多くのデータを読み取ることができます。ほとんどの場合、プライマリキーは自動インクリメントである方が良いです。これにより、簡単に並べ替えることができます(基本的には既に注文されています)。

さらに、セカンダリ(クラスタ化されていない)インデックスは、PKからのデータを格納します。より小さいタイプを使用すると、セカンダリインデックスが占めるスペースが小さくなります。セカンダリインデックスを使用するクエリでは、PKを使用して実際の行データにアクセスする必要があるため、PKを使用してアクセス時間を改善するメリットがあります。

また、特定の教員の部署が重複しないように、部門(name、schoolfacultyID)に一意のキーを追加する必要があります。

希望します。

+0

もし私がそうするなら、それは同じuniversity_idを持つ異なるfaculty_nameを許可しないでしょう。 – stanchen

+0

これは悪いデザインです。あなたは、指定された大学とはまったく異なる大学にある教員に割り当てられた部門を持つことができます。 –

+0

@stanchen:school_facultyのユニークなインデックス(name、universityID)がコンポジットなので、そうではありません。 – outis