1

OLTP に次のテーブル ルックアップ テーブルがあります。

CREATE TABLE TransactionState
(
    TransactionStateId INT IDENTITY (1, 1) NOT NULL,
    TransactionStateName VarChar (100)
)

これが OLAP に入ると、次のように構造を変更します。

CREATE TABLE TransactionState
(
    TransactionStateId INT NOT NULL, /* not an IDENTITY column in OLAP */
    TransactionStateName VarChar (100) NOT NULL,
    StartDateTime DateTime NOT NULL,
    EndDateTime NULL
)

私の質問は、TransactionStateId 列に関するものです。時間の経過とともに、OLAP で TransactionStateId 値が重複することがありますが、StartDateTime と EndDateTime の組み合わせにより、それらは一意になります。

OriginalTransactionStateId が追加され、着信 TransactionStateId がそれにマップされ、さらに新しい TransactionStateId IDENTITY フィールドが PK になり、結合に使用されるタイプ 2 ディメンションのサンプルを見てきました。

CREATE TABLE TransactionState
(
    TransactionStateId INT IDENTITY (1, 1) NOT NULL,
    OriginalTransactionStateId INT NOT NULL, /* not an IDENTITY column in OLAP */
    TransactionStateName VarChar (100) NOT NULL,
    StartDateTime DateTime NOT NULL,
    EndDateTime NULL
)

学士号 #2 または学士号 #3 を使用する必要がありますか?

4

3 に答える 3

2

この句によって:

と の組み合わせでStartDateTimeEndDateTimeそれらは一意になります。

重複しないということですか、それともデータベースのUNIQUE制約を満たしているということですか?

前者の場合、 in 結合を使用できますが、の代わりに条件StartDateTimeを使用するため、非効率になる可能性があることに注意してください。"<=""="

後者の場合は、偽の ID を使用してください。

一般に、データベースでは、このクエリに対して効率的なアルゴリズムを使用できません。

SELECT  *
FROM    TransactionState
WHERE   @value BETWEEN StartDateTime AND EndDateTime

SPATIAL、データで難解なトリックをしない限り。

そのため、この条件を次のように使用する必要がありますJOIN

SELECT  *
FROM    factTable
CROSS APPLY
        (
        SELECT  TOP 1 *
        FROM    TransactionState
        WHERE   StartDateTime <= factDateTime
        ORDER BY
                StartDateTime DESC
        )

を使用する可能性をオプティマイザから奪いますHASH JOIN。これは、多くの場合、そのようなクエリに対して最も効率的です。

このアプローチの詳細については、次の記事を参照してください。

使用できるようにクエリを書き直すHASH JOINと、600%時間のパフォーマンスが向上しますが、日時の精度が 1 日以下の場合 (またはハッシュ テーブルが非常に大きくなる場合) にのみ可能です。

StartDateTime時間コンポーネントがandから取り除かれているため、次のようなEndDateTimeを作成できます。CTE

WITH    cal AS
        (
        SELECT CAST('2009-01-01' AS DATE) AS cdate
        UNION ALL
        SELECT DATEADD(day, 1, cdate)
        FROM   cal
        WHERE  cdate <= '2009-03-01'
        ),
        state AS
        (
        SELECT  cdate, ts.*
        FROM    cal
        CROSS APPLY
                (
                SELECT  TOP 1 *
                FROM    TransactionState
                WHERE   StartDateTime <= cdate
                ORDER BY
                        StartDateTime DESC
                ) ts
        WHERE   ts.EndDateTime >= cdate
        )
SELECT  *
FROM    factTable
JOIN    state
ON      cdate = DATE(factDate)

日付範囲が複数の日付にまたがる場合は、オプションを100調整してください。MAXRECURSIONCTE

于 2009-07-28T16:54:19.973 に答える
1

IDENTITY(1,1)これは、その列に値を自動生成するための宣言であることに注意してください。PRIMARY KEYこれは、列を主キーのクラスター化インデックスにする宣言であるとは異なります。これらの2つの宣言は異なる意味を持ち、言わないとパフォーマンスに影響がありますPRIMARY KEY

于 2009-07-28T17:03:45.587 に答える
1

SSIS を使用して DW を読み込むこともできます。緩やかに変化するディメンション(SCD) 変換では、各属性の処理方法を設定できます。履歴属性が選択されている場合、タイプ 2 の SCD が行全体に適用され、変換によって詳細が処理されます。start_date必要に応じて、end_dateまたはcurrent/expired列を構成することもできます。

ここで区別すべきことは、主キーとビジネス (自然) キーの違いです。主キーは、テーブル内の行を一意に識別します。ビジネス キーは、ビジネス オブジェクト/エンティティを一意に識別し、ディメンション テーブルで繰り返すことができます。SCD 2 が適用されるたびに、新しい主キーを持つ新しい行が挿入されますが、ビジネス キーは同じです。古い行は期限切れとしてマークされ、新しい行は最新としてマークされます。または、開始日と終了日のフィールドが適切に入力されます。

DW は主キーを公開すべきではないため、OLTP からの受信データにはビジネス キーが含まれますが、主キーの割り当ては DW の管理下にあります。IDENTITY int は、ディメンション テーブルの PK に適しています。

すばらしいことに、SSIS の SCD 変換がこれを処理します。

于 2009-11-29T04:50:37.097 に答える