12

追加のデータをデータベースに収める必要があり、既存のテーブル (table_existing) を変更するか、新しいテーブルを作成するかを選択できます。

現在の table_existing は次のようになります。

table_existing
-------------------------
| ID | SP | SV | Field1 |
| .. | WW |  1 | ...... |
| .. | WW |  1 | ...... |
-------------------------

オプション (A)

table_existing
----------------------------------------------------------------------
| ID | SP | SV | Field1 | Field2 | Field3 | Field4 | Field5 | Field6 |
| .. | XX |  1 | ...... | ...... | ...... | ...... | ...... | ...... |
| .. | YY |  2 | ...... | ...... | ...... | ...... | ...... | ...... |
----------------------------------------------------------------------

オプション (B)

table_existing would be converted into table_WW_1_data
---------------
| ID | Field1 |
| .. | ...... |
| .. | ...... |
---------------

table_XX_1_data
------------------------
| ID | Field1 | Field2 |
| .. | ...... | ...... |
| .. | ...... | ...... |
------------------------

table_YY_2_data
---------------------------------
| ID | Field1 | Field2 | Field3 |
| .. | ...... | ...... | ...... |
| .. | ...... | ...... | ...... |
---------------------------------

コンテキスト: SP と SV の組み合わせによって、入力されるフィールドの「数」が決まります。たとえば、(XX, 1) には 2 つのフィールドがあります。(YY, 2) には 3 つのフィールドがあります。

オプション (A) を使用すると、「より広い」テーブルに多くの空/NULL 値が含まれることになります。

オプション (B) を使用する場合、基本的にはより多くのテーブルを作成します... SP、SV の「各」組み合わせに対して 1 つ - おそらく合計で 4 ~ 5 になります。ただし、それぞれに適切な数のフィールドが完全に入力されます。table_existing も変更されます。

速度の観点から、より最適なデータベース構造はどれですか? 保守性の観点からは、オプション (B) の方がよいのではないかと思います。


編集1

2 つのオプションのどちらも、アプリケーションで最も重要な/頻繁に使用されるテーブルにはなりません。

オプション (B) では、データが分割された後、データを結合する必要はまったくありません。XX_1 のフィールドが必要であることがわかっている場合は、そのテーブルに移動します。

多くの未使用の値を持つ1つの大きなテーブルを持つことと、同じデータをより多くのテーブルに分割することの長所と短所があるかどうかを理解しようとしています。テーブルの数が増えると、データベースのパフォーマンスが低下しますか?

4

5 に答える 5

19

速度の観点から、より最適なデータベース構造はどれですか?

さて、正しいこと、ベストプラクティスなどは正規化と呼ばれます。これを正しく行うと、オプションの列 (フィールドではない) も Null もなくなります。オプションの列は別のテーブルにあり、行数が少なくなります。確かに、(1 つの PK に加えて) 1 つの列ではなく、オプションの列のセットになるようにテーブルを配置できます。

サブテーブルの行を 1 つの 5NF 行に結合するのは簡単です。これはビューで行います (ただし、ビューを介して更新するのではなく、トランザクション ストアド プロシージャを介して各サブテーブルに対して直接行います)。

より多くの小さなテーブルは、正規化されたリレーショナル データベースの性質です。それに慣れる。正規化、重複、および Null がないため、少数の大きなテーブルは遅くなります。ジョインは SQL< では面倒ですが、それだけです。結合自体にはコストはかかりません。結合されるテーブル (行、行幅、結合列、データ型、不一致、インデックス [または非]) のみです。データベースは、データ ヒープ用ではなく、正規化されたテーブル用に最適化されています。そしてテーブル数が多い。

これがたまたま最適なパフォーマンスであることは驚くことではありません。理由は 2 つあります。

  1. テーブルが狭いため、ページあたりの行数が多くなり、物理 I/O あたりの行数が増え、同じキャッシュ スペースでより多くの行が取得されます。

  2. ヌルがないため、これらの列は長さが固定されており、列の内容を抽出するための解凍はありません。

多くのオプションの (null) 列を含む大きなテーブルには長所はなく、短所のみです。基準に違反することのプロは決していません。

4 つまたは 400 の新しいテーブルを検討しているかどうかに関係なく、答えは変わりません。

  • 多くのテーブルを真剣に検討している場合の推奨事項の 1 つは、気付かないうちに第 6 正規形の方向に向かっていることです。だからそれを認識し、正式にそうしてください。400 のテーブルはより適切に制御されます。専門家にやってもらうと、彼らはそれを正常化し、最終的には 100 未満に戻ります。
于 2010-11-27T06:01:20.483 に答える
2

私は SQL サーバーの DBA であるため、SQL Server 2008 で何をするかを提案します。

既存のテーブルに列を null 許容として追加し、列を SPARSE としてマークします。sparse タグを使用しても、既存のテーブル ページの余分な列のストレージは増加せず、依然として、sparse 列を列としてクエリできます。SQL Server は、スパース列を XML 形式で内部的に格納し、クエリや表示も行うことができます。

新しいテーブル構造を扱えないレガシーアプリがある場合

  1. テーブルの名前を変更する
  2. 元のテーブル構造でビューを作成し、元のテーブル名に名前を付けます

スパース列をサポートしていないバージョンを使用している場合は、既存のテーブルの単一の子テーブルを構築し、親テーブルの ID を使用して子を親にリンクします。2 つのテーブルにまたがるビューを作成して、データを表示します。

于 2010-11-28T15:31:49.770 に答える
0

クエリで (XX,1) セットの行を (YY,2) セットなどと組み合わせる必要がある可能性が高くなりますか?

そうでない場合は、すべてのクエリに使用される個々のテーブルが狭いため、個別のテーブルに分割する方が高速です。

それらを組み合わせると、メインテーブルに対して重複したクエリを必要とする UNION が必要になるため、わずかに遅くなる可能性があります。

于 2010-11-26T15:59:42.927 に答える
0

(B)を選択した場合、JOINなどの複雑さは言うまでもなく、元のField1値をすべて取得するために複数のテーブルに対してクエリを実行する必要があるというDVKに同意します。これは、別々のテーブルに分割しない限り意味がありません異なるエンティティへの分離に対応。

関連するエンティティの詳細と、実行するクエリと更新の種類を知らなければ、あなたの質問に実際に答えることはできないという点で、Paul に同意します。

于 2010-11-26T16:13:32.157 に答える
0

私は以前、これらの疑問を持っていたことを覚えています。

データ検証の観点からは、オプション (B) の方が有利であることがわかります。フィールドに制約をより適切に配置できます。これがまさに、ユーザーの役割に応じて NOT NULL 制約を適用するために、usersテーブルをstudents、などに分割したい理由です。teachers

一般に、テーブルに多数の NULL 値があると、インデックス作成の問題によりパフォーマンスが低下します。

経験則として、結合に含まれるテーブルの数が 4 以下である限り、パフォーマンスへの影響を心配する必要はありません。

編集:データベース内のテーブルの数が心配な場合は、こちらをご覧になることをお勧めします

于 2010-11-26T18:46:46.283 に答える