2

この質問は、CJ Date のSQL and Relational Theory: How to Write Accurate SQL Code を読み、インターネットで結合について調べることから来ています (これには、ここ NATURAL JOIN に関する複数の投稿に出くわすことも含まれます (また、SQL Server のサポートの欠如についても含まれます)。 )

ここに私の問題があります...

一方では、リレーショナル理論では、自然結合のみが発生する必要があります (または、少なくとも非常に好まれます)。

一方、SQL では NATURAL JOIN を使用せず、代わりに別の手段 (制限付きの内部結合など) を使用することをお勧めします。

これらの調整は次のとおりです。

  • 自然結合は真の RDBMS で機能します。ただし、SQL はリレーショナル モデルを完全に再現することに失敗しており、一般的な SQL DBMS のどれも真の RDBMS ではありません。

および/または

  • 優れた/優れたテーブル設計は、自然結合によって生じる問題を排除/最小化する必要があります。

?

4

4 に答える 4

6

まず、理論と実践のどちらを選ぶかは誤りです。Chris Date の言葉を引用すると、「真実はその理論、少なくとも私がここで話しているリレーショナル理論は、非常に実用的であるということです」.

次に、自然結合は属性の命名に依存していることを考慮してください。Accurate SQL Codeブックの次のセクションを (再) 読んでください。

6.12. 属性名への依存。顕著な引用:

関係代数の演算子はすべて、属性の命名に大きく依存しています。

3.9。SQL での列の命名。顕著な引用:

強くお勧めします: …SQL の 2 つの列が「同じ種類の情報」を表している場合は、可能な限り同じ名前を付けてください。(そのため、たとえば、サプライヤーと部品のデータベースにある 2 つのサプライヤー番号の列は両方とも SNO と呼ばれ、一方のテーブルでは SNO で、もう一方のテーブルでは SNUM ではありません。) 逆に、2 つの列が異なる種類の情報を表す場合、 、通常は別の名前を付けることをお勧めします。

「消費しているWebサービス」など、制御できないテーブルに列が追加されるという@kuru kuru paのポイント(これも良いものです)に対処したいと思います。この問題は、セクション 3.9 (上記参照) で Date によって提案された戦略を使用して効果的に軽減されるように思われます。

  • すべてのベース テーブルに対して、一部の列の名前変更を除いて、そのベース テーブルと同一のビューを定義します。
  • そのように定義された一連のビューが、上記の列の命名規則に従っていることを確認してください。
  • 基になるベース テーブルではなく、これらのビューに関して操作します。

個人的には、「自然な結合は危険と見なされます」という態度がもどかしいと思います。独善的に聞こえることを望んでいませんが、ISO 11179-5 命名および識別の原則のガイダンスに従う私自身の命名規則により、自然結合に非常に適したスキーマが得られます。

悲しいことに、自然結合は、私が専門的に使用している DBMS 製品 (SQL Server) ですぐにサポートされなくなる可能性があります。Microsoft Connect での関連する機能要求 は、現在のところ +38 / - 2 スコア が再開され、立派な 46 / -2 スコアを獲得しました (今すぐ投票してください :)

于 2011-09-14T08:12:53.763 に答える
6

あなたの質問に関するいくつかのポイント(あなたが尋ねたことに本当に答えていないのではないかと恐れていますが)、

「一方で、リレーショナル理論では、自然な結合が発生する唯一の結合です (または、少なくとも非常に好まれます)。」

これは、「他の種類の」結合を禁止しているかのように理論​​を解釈していることを示唆しているようです...それは実際には真実ではありません。リレーショナル理論は、「アンチジョインを使用できない」、「アンチジョインを使用してはならない」などとは言っていません。それが言うことは、リレーショナル代数では、自然な結合が唯一の「結合のような」演算子である原始演算子のセットを識別することができるということです。他のすべての「結合に似た」演算子は、定義されたプリミティブ演算子に関して常に同等に表現できます。たとえば、デカルト積は、自然結合の特殊なケース (共通属性のセットが空である場合) であり、2 つのテーブルのデカルト積が必要な場合共通の属性名を持っている場合、RENAME を使用してこれに対処できます。たとえば、セミジョインは、最初のテーブルの自然な結合であり、2 番目のテーブルにプロジェクションがあります。たとえば、アンチ結合 (Date の本では SEMIMINUS または NOT MATCHING) は、最初のテーブルと 2 つのテーブルの SEMIJOIN の間の関係の違いです。などなど

「一方、SQL では NATURAL JOIN を使用せず、代わりに別の手段 (例: 制限付きの内部結合) を使用することをお勧めします。」

