0

次のデータベースで、最初の 1:m リレーションと 2 番目の 1:m リレーションの間にジャンクション テーブルを作成する利点は何ですか?

代替テキスト http://dl.getdropbox.com/u/175564/db/db-simple.png

Joe Celko の本 tree and Hierarchies in SQL for Smarties には、その理由は 1:m で一意の関係を持つためであると書かれています。たとえば、次の表は、ユーザーがまったく同じ質問を 2 回し、まったく同じ回答を 2 回することをそれぞれ制限しています。

最初の 1:m リレーション

users-questions
===============
user_id REFERENCES users( user_id )
question_id REFERENCES questions ( question_id )
PK( user_id, question_id)           // User is not allowed to ask same question twice 

2 番目の 1:m 関係

questions-answers
=================
question_id REFERENCES questions( question_id)
answer_id REFERENCES answers( aswer_id )
PK( question_id, answer_id )       //  Question is not allowed to have to same answers

一意性に関するこの利点は、自分のコードをより難しくすることを私に納得させません。おそらくPHPを使用してそれを禁止できるため、dbに同じIDを持つ質問または回答を持つ可能性を制限する必要がある理由を理解できません。

4

3 に答える 3

3

ええと、ユニークな関係のことは私には無意味に思えます。おそらく、主キー以外のユニークなキーを定義できるDBMSに慣れているからでしょう。私の世界では、このようなマッピングテーブルは、多対多の関係を実装する方法であり、1対多の関係にそれらを使用することは狂気です。つまり、そうする場合は関係を1対多として使用されますが、実際に実装したのは多対多のサポートです。

ただし、永続層に一意の複合キーのユーティリティがないことについてあなたが言っていることに同意しません。アプリケーション層でそれを強制できるからです。永続層の一意性制約には、MySQLでを利用できるなど、複製が難しい多くの利点がありINSERT ... ON DUPLICATE KEY UPDATEます。

于 2009-08-11T23:21:34.613 に答える
2

通常、データの重複が原因です。

あなたの推論については、ビジネス層でこれを強制することはできますが、間違えるとかなりの量のコードが壊れる可能性があります。問題は、データ モデルにいくつかのテーブルしかない可能性があることです。あなたはラッキーです。データ モデルが大きくなると、構造を理解できず、非正規化されたテーブルを維持するためにすべてのロジックを GUI レイヤーに配置する必要がある場合、問題が非常に簡単に発生する可能性があります。パフォーマンスを損なうロックを使用せずに、SQL データベースの GUI で物事をスレッドセーフにするのは難しいことに注意してください。

DBMS は、これらの問題の処理に非常に優れています。データ モデルをクリーンに保ち、インデックス作成を使用して必要な速度を提供できます。あなたの目標は、最初にそれを正しく取得することであり、(パフォーマンスなどのために) 明確な必要性が見られる場合にのみ、テーブルを非正規化する必要があります。

信じられないかもしれませんが、正規化されたデータを使用すると、アプリケーションの作業が難しくなるのではなく、作業が楽になる状況がたくさんあります。たとえば、質問と回答を含む 1 つの大きなテーブルがある場合、それが一意かどうかを確認するコードを作成する必要があります。主キーを持つテーブルがある場合は、単に次のように記述します

insert into table (col1, col2) values (@id, @value) --NOTE: You would probably 
--make the id column an autonumber so you dont have to worry about this

そこに一意でない値がある場合、または質問なしで回答を入力している場合、データベースは挿入を防ぎます。あなたがする必要があるのは、挿入が機能したかどうかを確認することだけです。どれがコードが少ないと思いますか?

于 2009-08-11T23:36:32.710 に答える
1

この状況での1対多の結合テーブルはあまりメリットがないように思われ、@chaosが言うように、実際には多対多のサポートを実装することになることに同意します。しかし、ジョー・セルコは賢い人です。これは本当に彼の正確な答えですか?

1 対多で結合テーブルを実装するもう 1 つの考えられる理由は、ユーザーへの依存から質問/回答を完全に分離することです。

たとえば、Dogsテーブルとテーブルを追加したとしDeitiesます。犬はメールアドレスを持っていないのでユーザーとして登録できず、神はユーザーとして登録できないということは誰もが知っています。犬と神はまだ質問をするかもしれませんが、そのためには、犬の質問テーブルと神々の質問テーブルを実装することをお勧めします。理論的には、これは多対多ですが、実際には、複数の 1 対多を持つことができるようにします。

于 2009-08-11T23:44:23.803 に答える