多くのDBMS(例:mysql、postgres、mssql)を見つけることができる限り、fkとpkの組み合わせを使用してデータへの変更を制約するだけですが、結合する列を自動的に選択するためにネイティブで使用されることはほとんどありません(名前による自然結合のように)。何故ですか? pk/fkを使用して2つのテーブル間の関係をすでに定義している場合、データベースがそれらのテーブルを結合する場合、pk/fk列でそれらを結合する必要があるとデータベースが理解できないのはなぜですか?
編集:これを少し明確にするために:
table1とtable2があるとします。 table1には、列aに外部キーがあり、table2の主キーbを参照しています。これらのテーブルを結合する場合は、次のようにする必要があります。
SELECT * FROM table1
JOIN table2 ON table1.a = table2.b
ただし、table1.aがtable2.bを参照するキーを使用してすでに定義しているので、DBMSシステムがtable1.aとtable2.bを結合列として自動的に使用するようにするのは難しいことではないようです。簡単に使用できるように:
SELECT * FROM table1
AUTO JOIN table2
ただし、多くのDBMSはこのようなものを実装していないようです。
多くの場合、2つのテーブルを結合する方法は複数あります。多くの例については、他の回答を参照してください。もちろん、そのような場合に「自動結合」を使用するとエラーになると言えます。それから、それが使用できるほんの一握りの単純なケースだけが残されるでしょう。
ただし、重大な欠点があります。今日正しいクエリは、同じテーブルに2番目のFKを追加するだけで、明日エラーになる可能性があります。
もう一度言いますが、列を追加すると、それらの列を使用しないクエリが「正しい」から「エラー」になる可能性があります。
それはメンテナンスの悪夢であり、正気なスタイルガイドはこの機能の使用を禁止します。ほとんどの場合、すでに禁止されていますselect *
同じ理由で!
パフォーマンスが向上する場合、これはすべて許容されます。しかし、そうではありません。
要約すると、この機能は、限られた一連の単純なケースでのみ使用でき、パフォーマンスを向上させません。ほとんどのスタイルガイドでは、とにかくその使用を禁止します。
そのため、ほとんどのデータベースベンダーがより重要なことに時間を費やすことを選択するのは当然のことです。
外部キーはconstrainデータを意味します。つまり、参照整合性を適用します。それでおしまい。他には何もありません。
同じテーブルに複数の外部キーを持つことができます。出荷に開始点と終了点がある場合、次のことを考慮してください。
table: USA_States
StateID
StateName
table: Shipment
ShipmentID
PickupStateID Foreign key
DeliveryStateID Foreign key
ピックアップの状態に基づいて参加することができます。配送状態で参加したいかもしれません。両方で2つの結合を実行したい場合があります。 SQLエンジンには、必要なものを知る方法がありません。
多くの場合、結合スカラー値を交差させます。通常、スカラーは中間計算の結果ですが、場合によっては、正確に1つのレコードを持つ特別な目的のテーブルが存在することがあります。エンジンが結合の外部キーを検出しようとした場合...クロス結合は列と一致しないため、意味がありません。
特別な場合には、どちらも一意でない列を結合します。したがって、これらの列にPK/FKが存在することは不可能です。
上記のポイント2と3は関係がないと考えるかもしれません。質問はいつ[〜#〜] is [〜#〜]テーブル間の単一のPK/FK関係があるかということです。ただし、テーブル間に単一のPK/FKが存在しても、PK/FKに加えて他のフィールドを結合できないことを意味するわけではありません。 SQLエンジンは、結合するフィールドを認識しません。
「USA_States」というテーブルと、州へのFKを持つ5つの他のテーブルがあるとします。 「5」テーブルには、互いにいくつかの外部キーもあります。 SQLエンジンは、「USA_States」を使用して「5」テーブルを自動的に結合する必要がありますか?それとも、「5」を互いに結合する必要がありますか?どちらも? SQLエンジンがものを結合しようとする無限ループに入るように関係を設定できます。この状況では、SQLエンジンが必要なものを推測することは不可能です。
要約: PK/FKはテーブル結合とは関係ありません。それらは別個の無関係なものです。 PK/FK列で頻繁に参加するのは、単なる偶然です。
それが完全、左、右、または内部結合であるかどうかをSQLエンジンに推測させますか?私はそうは思いません。それは間違いなく、結合する列を推測するよりも罪が少ないでしょう。
「結合性」の概念。リレーション_
r1
_と_r2
_は、同じ名前の属性が同じタイプである場合にのみ結合可能です...この概念は、結合自体だけでなく、他のさまざまな演算[ユニオンなど]にも適用されます同様に。
SQLとリレーショナル理論:Cによる正確なSQLコードの書き方J.日付
標準SQLには、_NATURAL JOIN
_と呼ばれるそのような機能がすでにあり、mySQLに実装されています。
あなたの提案はそれほど価値がありませんが、それは合理的なもののようです。 SQL Serverでは( _NATURAL JOIN
_ のサポートが不足しています)、Management StudioでSQLプロンプトを使用します:_INNER JOIN
_を書き込むときInteliSenseは、共通の属性名と外部キーの両方に基づいてON
句を提案します。これは非常に便利です。ただし、このための新しい(標準の)SQL結合タイプを見たいとは思いません。
SQLが最初に来ました!
外部キーと外部キーの制約は後で登場し、本質的には「トランザクション」スタイルのアプリケーションの最適化です。
リレーショナルデータベースはもともと、リレーショナル代数を使用して数学的に証明可能の方法でデータのセットに複雑なクエリを適用する方法として考えられていました。 I.E.特定のデータセットと特定のクエリに対して、常に1つの正解があります。
それ以来、リレーショナルデータベースは長い道のりを歩んできました。トランザクションシステムの永続化レイヤーとしての主な用途はCODDらではありませんでした。すべてが想定されています。
ただし、ANSI標準化団体は、そのすべての相反する目標とベンダーの方針のために、常にSQLの「数学的に証明可能な」プロパティを維持するよう努めてきました。
データベースが「隠された」外部キーデータから結合プロパティを推測できるようにした場合、このプロパティは失われます(複数の外部キーセットが定義されている場合のあいまいさを考慮してください)。
また、SQLを読んでいるプログラマは、2つのテーブルに現在定義されている外部キーを必ずしも知っているとは限らず、クエリが何をしているかを理解するためにデータベーススキーマを調べる必要があります。
あなたは誤った仮定で操作しているかもしれません。「見つけることができる限り」と言いますが、実証的または証拠的な証拠は与えません。 pkまたはfkがクエリに最適なインデックスである場合は、それが使用されます。なぜこれが表示されているのかはわかりませんが、私のクエリは整形式ではないようです。
質問が完全に書き直されたので編集します:あなたが説明しているケースは、非常に小さなクエリのセットにのみ当てはまります。 12個のテーブルが結合されている場合はどうなりますか? FKがない場合はどうなりますか。デフォルトの結合があったとしても、読みやすさのために常に結合を指定します。 (私はデータを見て、それから何が結合されているのかを理解しようとする必要はありません)
一部のクエリツールでは、実際に自動結合が行われるため、結合を削除または編集できます。 MS AccessのQuery Builderがこれを行うと思います。
最後に、ANSII標準では、結合を指定する必要があると規定されています。それはそれを許さない十分な理由です。
外部キー関係を定義しましたが、それがすべてのクエリでテーブルを結合する方法であるとは限りません。テーブルを結合する最も可能性の高い方法ですが、正しくない場合があります。
データベースが安全にこれを行えない理由はたくさんあります。たとえば、外部キーを追加/削除すると、アプリケーションのソースコード内のクエリを含む、事前に作成されたクエリの意味が変わるという事実があります。また、ほとんどのデータベースには、実行する可能性が高いすべての結合をカバーする適切な外部キーセットがありません。また、より良いまたは価値があるために、外部キーはシステムを高速化するために削除されることが多く、ファイルから「間違った」順序でロードされたテーブルでは使用できません。
ただし、クエリの設計toolまたはテキストエディターが外部キーを使用して自動で結合を完了できない理由はありませんintellisense列名に。ツールで問題が発生した場合はクエリを編集して、完全に定義されたクエリを保存できます。このようなツールは、「親」テーブル名と親/子テーブルの両方で同じ名前の列などによって外部キー列に名前を付けるという慣例を有効に活用することもできます。
(妻はまだManagement StudioとSQL Serverの違いを理解できず、Management Studioの起動時にSQLサーバーを起動することについて話します!)
自然結合は「自動的に」一般的な列の等値で結合しますが、テーブルの意味と必要な結果に基づいてwantである場合にのみ、それを記述する必要があります。 2つのテーブルがどのように結合されるべきか、または他の方法でどのテーブルがクエリに「あるべきか」を「自動的に」知っていることはありません。問い合わせる制約を知る必要はありません。それらの存在は、入力が制限される可能性があることを意味し、その結果、出力も制限される可能性があります。宣言された制約ごとに「自動的に」結合する、ある種のjoin_on_fk_to_pk演算子を定義できます。ただし、制約のみが変更され、テーブルの意味は変更されない場合にクエリの意味を同じにしたい場合は、そのクエリをnotに変更する必要があります。新しく宣言された制約を使用します。結合と条件を使用して必要なクエリを指定するだけで、制約の変更があっても、意味は同じままです。
保持される制約(PK、FK、UNIQUE&CHECKを含む)は、テーブルの意味には影響しません。もちろん、表の意味が変わると、制約が変わる可能性があります。ただし、制約が変更されても、クエリを変更する必要があるとは限りません。
クエリするための制約を知る必要はありません。制約について知ることは、制約を保持しないと同じ答えを返さないという式をさらに使用できることを意味します。たとえば、UNIQUEを介してテーブルに行が1つあることを期待しているので、それをスカラーとして使用できます。制約が想定されているが宣言されていない場合、これらのクエリは壊れる可能性があります。しかし、クエリが想定していない制約を宣言しても、それを壊すことはできません。
その理由は、言語があり、その下にあるプリンシパルがあるからです。言語はまばらで、汎用言語で見られると予想される多くの機能が不足しています。これは単に、言語に追加されていない、おそらく追加されない素敵な機能です。それは死んだ言語ではないので、いくつかの希望がありますが、私は楽観的ではありません。
他の人が指摘したように、一部の実装では、結合(列)が共通の列名に基づいて2つのテーブルを結合する拡張機能を使用しています。しかし、それは広く普及していません。この拡張は、使用する列を指定する方法を含まないSELECT * FROM employee NATURAL JOIN department;
構文とは異なることに注意してください。どちらもテーブル間の関係に依存しないため、テーブルの信頼性は低くなります(拡張よりも自然な結合構文)。
PKFKが「2つのテーブル間で定義された外部キー関係」を意味するキーワードである「PKFKの内部結合テーブル」に基本的な障害はありません。同じテーブルへの複数のfkで問題が発生する可能性がありますが、単にエラーが発生する可能性があります。問題は、言語を設計している人々が、a)良いアイデアであり、b)他の言語の変更よりも取り組む方が良いと考えているかどうかです...
ON句の省略が参照整合性に基づいてフィールドに従うと想定される場合、デカルト積をどのように実行しますか?
編集:AUTOを使用これの利点は、タイピングが少し少なくなり、それらがどのように結合されるかを知ったり、複雑な結合を覚えたりする必要がないことです。リレーションシップが変更された場合、それは自動的に処理されますが、開発の初期を除いてほとんど発生しません。
ここで行う必要があるのは、relationahipの変更中にすべてのAUTO結合が保持され、selectステートメントの意図と一致するかどうかを判断することです。