そのようなことはどこでアドバイスされていますか?SQL標準では?そうは思いません。ISO 標準で定義されている SQL 言語自体と、特定のベンダーによって構築されたその言語の特定の実装(/任意の) を区別することが重要です。Microsoft が SQL Server 200x で NJ を使用しないように顧客にアドバイスする場合、そのアドバイスは、SQL で NJ をまったく使用しないようにという誰かのアドバイスとはまったく異なる意味を持ちます。

「自然結合は真の RDBMS で機能します。しかし、SQL はリレーショナル モデルを完全に再現することに失敗し、一般的な SQL DBMS のどれも真の RDBMS ではありません。」

SQL 自体がリレーショナル理論に忠実に準拠していないことは事実ですが、それは実際には NJ の問題とはほとんど関係がありません。

ある実装が NJ の呼び出しに対して優れたパフォーマンスを発揮するかどうかは、その実装の特性であり、言語の特性ではなく、「RDBMS」の「R」の「真度」の特性でもあります。SQL を使用しない TRDBMS を構築するのは非常に簡単で、NJ の実行時間が非常に長くなります。SQL 言語自体には、NJ をサポートするために必要なすべてが含まれています。実装が NJ をサポートしている場合、NJその実装でも機能します。優れたパフォーマンスが得られるかどうかは、その実装の特徴であり、特定の実装のパフォーマンスの低さを他の実装に「外挿」したり、SQL 言語自体の特徴と見なしたりしないでください。

「優れた/優れたテーブル設計は、自然結合が引き起こす問題を取り除き/最小限に抑える必要があります.」

自然な結合が引き起こす問題? 結合の引数に表示される列の制御は、必要な列に明示的なプロジェクションを追加する (必要に応じて名前を変更する) ことで簡単に実行できます。基本的に同じ理由で、 SELECT * をできるだけ避けたいのと同じように...

于 2011-09-14T22:46:04.533 に答える
2

SQL の NATURAL JOIN 構文の主な問題は、通常、冗長すぎることです。

チュートリアル D の構文では、自然な結合を次のように非常に簡単に記述できます。

R{a,b,c} JOIN S{a,c,d};

ただし、SQL では、同じことを行うために SELECT ステートメントに派生テーブル サブクエリまたは WHERE 句とエイリアスが必要です。これは、単一の「SELECT ステートメント」が実際には非関係の複合演算子であり、コンポーネントの操作が常に事前に決められた順序で行われるためです。プロジェクションは結合のに行われ、結合の結果の列は必ずしも一意の名前を持つとは限りません。

たとえば、上記のクエリは SQL で次のように記述できます。

SELECT DISTINCT a, b, c, d
FROM
(SELECT a,b,c FROM R) R
NATURAL JOIN
(SELECT a,c,d FROM S) S;

また:

SELECT DISTINCT R.a, R.b, R.c, S.d
FROM R,S
WHERE R.a = S.a AND R.c = S.c;

後者の方が短くて「簡単」なので、人々はおそらく後者のバージョンを好むでしょう。

于 2011-09-14T15:58:15.583 に答える
-2

理論対現実…

自然結合は実用的ではありません。
私の知る限り、純粋な (つまり、実践は理論に理想的である) RDBMS などというものはありません。

オラクルと他のいくつかは実際に自然結合のサポートをサポートしていると思いますが、TSQL はサポートしていません。

私たちが住んでいる世界を考えてみてください。2 つのテーブルがそれぞれ同じ名前の列を持つ可能性はかなり高いです (おそらく [name]、[id]、[date] など)。実際に参加する可能性のあるテーブルのみをグループ化することで、これらの可能性を少し絞り込むことができます。ただし、テーブル構造を注意深く調べないと、「自然結合」が適切かどうかはわかりません。たとえそうであったとしても、アプリケーションがアップグレードされて特定のテーブルなどに列が追加されたり、使用している Web サービスがあなたが知らなかったフィールドを追加したりするのは、その瞬間ではないかもしれません。等

「純粋な」システムとは、少なくとも 100% 制御できるシステムである必要があると思います。また、テーブルの変更/テーブルの作成プロセスで適切な検証が行われ、テーブルの作成を警告/防止するシステムである必要があります。結合可能にするつもりのない他のテーブルに「自然に」結合できるテーブルの新しい列。

私にとっての結論は、自分の健全性を評価すること、アプリケーションのアップタイムを最大化すること、迅速でクリーンなメンテナンスとアップグレードを評価することなどだと思います。このコンテキストでの優れたテーブル設計とは、自然結合を使用しないことを意味します (これまで) .

于 2011-09-13T23:20:02.733 に答える