2009-05-13 17 views
0

私は(ID、FIRST_NAME、MIDDLE_NAME、LAST_NAME、性別) と私は携帯電話の表のように、第二種の同様のテーブルを持つことになる(id_fk、email_add)この特定のシナリオでは主キーが必要ですか?

Infactはとの電子メールテーブルと名のテーブルを持っています(id_fk、phone_no)。ここで、id_fkは、名前テーブルのidを参照する外部キーです。

2番目と3番目のテーブルにプライマリキーを持つのは正当な理由ですか?または他の同様のテーブル?あるいは、別のスキーマを提案しますか?

PS:テーブルは、行がそうでない場合、共有順不同のコレクションを表し、持っていないため、主キーは(id_fk、PHONE_NO)テーブル全体で、あなたが記述例ではアプリ

答えて

1

あなたは、ほとんどの場合、主キーを使用したほうが良いです。データベースが拡大して複雑になるにつれて、今必要ではないと思っても、すぐに問題なしに問題に遭遇します。

個人的には、guid/uuid/serialなどのプライマリキーにデータに依存しない列を使用することをおすすめします。使用可能なデータが含まれていないフィールドを使用することで、データベースが大きくなると、別の乱雑な操作になる可能性のある主キーを更新する必要がない状況になることはありません。

+0

私が質問したのは、データベースを勉強しているうちに、私は実際の経験(プロジェクト)を使っていないということです。 "データベースが拡大して複雑になるにつれて、すぐに問題が発生しなくなります。 あなたは親切に私に例を与えることができますか?私が持っているかもしれない問題のように。 あなたのアドバイスは健全ですが、私はすべてのテーブルに生成されたpkを使用する傾向があります。 – Sujoy

+1

3番目のテーブル(id_fk、phone_no)では、プライマリキーはid_fkとphone_noの複合キーです。これは、プライマリキーを変更するときにphone_noを変更する必要がない場合に意味します。さらに、後であなたのアプリケーションを強化し、仕事、携帯電話番号、自宅の番号などを持っていて、ユーザーがすべて同じ番号を入力すると、重複した主キーエラーで挿入が失敗します。 – sipwiz

+0

その場合、電話番号テーブルには「タイプ」という3番目の列があり、複合主キーは(id_fk、phone_no、type)である必要があります。 –

4

を格納接触するためのものです独自のアイデンティティーではなくむしろ価値観だけである。

+0

はい私もそれを認識しました。しかし、後にpkを変更する問題に関するsipwizの答えの後、私は半分pkを使いたいと思う。 – Sujoy

1

複合主キーを(外部キー、電話番号)にすることができます。

個人的に私は厳密にテクニカルプライマリキーの使用を薦めま​​す。通常、オートナンバーIDカラムを意味します。利点の1つは、HTMLフォームなどの古い値を覚えておくのではなく、IDを使用してレコードを更新および削除する方が簡単になるということです。

2

これらの各テーブルに単純な自動増分「id」主キーを追加すると、コストが低く、後で特定の行を参照しやすくなります。

外部キーの別の命名体系を見るとよいかもしれません。 "id_fk"は、それが参照しているテーブルの "id" name_id "が良い選択かもしれません。

+0

私は外部キー列の名前付けに関するTobiasのコメントに同意します。命名規則 'parent_id'(parentは参照先テーブルの名前)を使うのは良い考えです。 'fk'を使用して、列ではなく外部キーCONSTRAINTに名前を付けます。 – spencer7593

1

すべてのテーブルには必ずプライマリキーが必要です。 (id_fk、phone_no)の場合は、両方の列からなる複合キーを使用するか、別の列を主キーとして追加することができます。私は最終的にはすべての複雑さを軽減し、ORMを使用している場合にはさらに快適になるので、後者をお勧めします。

0

電子メールアドレスと電話番号に別のテーブルが必要なのはなぜですか?それらをすべて同じテーブルに格納する方がずっと効率的です。あなたのスキーマは次のようになります。

(擬似SQL)

Create table ContactName (
     CONTACT_ID integer not null default auto_increment, 
     etc 
     ) 

CREATE TABLE TELECOM_CLASSES (
    CLASS_ID INTEGER NOT NULL DEFAULT AUTO_INCREMENT, 
    CLASS_NAME VARCHAR(200) NOT NULL 
       CHECK (CLASS_NAME IN ('email','tel','fax',etc)), 
    etc 
    ); 

CREATE TABLE CONTACT_TELECOMS (
    TELECOM_ID INTEGER NOT NULL DEFAULT AUTO_INCREMENT, 
    CONTACT_ID INTEGER NOT NULL REFERENCES CONTACTNAME (CONTACT_ID), 
    CLASS_ID INTEGER NOT NULL REFERENCES TELECOMS_CLASSES (CLASS_ID), 
    TELECOM VARCHAR(200) NOT NULL, 
    etc 

); 
+0

したがって、CLASS_IDが電子メールの場合、TELECOMに電子メールアドレスがあります。うーん、私はアイデアを得るが、これはどのようにこれはより多くのeficient以来、私はメールが必要なときに私はちょうど任意のCLASS_IDを気にせずに電子メールテーブルに対してクエリすることができます別のテーブルと – Sujoy

+0

これはあなたがポストオフィスボックスのように追跡する別のエンティティを追加することができます。また、ユーザーのためにすべてを照会し、すべての表を結合することなくリストするのが簡単になります。あなたが失うものは、データベースレベルで電話番号と電子メールアドレスの形式を制御する能力です。私は適切なロジックを持つトリガーがそれを処理できると思います。 – JeffO

+0

一部のテーブル名が_SINGULAR_で、一部が_PLURAL_であるという規則に注意してください。クラスに名前を付けます。表の中の1つの行の名前を指定します。 – spencer7593

2

私のデザイン哲学は、すべてのテーブルは、常に単一のint型のアイデンティティPK列を持っていることです。

これは以前のコメントで示されているように、これは議論の余地があると思われますが、非常に便利です。

+0

複数の複合キーを使用してデータベースにアドホッククエリを書き込むだけで、それらを繰り返したり進めたりすることができます。 – JeffO

+0

説明した練習には利点と欠点があります。このスペースは、これらの利点と欠点を完全に議論したり、他の設計プラクティスと比較するにはあまりにも窮屈です。私は、それが論争を経ずに挫折と侮辱に終わらせることができれば、他のところで問題を追求したいと思う。 –

関連する問題