- ベストアンサー
データベース設計手法について
データ重複を避けるためのPK以外に、シーケンシャルなカラム(id)にindexを貼ってFKとしようとしています。 このような設計手法って一般的でしょうか?呼び名とかあるのでしょうか? 例) id(index) customer_id(pk) member_id(pk)
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
通常はidの方をPrimary Keyにして(custmer_id,member_id)でunique indexを作成します。このような場合は、シーケンシャルに符番するidを人工キーと呼びます。 なぜ、このような作り方をするかというと、primary keyは変化しない項目の方が望ましいからです。
その他の回答 (7)
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
補足:タイプ4! id______________PK customerNum_____普通の列 memberNum_______普通の列 これがタイプ4。 表:受注台帳 id____________1 sdate_________2011/12/12 customer_id___1 ・・・・・ この表「受注台帳」は、正にタイプ4。 回答1で述べているように、私がよく採用しているタイプ。 >その場合、想定されるテーブル構造は次の3つです。 当然に、タイプ4は存在しますよ。 例は、このタイプ4なのかな?
お礼
いろいろご回答ありがとうございました。実際の業務で使われている構成ですので、あまり細かいニュアンスは伝えることが出来ませんでした。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
プロの方の回答が付かないので、私が例を理解できない理由を3つ。 1、テーブルと列とが何を意味するのか不明。 PKを[id]、FKを[tableName_id]と表記すると仮定します。その場合、想定されるテーブル構造は次の3つです。 タイプ1: id______________PK customer_id_____FK member_id_______FK タイプ2: id______________PK member_id_______FK タイプ3: id______________PK memberNum_______普通の列 質問者の例は、この3タイプのいずれでもありません。 2、PKとFKという表現が何を意味するのか? PK・・・・テーブルの先頭列のみに出現。 FK・・・・テーブルの先頭列以外に出現。 前述の3タイプでも、かかるルールでそれぞれが出現しています。 >indexを貼ってFKとしようとしています。 ですから、これが判りません。 3、例そのものに対する疑問。 列[customer_id]が顧客を一意に特定するユニークなコード、あるいは数値だと仮定。この場合、複合キーを設定する必要はありません。また、ユニークキー以外にユニークな列[id]を付加する理由もありません。 疑問1、なぜに、列[customer_id]はユニークではないのか? 疑問2、なぜに、列[customer_id]と列[member_id]とで複合キーを作成するのか? 仮に、列[customer_id]が何らかの事情でユニークでないとすれば、そういう場合は、列[id]を主キーとして用意するのは誰もが普通にやっていること。でも、質問文からは、そういうニュアンスは伝わってこない。 以上が、私の疑問です。
- yamada_g
- ベストアンサー率68% (258/374)
例のような場合であれば、idをPKにしてcustomer_id,member_idにユニーク制約を付けるというのが自然だと思います。 「サロゲートキー データベース」などで検索してみてください。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
例の意味合いが理解不能! 第一、[customer_id]と[member_id]は重複することがないでしょう。 PKなんですからユニークの筈。 だから、PK以外にFKの必要もないし意味不明! 仮に、幾つかのインデックスを持たせられる列の他に列[id]を設けるとすれば、それが主キー。 FK云々という話ではないのでは・・・。 *よく、質問が理解できませんので補足は不要です。 *プロの回答をお待ちください。
補足
回答者様の例ではidしかPK指定されていませんよ? 以下のSQLの2つめでエラーにならないと思いますが。。ここがエラーになることが大前提です。 尚、あえて正規化をしない状態での質問ですので、「正規化すること」という回答はご遠慮下さい。 insert into table (customer_id, member_id) values (1,1); insert into table (customer_id, member_id) values (1,1);
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
補足を読まないで訂正を送信。 補足を読んで意味が判りました。 表:受注台帳 id_________________1 <-------------PK sdate____________2011/12/12 customer_id___1 ・・・・・ 表:受注明細 salesMain_id__1 <-------------FK rowNumber___1 ・・・・・ PKとFKって、こういう関係かと思いますが・・・。 PK+FKというケースがありますか?
補足
いろいろ書いていただいて恐縮ですが、私の例を元にお考え下さい。 回答者様の例のように、idだけをPKにすると、customer_idとmember_idの組み合わせが同じ場合でも挿入できてしまいますよね? 重複チェックはアプリ側ではなく、あくまでデータベース側で行いたいため、このような設計にしています。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
お詫びと訂正:受注履歴の複合キーは重複しない! あたかも、表「受注履歴」の複合キーが重複するかのように述べましたが、これは勘違いでした。確かに、同日に同一顧客からの受注は重複して発生します。しかし、この場合は、受注台帳という主表に何時、誰がを記録し、その詳細は受注明細という従表に控えるのが一般的。この場合、主表と従表とを連結させるために<受注台帳.id>を設けます。 前回回答の複合キーと[id]との関係の記述は、このように大きく訂正します。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
Q、このような設計手法って一般的でしょうか? A、質問の主旨が・・・??? 表「SPERSON」(営業マン)の類ではなく表「CONTACT](商談情報)などを問題にしているのでしょうか? 表:SPERSON id_________1 position___1 lname______Bell fname______Robert ・・・・・ 表:CONTACT(1) cdate______1986/04/15 sperson_id_1 ndate______1986/06/01 nemp_______126 ・・・・・ 表:CONTACT(2) id_________1 cdate______1986/04/15 sperson_id_1 ndate______1986/06/01 nemp_______126 ・・・・・ その場合、表「CONTACT」の主キー列[id]は不要と言えば不要。必要と言えば必要。表CONTACTの情報を登録順に表示するのに都合が良いDBもあれば、そうでないDBも。 >データ重複を避けるため・・・ 表「CONTACT」が商談情報ではなく受注履歴情報だとすれば・・・。その場合には、列[sdate]と列[sperson_id]との組み合わせで重複が発生します。この場合、複合キーとして処理する手が存在します。例示(1)のやり方です。そうではなくて、(2)のやり方もあります。後者の場合、「登録順表示の容易さ」が確保されるかも知れません。前者は、少なくとも1980年代の主流だったのではと推察します。手元のUNIXのデータベースのサンプルは全て前者で統一されていますから・・・。 >PK以外に、シーケンシャルなカラム(id)にindexを貼ってFKとしようとしています。 これが、(1)の設計を意図しているのか?それとも、(2)に相当するのか?質問の主旨が判然としません。 ただ言えることは、1980年代と違って格段にハードの性能が向上しています。ですから、テーブル設計の正規化を志向しつつ<アプリケーションのコードが簡単になる設計>を採用するのが今のやり方。と、私は思います。そして、私自身は、(2)のタイプで設計してきました。 *PS、補足を! 私は、まったくの素人プログラマ。プロの方のちゃんとしたアドバイスを受けられるには、ちょっと質問の主旨を補足されるべきかと・・・。私の回答が、補足のヒントになれば幸いです。
補足
「本来のPK以外にFK用にid列を付ける設計」というものが一般的なのか気になって。。
お礼
ありがとうございました。勉強になりました。