次の方法で共有


Microsoft Fabric の倉庫テーブルで一意識別子を生成する

適用対象:✅Microsoft Fabric のウェアハウス

Data Warehouse では、テーブルの各行に一意識別子を割り当てることが一般的な要件です。 SQL Server ベースの環境では、これは通常、テーブルに ID 列を作成することによって行われますが、この機能は現在、Microsoft Fabric のウェアハウスではサポートされていません。 代わりに、回避技法を使用する必要があります。 2 つの代替策を示します。

この記事では、ウェアハウス テーブルで一意識別子を生成する回避技法について説明します。

方法 1

この方法は、ID 値を作成する必要があるが、値の順序が重要でないときに最適です (非連続の値が許容されます)。

テーブルにデータを挿入するコードで、一意の値が生成されます。

  1. この方法を使用して一意のデータを作成するには、一意識別子の値を保存する列を含むテーブルを作成します。 列のデータ型は、bigint に設定する必要があります。 また、すべての行に識別子が確実に割り当てられるように列を NOT NULL として定義する必要があります。

    次の T-SQL コード サンプルでは、dbo スキーマに Orders_with_Identifier という名前のテーブル例を作成します。ここでは、Row_ID 列が一意キーとして機能します。

    --Drop a table named 'Orders_with_Identifier' in schema 'dbo', if it exists
    IF OBJECT_ID('[dbo].[Orders_with_Identifier]', 'U') IS NOT NULL
        DROP TABLE [dbo].[Orders_with_Identifier];
    GO
    
    CREATE TABLE [dbo].[Orders_with_Identifier] (
        [Row_ID] BIGINT NOT NULL,
        [O_OrderKey] BIGINT NULL,
        [O_CustomerKey] BIGINT NULL,
        [O_OrderStatus] VARCHAR(1) NULL,
        [O_TotalPrice] DECIMAL(15, 2) NULL,
        [O_OrderDate] DATE NULL,
        [O_OrderPriority] VARCHAR(15) NULL,
        [O_Clerk] VARCHAR (15) NULL,
        [O_ShipPriority] INT NULL,
        [O_Comment] VARCHAR (79) NULL
    );
    
  2. テーブルに行を挿入するときは、T-SQL スクリプトまたはアプリケーション コードを使用するか、NEWID() 関数を使用して Row_ID に対して一意のデータを生成します。 この関数は、uniqueidentifier 型の一意の値を生成します。これを、bigint としてキャストおよび保存できます。

    次のコードは、dbo.Orders_with_Identifier テーブルに行を挿入します。 Row_ID 列の値は、newid() 関数によって返される値を変換することで計算されます。 この関数には、ORDER BY 句は必要なく、レコードごとに新しい値が生成されます。

    --Insert new rows with unique identifiers
    INSERT INTO [dbo].[Orders_with_Identifier]
    SELECT
        CONVERT(BIGINT, CONVERT(VARBINARY, CONCAT(NEWID(), GETDATE()))) AS [Row_ID],
        [src].[O_OrderKey],
        [src].[O_CustomerKey],
        [src].[O_OrderStatus],
        [src].[O_TotalPrice],
        [src].[O_OrderDate],
        [src].[O_OrderPriority],
        [src].[O_Clerk],
        [src].[O_ShipPriority],
        [src].[O_Comment]
    FROM [dbo].[Orders] AS [src];
    

方法 2

この方法は、連続する ID 値を作成する必要があるときに最適ですが、別の方法よりも遅くなる可能性があるため、大規模なデータセットについては注意して使用する必要があります。 データを同時に挿入する複数のプロセスについても、値が重複する可能性があるため、考慮する必要があります。

  1. この方法を使用して一意のデータを作成するには、一意識別子の値を保存する列を含むテーブルを作成します。 データの保存予想量に応じて、列のデータ型を int または bigint に設定する必要があります。 また、すべての行に識別子が確実に割り当てられるように列を NOT NULL として定義する必要があります。

    次の T-SQL コード サンプルでは、dbo スキーマに Orders_with_Identifier という名前のテーブル例を作成します。ここでは、Row_ID 列が一意キーとして機能します。

    --Drop a table named 'Orders_with_Identifier' in schema 'dbo', if it exists
    IF OBJECT_ID('[dbo].[Orders_with_Identifier]', 'U') IS NOT NULL
        DROP TABLE [dbo].[Orders_with_Identifier];
    GO
    
    CREATE TABLE [dbo].[Orders_with_Identifier] (
        [Row_ID] BIGINT NOT NULL,
        [O_OrderKey] BIGINT NULL,
        [O_CustomerKey] BIGINT NULL,
        [O_OrderStatus] VARCHAR(1) NULL,
        [O_TotalPrice] DECIMAL(15, 2) NULL,
        [O_OrderDate] DATE NULL,
        [O_OrderPriority] VARCHAR(15) NULL,
        [O_Clerk] VARCHAR (15) NULL,
        [O_ShipPriority] INT NULL,
        [O_Comment] VARCHAR (79) NULL
    );
    GO
    
  2. テーブルに行を挿入する前に、テーブルに格納されている最後の識別子の値を決定する必要があります。 これを行うには、識別子の最大値を取得します。 (次の手順で) テーブル行を挿入するときに参照できるように、この値を変数に割り当てる必要があります。

    次のコードは、最後の識別子の値を @MaxID という名前の変数に割り当てます。

    --Assign the last identifier value to a variable
    --If the table doesn't contain any rows, assign zero to the variable
    DECLARE @MaxID AS BIGINT;
    
    IF EXISTS(SELECT * FROM [dbo].[Orders_with_Identifier])
        SET @MaxID = (SELECT MAX([Row_ID]) FROM [dbo].[Orders_with_Identifier]);
    ELSE
        SET @MaxID = 0;
    
  3. テーブルに行を挿入すると、ROW_NUMBER 関数によって返される値に @MaxID 変数の値を追加することによって、一意の連続する数値が計算されます。 この関数は、1 から始まる連続する行番号を計算するウィンドウ関数です。

    次の T-SQL コードは、手順 2 のスクリプトと同じバッチで実行され、Orders_with_Identifier テーブルに行を挿入します。 Row_ID 列の値は、ROW_NUMBER 関数によって返される値に @MaxID 変数を追加することによって計算されます。 この関数には、結果セット内の行の論理順序を定義する ORDER BY 句が必要です。 ただし、これが SELECT NULL に設定されていると、論理的な順序は適用されません。つまり、識別子の値は任意に割り当てられます。 この ORDER BY 句を使用すると、実行時間が短縮されます。

    --Insert new rows with unique identifiers
    INSERT INTO [dbo].[Orders_with_Identifier]
    SELECT
        @MaxID + ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS [Row_ID],
        [src].[O_OrderKey],
        [src].[O_CustomerKey],
        [src].[O_OrderStatus],
        [src].[O_TotalPrice],
        [src].[O_OrderDate],
        [src].[O_OrderPriority],
        [src].[O_Clerk],
        [src].[O_ShipPriority],
        [src].[O_Comment]
    FROM [dbo].[Orders] AS [src];