1対1の関係は正規化されていますか?


12

レコードの統計データの大規模なセットがあると考えてください。例:20〜30 INTカラム。セット全体が1つのレコードに属しているため、セット全体を1つのテーブルに保持するか、1対1の関係で接続された別のテーブルを作成する方が良いでしょうか。

前者の利点はJOIN、対応するレコードのすべての統計データを回避して迅速にアクセスできることです。

後者の利点は、カラムを整頓することです。最初の列は読み取り中心で、2番目の列は書き込み中心です。もちろん、行レベルのブロッキングでInnoDBを使用しているので、パフォーマンスに大きな影響はないと思います。

一般に、1つのレコードに対して異なるデータセットを分離することが実用的かどうか知りたいですか?


2
「正規化」とは、第1正規形(1NF)を意味し、リレーショナルモデルの基本的な要件です。「完全に正規化」とは、5NF以上を意味します。提案された「1対1の関係」テーブルは、分解されているため、現在のものよりも(おそらく6NFでも)より高い正規形になる可能性が高くなります。既存のテーブルはどのような通常の形式を満たしていますか?
onedaywhen

@onedaywhen他の多くの人と同様に、正規化を順を追って説明しません。非正規化も役立つ場合があるためです。一般的に、データベース全体の正規化レベルは3NFから5NFの間でなければなりません(私は常に4NFで問題があります!)
Googlebot

回答:


19

正規化のルールに当てはまる場合、1:1の関係は正規化できます(定義により!)-つまり、1:1の関係については、正規の形式に従うことが不可能になるものはありません。

1対1の関係の実用性についての質問に答えるために、これは、述語(列)が異なるサブタイプがある場合など、完全に便利な構成である場合があります。

1対1の関係を使用する理由は、視点によって異なります。DBAはすべてをパフォーマンスの決定であると考える傾向があります。データモデラーとプログラマーは、これらの決定をデザインまたはモデル指向であると考える傾向があります。実際、これらの視点の間には多くの重複があります。それはあなたの視点と優先順位が何であるかに依存します。以下は、1対1の関係の動機の例です。

  • 非常に幅の広い列のサブセットがあり、パフォーマンス上の理由から、それらをストレージ内で物理的に分離したい場合。

  • 頻繁に読み取られたり更新されたりしない列のサブセットがあり、パフォーマンス上の理由から、それらを頻繁に使用される列から離しておく必要があります。

  • 一般にオプションの列がいくつかありますが、レコードが特定のタイプであることがわかっている場合は必須です。

  • サブタイプに論理的に属している列がいくつかあり、それらをモデル化して、コードのオブジェクトモデルにうまく適合させたいとします。

  • エンティティのスーパータイプの一部のサブタイプにのみ適用できる列がいくつかあり、スキーマで他のサブタイプにこのデータが存在しないようにする必要があります。

  • エンティティに属するいくつかの列がありますが、より制限されたアクセスルール(従業員テーブルの給与など)を使用してこれらの特定の列を保護する必要があります。

ご覧のとおり、ドライバーはパフォーマンスである場合もあれば、モデルの純粋さである場合もありますが、宣言型スキーマルールを最大限に活用したいという欲求もあります。


You have some subset of columns that are very wide and you want to segregate them physically in your storage for performance reasons.それらを分離することでパフォーマンスがどのように向上しますか(メインテーブルがアクセスされるたびに常に列にアクセスすると想定)。
ギリ2014

@ギリ-あなたの仮定が真実なら、このケースは当てはまりません。大きくてめったに必要とされない列を分離すると、ページにより多くの行を収めることができるため、一般的に使用される列をより速く取得できます。結合が必要なため、分離された列と一般的に使用される列の読み取りは明らかに遅くなります。
ジョエルブラウン

設計上の理由(懸念の分離、コードの再利用の増加)のために、一般的に使用される列に沿って分離したいと思います。そのような参加のコストの見積もりを誰かが投稿しましたか?彼らは無視できるか、私が長期的に心配すべき何かですか?
ギリ

@Gili-re:結合のコスト:「依存する」以外にその質問に対する正しい答えはありません。参加コストは多くの要因の影響を受けます。それらが無視できるかどうかは、最終的に主観的であるため、答えるのがさらに困難です。質問に答える最良の方法は、いくつかのテストデータをモックアップしてボリュームテストを行うことです。両方の方法を試して、実際のデータボリューム(アプリケーションに意味するものは何でも)を使用して違いを確認できるかどうか確認してください。
ジョエルブラウン

私はそうし、驚くべき結果を得ました:dba.stackexchange.com/q/74693/4719 これは正規化の典型的な例ではないことを認めますが、JOINが(まだ)非常に高価であることを強調していません。
ギリ2014

4

1対1のマッピングを使用して大きなテーブルを2つに分割する主な理由は、次のようなパフォーマンス上の理由です。

a)テーブルには、頻繁にアクセスされるテーブルにバイナリ/クローブ/ブロブデータがあり、大きな列は異なる方法で処理されるため、パフォーマンスが低下します。

b)テーブルにはさまざまなクエリによってアクセスされる多くの列があるため、パフォーマンスが低下するため、関連する列を別のテーブルに移動して、アクセスのパフォーマンスを向上させます。

ただし、多くの整数列があるからといって、テーブルを別々のテーブルに分割してクエリする必要があるという追加の努力が正当化されません。


問題を明確にするための非常に良い点!
Googlebot
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.