タイプ1および2の属性を持つディメンションの形成方法

私たちは電気通信でDWHに取り組んでいるので、私が検討している例は「加入者」と呼ばれています。 原則は普遍的であり、業界に応じて「クライアント」または「患者」になります。 この方法論が、さまざまな業界のDWH開発者に役立つことを願っています。



DWH、測定値、および事実がわからない場合は、Ralph Kimballの書籍Dimensional Modelingを読むことをお勧めします。 私たちは、企業の分析と統合レポートのためのデータベース、具体的には測定の形成と更新、つまり将来のクエリで選択(WHERE)のための属性(フィールド)を格納するテーブルについて話している。



私たちのテクニックはMicrosoft SQL Server用です。



定義の原則の変更



タイプ1(書き換え可能)および2(測定レコードへの履歴の保存)の属性の変更は、フィールドのチェックサムの比較に基づいて決定されます。



チェックサムを計算するには、T-SQL CHECKSUM関数を使用します。この関数は、ディメンションに収まらないtext、ntext、imageのタイプをサポートしません。 実際にBINARY_CHECKSUMを使用すると、NULLを含むフィールドの変更を誤って検出できることが示されています。 この手法を使用すると、.NETで開発されたカスタムチェックサム関数を使用できます。



測定のお知らせ



ディメンションは、クラスター化インデックスを含む主キーで宣言する必要があります。



「サブスクライバー」ディメンション宣言のSQLスクリプトの例:



USE [DWH] GO /*     Dim */ IF SCHEMA_ID('Dim') IS NULL EXECUTE('CREATE SCHEMA [Dim] AUTHORIZATION [dbo]') GO /*   */ IF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[Dim].[]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1 ) DROP TABLE [Dim].[] GO /*   */ CREATE TABLE [Dim].[] ( [AccountKey] INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, [ ] INT NULL, [ ] NVARCHAR(13) NOT NULL CHECK ([ ] IN (N'.', N'.', N' ')) DEFAULT N' ', [] NVARCHAR(16) NOT NULL DEFAULT N' ', [ ] NVARCHAR(50) NOT NULL DEFAULT '   ', [  ] DATE, [  ] DATE, [] NVARCHAR(100) NOT NULL DEFAULT '   ', [] NVARCHAR(100) NOT NULL DEFAULT '   ', [] NVARCHAR(100) NOT NULL DEFAULT '   ', [ ] DATE, [] AS [] + CASE WHEN [] != N'   ' THEN N' ' + [] ELSE N'' END + CASE WHEN [] != N'   ' THEN N' ' + [] ELSE N'' END, [ ] NVARCHAR(100) NOT NULL DEFAULT N'   ', ... [] NVARCHAR(200) NOT NULL DEFAULT N'   ', [  SMS] NVARCHAR(20) NOT NULL DEFAULT N'   ', [] NVARCHAR(200) NOT NULL DEFAULT N'   ', [E-mail] NVARCHAR(50) NOT NULL DEFAULT N'   ', [ ] AS N': ' + [] + N', ' + N'  SMS: ' + [  SMS] + N', ' + N': ' + [] + N', ' + N'E-mail: ' + [E-mail], [StartTime] DATETIME2 NOT NULL, [EndTime] DATETIME2 NULL, [Checksum1] INT NULL, [Checksum2] INT NULL ) /*    */ SET IDENTITY_INSERT [Dim].[] ON INSERT INTO [Dim].[] ([AccountKey],[ ],[StartTime]) VALUES (-1, NULL, GETDATE()) SET IDENTITY_INSERT [Dim].[] OFF GO
      
      







チェックサムフィールドを含む測定の条件[EndTime] IS NULLを使用して、ビジネスキーに条件付きインデックスを課す必要があります。 インデックスにチェックサムを含めると、測定テーブルの主キーのクラスターインデックス([AccountKey])に従って、最初のクエリの実行時に測定テーブル自体を読み取れないようになります。 同時に、インデックスは一意性制御の機能を実行します-1つのビジネスキーに対して1つの有効なレコード。



「サブスクライバー」測定のインデックスの例:



 CREATE UNIQUE INDEX IX__ ON [Dim].[] ([ ], [EndTime]) INCLUDE ([Checksum1], [Checksum2]) WHERE [EndTime] IS NULL
      
      







典型的な初期SQLクエリ


最初のSQLクエリには、ソースコピーテーブルからフィールドを受け取る内部サブクエリ[i]と、チェックサムを生成し、現在の測定行をビジネスキーと結合する外部クエリ[o]が含まれます。



「サブスクライバー」ディメンションの初期クエリの例:



 SELECT [o].*, [].[Checksum2] AS [OLD_CHECKSUM2], [].[Checksum1] AS [OLD_CHECKSUM1], [].[AccountKey] AS [OLD_AccountKey] FROM ( SELECT i.*, CHECKSUM( [ ], [], [ ], [  ], [], [], [], [ ], [], [], [], [], [ ], [ ] ) AS [CHECKSUM2], CHECKSUM( [], [  SMS], [E-mail], [ ] ) AS [CHECKSUM1] FROM ( SELECT FROM [Raw].... LEFT JOIN [Raw].... ) AS [i] --     ) AS [o] --      LEFT JOIN [Dim].[] ON [o].[ ] = [].[ ] AND [].[EndTime] IS NULL --     
      
      







型変換(通常はCAST(... AS NVARCHAR(..))またはIIF(ISDATE([...])= 1、CAST([...] AS DATE)、NULL))、およびバインディング全体ソーステーブル(LEFT JOIN)および条件付きフィールド形成(CASE、IIF)は、内部クエリで実行する必要があります-FROM(...)AS [i]内。



