2016-11-30 3 views
0

これは愚かな質問かもしれません。SQL Serverテーブル設計のアドバイス

これらのサーバーは今後数カ月間で2014年にアップグレードされますが、SQL Server 2008 R2の効率に関するアドバイスもあります。私は3つのテーブルを作成しています。

  • t1は、様々なタイプの多くの列と主キーであるアイデンティティの数値IDを持っています。私はこのテーブルが1000の低い行に入ることを期待しています。

  • t2は、t1と1対多の関係にあります。主キーはt2 IDとt1 IDの複合です。 t2数値IDはフロントエンドアプリケーションによって送信され、t1 IDごとに一意になります。私はこのテーブルが50000+の行に到達することを期待しています。これらの2つのIDの他に、さまざまな長さのvarcharカラムがいくつか含まれています。

  • t3は、t2と1対多の関係にあります。プライマリキーは、t3 ID、t1 ID、およびt2 IDのコンポジットです。再び、t3数値IDはフロントエンドアプリケーションによって送信され、t2 IDごとに一意になります。私はこのテーブルが数百万行に達することを期待しています。これらの3つのID以外に、少数の日付または数値列が含まれます。私はt3は、本質的にT3の主キーは、T3のIDとt2からのID列、つまり、2列の代わりに、3になることを意味するために参照するID列を設定する必要があります私の質問をt2内にある

。これはより効率的でしょうか? t2内のこのID列にインデックスを付ける必要がありますか?ジョインを助ける?

私は何か他のことをしていますか?

+0

どのような検索が最も頻繁に実行されますか?あなたは 't1'または' t2'キーを使って 't3'を探しますか、他のフィールドのデータを使うのですか?あなたの答えは、サロゲートキーまたはナチュラルキーをより良い選択にするかもしれません。 – Tony

+0

** ** t2 **と** t3 **の両方で、検索は個別に実行されることはありませんが、これは疑いがありますが、今後これが発生する可能性があります。これらのテーブルに対するクエリは、** t1 **への結合によって駆動されます。大部分の日中の検索は、1 t1レコードとそのt1 IDのt2にあるものとt1 | t2 IDのt3にあるものの大部分になります。 – Darybrain

答えて

0

私が最初に考えたの懸念声明

... [T2 | T3]の数値IDは、フロントエンドアプリケーション によって送信されます...

あなたはユニークな識別子を生成している場合データベースで使用するには、データベースに数値を生成させることをお勧めします。 になることができない限り、は重複IDを生成しません。

 
    +----+ +----+ +----+ 
    | | | | | | 
    | t1 +---+ t2 +---+ t3 | 
    | | | | | | 
    +----+ +----+ +----+ 

keys: t1.id t1.id t1.id 
       t2.id t2.id 
         t3.id 

代理キーへの変更は、それがt1(不要)を変更しません(私が正しくあなたのテーブル構造を理解している場合)サロゲートキーを使用しているときあなたのコメントに応えて

は、ここでの違いをです。 t2も同じままですが、t2.idを行番号から一意のプライマリキー[pk]に変更する必要があります。問題は、テーブルの別のフィールドとして '行番号'を保存する必要があることです。

主な違いは​​で、3つのテーブル識別子すべてではなく、t2.pkとそれ自身の行識別子のみが必要です。

 
     +----+ +----+ +----+ 
     | | | | | | 
     | t1 +---+ t2 +---+ t3 | 
     | | | | | | 
     +----+ +----+ +----+ 

keys: t1.id  t2.pk t2.pk 
       t1.id t3.pk 

この方が良いでしょうか?よく分かりません。また、テーブルに対して実行しているクエリのタイプと頻度にも依存します(ご質問のコメントを参照)。t2またはt1に参加しなくても、t3内の行を検索 -

idによってあなたは主に、クエリの場合、最初のレイアウトが最高になります。しかし、検索を行うために他のテーブルからの情報が必要な場合は、代理キー構造によって結合があまり冗長になることがあります。

最終的には、実装するまでは何が最良かを知ることができないため、これは最終的に(クエリのパフォーマンスに関して)時期尚早な最適化です。

+0

これらは常に一意である必要があります。フロントエンドでは、t2 IDは本質的に各t1レコード内の画面上の行番号です。フロントエンド内でデータが変更されたら、レコードが存在するかどうかをチェックして、動的更新または挿入SQL文を生成する必要があるかどうかを確認する必要があります。どのような構造をお勧めしますか?一列のアイデンティティーを主キーとして使用する場合でも、テーブルに応じて[t1 | t2]または[t1 | t2 | t3]の組み合わせを保存する必要があります。これらが重複していないことを確認するには、データベース内で何がベストですか? – Darybrain

+0

@Darybrain - 私はあなたのコメントに応じて私の答えを更新しました。 – Tony

0

私は通常、このためにID intプライマリキーを作成し、これをクラスタ化インデックスにします。

私は、t2またはt3に複合IDではなく、別のフィールドを持ち、外部キー制約を設定することはありません。

クラスタ化インデックスと外部キーは、必要なすべてのインデックス作成(結合用)になります。クエリに基づいて追加のインデックスが必要な場合があります。

私はこれを1億の行数のテーブルに設定し、1秒未満でクエリ結果を取得しました。

+0

t2を例にとると、クラスタ化されたプライマリとしてID列を作成した場合でも、t1 IDとt2 ID(基本的に各t1レコードの行番号)が必要です。両者の組み合わせが重複しないようにするにはどうすればよいでしょうか?これらの2つのフィールドはあなたが言及した制約に含まれますか? – Darybrain

+0

@Darybrain - キーフィールドに「UNIQUE」インデックスを使用すると、1つの数値キーフィールドを持つときに重複を防ぐことができます。 – Tony

+0

フロントエンドがキーを生成するのはなぜですか?アプリケーションが複数のデータストアを制御していない限り、私はその必要性を理解していません。 @Darybrainも同様ですが、重複を防ぐためにユニークな制約を追加できますが、トラップして処理する必要があるエラーが発生します。重要な問題は、フロントエンドがRDBMSを制御する理由です。 –

関連する問題