Dela via


Generera unika identifierare i en lagertabell i Microsoft Fabric

Gäller för:✅ Warehouse i Microsoft Fabric

Det är ett vanligt krav i informationslager att tilldela en unik identifierare till varje rad i en tabell. I SQL Server-baserade miljöer görs detta vanligtvis genom att skapa en identitetskolumn i en tabell, men för närvarande stöds inte den här funktionen i ett lager i Microsoft Fabric. I stället måste du använda en lösningsteknik. Vi presenterar två alternativ.

Den här artikeln beskriver lösningar för att generera unika identifierare i en lagertabell.

Metod 1

Den här metoden är mest tillämplig när du behöver skapa identitetsvärden, men värdenas ordning är inte viktig (icke-sekventiella värden är acceptabla).

Unika värden genereras i koden som infogar data i tabellen.

  1. Om du vill skapa unika data med den här metoden skapar du en tabell som innehåller en kolumn som lagrar unika identifierarvärden. Kolumndatatypen ska vara inställd på bigint. Du bör också definiera kolumnen så NOT NULL att varje rad tilldelas en identifierare.

    Följande T-SQL-kodexempel skapar en exempeltabell med namnet Orders_with_Identifier i dbo schemat, där Row_ID kolumnen fungerar som en unik nyckel.

    --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. När du infogar rader i tabellen genererar du unika data för Row_ID med NEWID() funktionen via T-SQL-skript eller programkod eller på annat sätt. Den här funktionen genererar ett unikt värde av typen uniqueidentifier som sedan kan castas och lagras som en bigint.

    Följande kod infogar rader i dbo.Orders_with_Identifier tabellen. Värdena för Row_ID kolumnen beräknas genom att de värden som returneras av newid() funktionen konverteras. Funktionen kräver ORDER BY ingen sats och genererar ett nytt värde för varje post.

    --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];
    

Metod 2

Den här metoden är mest tillämplig när du behöver skapa sekventiella identitetsvärden men bör användas med försiktighet för större datamängder eftersom den kan vara långsammare än alternativa metoder. Överväganden bör också göras för flera processer som infogar data samtidigt eftersom detta kan leda till duplicerade värden.

  1. Om du vill skapa unika data med den här metoden skapar du en tabell som innehåller en kolumn som lagrar unika identifierarvärden. Kolumndatatypen ska anges till int eller bigint, beroende på mängden data som du förväntar dig att lagra. Du bör också definiera kolumnen så NOT NULL att varje rad tilldelas en identifierare.

    Följande T-SQL-kodexempel skapar en exempeltabell med namnet Orders_with_Identifier i dbo schemat, där Row_ID kolumnen fungerar som en unik nyckel.

    --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. Innan du infogar rader i tabellen måste du fastställa det sista identifierarvärdet som lagras i tabellen. Du kan göra det genom att hämta det maximala identifierarvärdet. Det här värdet ska tilldelas till en variabel så att du kan referera till det när du infogar tabellrader (i nästa steg).

    Följande kod tilldelar det sista identifierarvärdet till en variabel med namnet @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. När du infogar rader i tabellen beräknas unika och sekventiella tal genom att värdet för variabeln @MaxID läggs till i de värden som returneras av funktionen ROW_NUMBER . Den här funktionen är en fönsterfunktion som beräknar ett sekventiellt radnummer som börjar med 1.

    Följande T-SQL-kod – som körs i samma batch som skriptet i steg 2 – infogar rader i Orders_with_Identifier tabellen. Värdena för Row_ID kolumnen beräknas genom att variabeln läggs till i @MaxID värden som returneras av ROW_NUMBER funktionen. Funktionen måste ha en ORDER BY sats som definierar den logiska ordningen för raderna i resultatuppsättningen. Men när det är inställt på SELECT NULL, införs ingen logisk ordning, vilket innebär att identifierarvärden tilldelas godtyckligt. Den här ORDER BY satsen resulterar i en snabbare körningstid.

    --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];