ソーステーブルをリンクするロジックが複雑すぎて(たとえば、階層からデータをプルする必要がある場合)、FROM内で実行できない場合、SSISのデータフローの前に、SQLタスクを挿入する必要があります。オブジェクト)。 一時テーブルは、SSISが出力ストリームのメタデータをそこから判断できないため、機能しません。



実行プランを調べることにより、インデックスと最初のクエリ間の相互作用の正確性を確認できます。 実行計画の最後に、テーブルへの参照がないはずです。



画像



典型的なデータストリーム



ディメンションを形成するデータのフローは、上記の初期SQLクエリを残し、さらに変更ロジックを実装します。



画像



「StartTimeの追加」操作で、SSISパッケージの開始時間を使用してStartTimeをストリームに追加します(変数@ [System :: StartTime]を取得します)



「タイプ1更新の検出」操作では、式に基づいて「タイプ1フィールドが更新されます」という1つのストリームを選択します!ISNULL(OLD_CHECKSUM1)&& CHECKSUM1!= OLD_CHECKSUM1。



「ビジネスキーによるタイプ1のフィールドの更新」操作では、最初のタイプの属性が変更されたすべてのディメンションレコード(タイプ2フィールドの履歴値を含む既に閉じたレコードを含む)を更新します-このため、無関係なレコードを切り捨てる条件のないビジネスキーを使用([EndTime]の条件なし)。 「サブスクライバー」の例:



 UPDATE [Dim].[] SET [] = ?, [  SMS] = ?, [E-mail] = ?, [ ] = ? [Checksum1] = ? WHERE [ ] = ?
      
      







「タイプ2更新および新規レコードの検出」操作では、2つのストリームを区別します。

  1. ISNULL式に基づく「新規」(OLD_AccountKey)
  2. 式CHECKSUM2!= OLD_CHECKSUM2に基づく「Type2フィールドが更新されました」




「変更された測定行を閉じる」操作で、測定レコードの[EndTime]をストリームのStartTime値で更新します。 「サブスクライバー」の例:



 UPDATE [Dim].[] SET [EndTime] = ? WHERE [AccountKey] = ?
      
      







「ディメンションへの行の挿入」操作では、新しい行を挿入すると同時に、ストリームからStartTimeを[StartTime]フィールドに挿入し、測定キーと[EndTime]を無視します([EndTime]フィールドで生成されたNULLは現在のレコードの符号になります)。



最後の操作に貼り付ける場合、更新と同じスレッドで実行される挿入は、ロックをテーブルレベルに拡張せずに行で操作する必要があるため、高速ロードモードを使用しても機能しません。そうしないと、同時に実行される操作間に競合が発生します。 または、操作を制御フローの異なるステップに分割し、RawまたはCacheに中間結果を保存し、操作の順序を観察できます。



トランザクションの使用



データフローコンテナ(または、制御フローのステップで操作を分割した場合は一般的なコンテナ)のレベルでは、トランザクションを含めることが望ましいです。 これを行うには、TransactionOption = Required(DTCが必要)およびIsolationLevelをReadCommittedより低く設定します。



トランザクションがない場合、データフローの中断中に、関連する実際のレコードを挿入せずに、測定レコードの一部が閉じたままになることがあります。 次の開始時に、不足しているエントリは新規として挿入されますが、開始時間は前の行の終了時間とは異なります。 これは、ファクトが発生時に関連するレコードを添付する方法によってファクトが測定に関連付けられている場合、つまり、測定が終了時間によってのみリンクされている場合に動作する場合に考慮する必要があります。



他の方法との比較



緩やかに変化するディメンションと呼ばれる標準のSQL Server Integration Servicesコンポーネントの使用と比較すると、このメソッドは各フィールドをディメンション行の各フィールドと比較せず、テーブルにアクセスしてそのような比較を行いません。 これは主な利点-速度を提供します。 さらに、標準の緩やかに変化するディメンションは、要素のチェーン全体をすぐに制御するため、要素のカスタマイズが困難になります。 私にはわからない理由で、標準のSSISコンポーネントは変更を誤って検出する可能性があります(おそらくこれもNULLフィールドに関連しています)。



サードパーティの商用コンポーネントと比較して、SQL Serverリリースに付属している標準のコンポーネントと機能に基づいているという点で、この方法には基本的な利点があります。 したがって、更新されたコンポーネントが次のバージョンのSQL Serverにアップグレードされるのを待つ必要はありません。



メソッドの変更



SQLクエリではなく、Lookup操作を介してSSISデータストリームで結合が実行される、修正されたメソッドが可能です。 これにより、データベース呼び出しが増え、効率的なハッシュマッチが効率の悪い単一のリクエストに置き換えられます。 一方、これにより、ソーステーブル(ソースシステムからの読み込みの段階で生成されたコピーテーブル)と異なるサーバー上の測定テーブルを分離できます。 しかし、この機会の利点は疑わしい。



結合結合操作を介してSSISストリームに結合することは可能ですが、テーブルを取得して並べ替える必要があり、インデックスの利点が無効になります。



チェックサムの計算は、たとえば個別のコンポーネントとしてデータストリームでも可能ですが、この場合、個別のコンポーネントが必要ないという利点はなくなります。



C#のスクリプト変換を使用したデータストリームのチェックサムの計算は、この複雑さが理にかなっている場合、可能な修正オプションです。



Konesansからチェックサムを計算するための無料のサードパーティコンポーネントを使用し、カスタムルックアップ(インデックスを使用する)を使用する、変更されたメソッド(以前のバージョンの実際)の実装の概要(スクリーンショット付き)は、 ここにあります



All Articles