3

既に 32 列あるテーブルに 64 個の新しい列を追加する必要に直面しています。例のために:

Customers
(
    CustomerID int
    Name        varchar(50)
    Address     varchar(50)
    City        varchar(50)
    Region      varchar(50)
    PostalCode  varchar(50)
    Country     varchar(2)
    Telephone   varchar(20)

    ...
    NewColumn1  int null
    NewColumn2  uniqueidentifier null
    NewColumn3  varchar(50)
    NewColumn4  varchar(50)
    ...
    NewColumn64 datetime null

    ...
    CreatedDate datetime
    LastModifiedDate datetime
    LastModifiedWorkstation varchar(50)
    LastModifiedUser varchar(50)
)

ほとんどの場合、これらの新しい列の大部分には が含まれますnull

また、これらSELECTの 64 個の新しい列を新しいテーブルに垂直方向に分割すると、顧客からのたびに次のようになります。

SELECT ...
FROM Customers

分割された値を取得するには、結合に変換する必要があります (つまり、新しい列を必要としない場合にパフォーマンスが向上することはありません)

SELECT ...
FROM Customers
    INNER JOIN Customers_ExtraColumns
    ON Customers.CustomerID = Customers_ExtraColumns.CustomerID

これは、列を分割することの 1 つの欠点です。

もう 1 つの短所は、行を 1 つだけではなく 2 つのテーブルに同時に挿入する必要があることです。

私が考えることができる最後の詐欺は、SQL Server が「 CustomersINNER JOIN 」にアクセスしたいときにいつでも実行する必要があるということです。実際には 1 つのテーブルであるテーブルを結合するための CPU と I/O の浪費は、今後も永遠に続きます。ただし、それらを分割することにした場合を除きます。

だから私の質問は:なぜ私はそれらを分割するのですか?

ほとんどがnullになる場合、64列を別のテーブルに垂直に分割することに価値はありますか? Null はほとんどスペースを占有しません....

長所は何ですか?

編集:なぜ私はパーティショニングを考えているのですか? テーブル内の列数を 3 倍にするのは、ほとんどが null データです。きっと悪いに違いない!

4

3 に答える 3

2

データモデルを簡単にするために、詳細な情報がなければ、おそらく分割しないでしょうが、これらの新しい列のデータの性質を示していません (おそらく、一部の列は代わりに正規化する必要がある配列です)。

ただし、いくつかの点:

垂直分割を行い、補助テーブルに FK 制約がある場合、1 つの行のみが存在することがわかっているため、一部のシナリオでは結合を排除するのに役立つ場合があります。明らかに、同じ一意のキーでインデックスが作成されます。これにより、0 行または 1 行しか存在できないため、クロス結合があるかどうかを判断する必要がなくなります。

2 つのテーブルを結合する単一の更新可能なビューを作成し、ビューを作成するために結合された 2 つのテーブルに挿入するビューにトリガーを設定できます。また、左結合を実行し、それを必要とする列のいずれかが非 NULL である場合にのみ補助行を作成することもできます。

まばらに結合された補足データのテーブルのセットを使用することもできます。明らかに、これにも結合が必要ですが、1 の場合と同様に、複数の補助テーブルで同様の手法を使用することもできます。

于 2010-08-17T03:15:51.810 に答える
1

答えは、質問から省略された詳細にあります。列の数は関係ありません。重要なのはデータの性質です。

  • まず、テーブル内の特定の行が 8060 バイトを超えることはできないことに注意してください。そのため、理論的にはその制限を超えることができるように新しい列のサイズが設定されている場合、データベースに時限爆弾が組み込まれていることになります。都合の悪いときに、データの挿入または更新でエラーが発生したり、データが失われたりすることがあります。

    これを防ぐには、複数のテーブルを使用する必要がある場合があります。これは、SQL Server のほとんどのエディションの制限です。
    .

  • もう 1 つの重要な考慮事項は、データ モデリングです。新しい列は と 1 対 1 の関係にあり CustomerIDますか? たとえば、 eyeColor?

    列の数と名前を省略したという事実から、正規化されていない設計が検討されていると思われます。新しい列がWebPage1WebPage2、などの場合、これらを別の正規化WebPage3されたテーブルに分割する必要があります。 .

しかし、列が本当に一意のアイテムであり、互いに関連がなく、CustomerID(またはそのテーブルの主キーが何であれ) と 1 対 1 の関係にあり、サイズ制限を破ることができない場合、すべてを 1 つにまとめることができます。テーブルはまったく問題ありません。

于 2010-08-17T03:04:06.690 に答える
1

これらの値が a) レコードに固有である場合 (特定の顧客は、NewColumn1 に入る値を 1 つだけ持つ必要があります)、および b) 他のレコードで使用されていない場合 (少なくとも、基本顧客も必要としない他のレコードはありません)情報) それらを 1 つのテーブルのままにしておくといいでしょう。テーブルに対して作成するクエリでは、特定の列に名前を付けることを忘れないでください。

私は EDI のバックグラウンドを持っており、行ごとに 30 列以上のデータを含むフラットファイルを処理する必要がある場合があります。あなたが言及NULLしたように、多くのスペースを占有しません。また、列を個別に取得することが決してない場合 (そして、ベースの顧客データを個別に取得することは決してできません)、私はあなたが持っていると思いますそれは正しい。

于 2010-08-16T19:45:48.920 に答える