web-dev-qa-db-ja.com

主キーのSQLテーブルの設計(ベストプラクティス)

次の列で構成されるUserテーブルがあります。

  • ID(自動生成されたGUID)
  • UserName
  • パスワード
  • ファーストネーム
  • 苗字
  • Eメール
  • アドレスID(GUID)

これは、次の列を含むテーブルAddressにリンクされています(1対1の[1-1]関係)。

  • ID(自動生成されたGUID)
  • 通り
  • その他の住所フィールド

それは(私にとって)これを行う論理的な方法のようです。しかし、冗長な列(AddressID)が含まれている可能性があり、Address.IDではなくEntityIDを使用する必要があると誰かが私に言った。

列は1つ少なくなりますが、Addressテーブルには独自のID列があります。

どの方法をお勧めしますか?実行速度が速いものはありますか?親子関係のコンテキストで何が最善ですか?パフォーマンスに影響はありますか?

4
Mathieu

私はMaessに同意します。エンティティが異なる場合、それぞれに独自のID列を設定する必要があります。しかし、SQL Serverのクラスタリングキーに主キー、より具体的にはGUIDを使用することに強い反対があります。

GUIDは主キーの自然な選択のように思えるかもしれませんが、本当に必要な場合は、テーブルの主キーにGUIDを使用するように主張できます。私が強く推奨することしないことは、GUID列をクラスタリングキー、特に指示しない限り、SQL Serverはデフォルトでこれを実行します。

あなたは本当に2つの問題を分けておく必要があります:

1)主キーは論理構造です-テーブルのすべての行を一意かつ確実に識別する候補キーの1つ。これは実際には何でもかまいません-INT、GUID、文字列-シナリオにとって最も意味のあるものを選択してください。

2)クラスタリングキー(テーブルの「クラスタ化インデックス」を定義する1つまたは複数の列)-これはです物理ストレージに関連するもの、そしてここでは、小さくて安定した、増え続けるデータ型が最適な選択です-デフォルトのオプションとしてINTまたはBIGINT。

デフォルトでは、SQL Serverテーブルの主キーはクラスタリングキーとしても使用されますが、そのようにする必要はありません。以前のGUIDベースのプライマリ/クラスター化キーを2つの別々のキーに分割すると、パフォーマンスが大幅に向上します。GUIDのプライマリ(論理)キーと、別のINT IDENTITY(1、 1)カラム。

Kimberly Tripp -インデックス作成の女王-および他の人は何度も述べています-a GUIDクラスター化キーはランダムであるため、最適ではないため、それは大規模なページとインデックスの断片化と一般的に悪いパフォーマンスにつながります。

はい、わかっています-SQL Server 2005以降にはnewsequentialid()がありますが、それでも完全にシーケンシャルではないため、GUID-と同じ問題が発生します-あまり目立たないので。

次に、考慮すべき別の問題があります。テーブルのクラスタリングキーは、テーブルのすべての非クラスタ化インデックスのすべてのエントリに追加されるため、できるだけ小さくする必要があります。通常、20億行のINTは、大多数のテーブルに十分なはずです。GUIDをクラスタリングキーとして使用する場合と比較すると、ディスク上のストレージを数百メガバイト節約できます。サーバーのメモリ内。

クイック計算-INTとGUIDをプライマリおよびクラスタリングキーとして使用:

  • 1'000'000行のベーステーブル(3.8 MB対15.26 MB)
  • 6つの非クラスター化インデックス(22.89 MB対91.55 MB)

合計:25 MB対106 MB-そして、それは単一のテーブルにあります!

思考のためのもう少し食べ物-Kimberly Trippによる優れたもの-読んで、もう一度読んで、消化してください! SQL Serverのインデックス作成の福音です。

6
marc_s

現在、多対1の関係があり、多くのユーザーが1つのアドレスを持つことができます(UserテーブルのAddressIDに制約はありません)。

ユーザーがプリンシパルでアドレスが依存する真の1対1になるためには、ユーザーテーブルのautogenプライマリキーとしてUser.IDを作成し、非auto genプライマリキーのAddress.Idと参照する外部キーを作成する必要があります。 User.Id列。

EFは、これを有効な1対1の関係として認識します。

3
np-hard

テーブルがリレーションではなくエンティティを表す場合、それが独自の主キーを持つことがベストプラクティスです。したがって、UserとAddressの両方に独自のPKがあり、AddressIDはUserテーブルのFKである必要があります。あなたが従っているアプローチは正しいです。

1
Maess