2012-03-03 48 views
0

SQL Server 2008 R2で、ユーザーが独自のサブタイプをカテゴリに配置できるデータベースを構築しようとしています。私は、(私によって定義された)プリセットカテゴリ名を保持する親テーブルを持っています。複合キーが存在するときに一意のIDフィールドが主キーに含まれない

私が直面している問題は、PRIMARY KEYUNIQUEの制約と外部キーに関する問題を扱う最良の方法です。サブテーブル(私たちはCategoryTypesと呼ぶ)が時間とともにかなり大きくなり、親テーブル(Categories)に基づいてデータから効率的に読み込みを可能にする必要があると予想しているので、インデックス作成が中心です。テーブルが次のように配置されている場合、私は予想する必要がある問題はありますか?

私の懸念は、CategoryTypesテーブルのIDENTITY列が一意のカウントを維持する必要があることです。私がこのフィールドを含む理由は、アプリケーション内の層の間でデータを渡すときに、より簡単な参照を許可するためです。 Integer対Integer/Stringの組を渡すことによって。これらのテーブルのデータは、帯域幅を節約するためにデータベースの各レイヤーで保持されます。データベースの観点からは、一度配置すると、以下のレイアウトに大きな問題が生じますか?

簡略化するために、コンポジットキーが存在するときにプライマリキーに含まれない一意のIDフィールド(IDENTITY)を使用する際に問題がありますか?

親表:

CREATE TABLE schema.Categories 
(
    Id TINYINT PRIMARY KEY NOT NULL, 
    Name VARCHAR(100) NOT NULL, 
) 

サブテーブル(ユーザ時間をかけてデータを挿入する):

CREATE TABLE schema.CategoryTypes 
(
    Id INT IDENTITY(1,1) NOT NULL, 
    CategoryId TINYINT REFERENCES schema.Categories(Id) NOT NULL, 
    Name VARCHAR(100) NOT NULL, 
    CONSTRAINT PRIMARY KEY CLUSTERED(CategoryId, Name) 
    CONSTRAINT UC_CategoryTypesId UNIQUE NONCLUSTERED(Id) 
) 
+0

PSを - 私もそれが必要であるので、サブテーブル「CategoryTypes」でIdが...外部キーの関係などを介して他のテーブルによって参照されることを追加します。テーブルデザインでこのような複雑さに対処するベストプラクティスを公開しています。 –

+1

セカンダリインデックスはクラスタ化されたテーブルでは高価です。あなたが代理キー '{Id}'を本当に必要としないなら、それをまったく使用せず、自然キー '{CategoryId、Name}'だけを使用してください。両方のキーが必要な場合は、ヒープベースのテーブル(つまり、「PRIMARY KEY NONCLUSTERED」)を使用します。 –

+0

Branko、私は余分なオーバーヘッドを認識していますが、この文脈でこれを繰り返していただきありがとうございます。私が直面している課題は、代理ID(外部キー)を参照する必要があることです。私は、あなたが複合的な外部キーを行うことができると思います...しかし、私はこれに慣れていません。代理人は物事をもっと楽にするようです。つまり、あなたとジャスティンの両方が推奨しているように、「CLUSTERD」索引付けを「NONCLUSTERED」にすることから始めることができます。パフォーマンスが必要な場合は、後で私はいくつかの生産データを持っています。 CRUDでは - クラスタ化インデックスは「読み込み」を助けますが、オーバーヘッドをかけることがあります。 –

答えて

0

あなたは一種の継承構造のような音を記述している何を、以下の表のレイアウトを参照してください。私が理解する限り、サンプルデータセットを作成しました。これがあなたの意図であることを確認できますか?

これが正常に動作するはずです。なぜ、CategoryType.Idをプライマリキーとして設定していないのかわかりません。それがあなたのPKではなく、他の場所でFKとして参照されていないなら、私はそれを指摘しません。私は個人的には帯域幅の節約に十分になるとは思っていません。おそらくCategoryIdとNameでデータを要求してください。実際、継承構造がどのように表現されるかは、PKがしばしばありません(How can you represent inheritance in a database?)。

あなたがそれを設定したままにしなければならない場合は、私は個人的にIDをPKとして設定し、CategoryId/Nameに一意の制約を設定することをおすすめします。

それはちょうど私の2セントです。

Category 
---- 
Id|Name 
1 |Food 
2 |Drink 

CategoryType 
---- 
Id|CategoryId|Name 
1 |2   |Water 
2 |2   |Orange Juice 

UPDATED ANSWER(直接パフォーマンスの問題に対処するため)

まず、それは問題ではない場合、私はあまりそれについて全く心配ありませんお勧めします。それは、私たちの多くが行う共通の問題であり、必要のないものを過度に複雑にしています。それは私の本

KISS principleに該当しますが、ここで、その後、事前にあなたが説明した方法をこれを理解しようとしているのdeadsetしている場合しかし、私の追加の考えている:

  • がIDとしてPKを作成します。ただし、これをノンブロッキングにしてください
  • クラスターインデックスをCategoryIdに作成し、上記のノンクラスタードインデックスでINCLUDE keywordを使用することを検討してください。
  • のみ、あなたがより頻繁に照会するための区分を使用しようとしている場合は、上記の操作を行いCategoryType.Idより
  • 検討(でもINCLUDE記事から取った)にもかかわらず、あなたのキーを作成するとき
Index maintenance may increase the time that it takes to perform modifications 
, inserts, updates, or deletes, to the underlying table or indexed view. 

は最終的に、私はあなたは大丈夫だろうやっていると思います、しかし、PKをクラスタ化する必要はありませんので、私は間違いなくIdフィールドにPKを移動します。 CategoryIdまたはCategoryId/Nameでクラスタを作成する場合、または私が提案したようにINCLUDEを使用したい場合は、選択してください。これは実際にどのようにテーブルが使用されているかによって異なりますので、実行計画を比較すると役立ちます。

うまくいけば、これは役立ちます:)

+0

ジャスティン、あなたの質問に答えてください "これは継承構造ですか?"レイアウトした例は、私がしようとしていることと完全に平行しています。あなたはIDを作ることについてコメントします.PKは私の現在のSQLの構造が実装したものです。私がこれを逆に投稿したのは、インデックス(例えば、100万のCategoryTypesがある場合、複合リレーションシップに基づいてクラスタードインデックスを持つことは効果がないでしょうか?私は同意します.PKは最も論理的な意味を持つようですここでIDとして...しかし、PKが一意のClusteredキーとほとんど同じであることを考えると、どちらの方法がperfに最適か疑問に思う。 –

+0

あなたのより具体的な質問に少し集中して回答を編集した。 –

関連する問題