À quoi sert une colonne Row_GUID?

18

J'ai fouillé dans la base de données AdventureWorks2012 et je vois Row_GUID utilisé dans plusieurs tables.

Il y a 2 parties à ma question:

Quand dois-je inclure une colonne Row_GUID?

Quels sont les usages et les avantages d'une colonne Row_GUID?

SQLSuperHero
la source

Réponses:

25

ROWGUIDCOLest principalement utilisé pour la réplication MERGE , et est également requis pourFILESTREAM , mais peut être utilisé dans n'importe quel scénario où vous voulez une colonne immuable distincte de la clé primaire (par exemple dans le cas où une valeur de clé primaire peut changer, mais vous voulez toujours être capable de dire quelle ligne était laquelle avant et après le changement).

USE tempdb;
GO

CREATE TABLE dbo.example
(
  name sysname PRIMARY KEY, 
  rowguid uniqueidentifier NOT NULL DEFAULT NEWID() ROWGUIDCOL
);

INSERT dbo.example(name) VALUES(N'bob'),(N'frank');

SELECT * FROM dbo.example;

UPDATE dbo.example SET name = N'pat' WHERE name = N'bob';
UPDATE dbo.example SET name = N'bob' WHERE name = N'frank';

SELECT * FROM dbo.example;

DROP TABLE dbo.example;

Maintenant, si la réplication, ou votre application, ou ce que vous avez fait attention, elle remarquera que:

entrez la description de l'image ici

Voir ici , ici , et la section "Considérations sur les instantanés" ici pour plus d'informations.

Aaron Bertrand
la source
L'ajout d'un ROWGUIDCOLUMN aux tables en cours de réplication garantit que le moteur de réplication peut utiliser le champ ROWGUIDCOLUMN pour différencier les enregistrements avec les mêmes valeurs de clé primaire. - Rich Turner - stackoverflow.com/questions/4443036/…
Yevgraf Andreyevich Zhivago
2
@YevgrafAndreyevichZhivago Comment deux lignes peuvent-elles avoir les mêmes valeurs de clé primaire? Voulez-vous dire les clés candidates (mais pas non plus explicitement définies )?
Aaron Bertrand
13

Le marquage d'une colonne ROWGUIDCOLpermet de la référencer via $ROWGUIDdans les requêtes. Cela permet de rendre les requêtes plus génériques car vous n'avez pas besoin de rechercher, pour chaque table, ce qu'est la colonne "unique" (cela est très utile pour des fonctionnalités telles que la réplication et FileStream comme indiqué par @Aaron et @Martin, respectivement ). Vous pouvez avoir une requête construite dans la couche d'application, ou même dans Dynamic SQL, qui fait quelque chose comme SELECT $ROWGUID AS [ID] FROM {table_name}et simplement itère sur une liste de tables.

N'oubliez pas que la ROWGUIDCOLdésignation n'impose pas l' unicité. Vous devrez toujours appliquer cela via une clé primaire, un index unique ou une contrainte unique. Cette option n'impose pas non plus que la colonne soit immuable. Pour cela, vous auriez besoin d'un AFTER UPDATEdéclencheur ou d'autorisations de niveau DENY UPDATEcolonne sur cette colonne.

Par exemple:

SET NOCOUNT ON;
CREATE TABLE #RowGuidColTest
(
  ID UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWID()) ROWGUIDCOL,
  SomeValue INT
);

INSERT INTO #RowGuidColTest (SomeValue) VALUES (12), (14), (1231);

DECLARE @Search UNIQUEIDENTIFIER;

SELECT TOP (1) @Search = $ROWGUID
FROM   #RowGuidColTest;

SELECT @Search AS [@Search]

SELECT *, $ROWGUID AS [$ROWGUID]
FROM   #RowGuidColTest;

SELECT *
FROM   #RowGuidColTest
WHERE  $ROWGUID = @Search;

-- No enforced uniqueness without a PK, Unique Index, or Unique Constraint.
UPDATE tmp
SET    $ROWGUID = @Search
FROM   #RowGuidColTest tmp

SELECT *
FROM   #RowGuidColTest
WHERE  $ROWGUID = @Search;

Renvoie quelque chose de similaire à:

@Search
E7166D18-5003-4D20-8983-E2402472CF82


ID                                      SomeValue    $ROWGUID
E7166D18-5003-4D20-8983-E2402472CF82    12           E7166D18-5003-4D20-8983-E2402472CF82
44FD48A4-AF38-41BF-AE4E-8A12D26B5B57    14           44FD48A4-AF38-41BF-AE4E-8A12D26B5B57
2D50C5C7-1E43-4ADA-A03B-ED202FC88D20    1231         2D50C5C7-1E43-4ADA-A03B-ED202FC88D20


ID                                      SomeValue
E7166D18-5003-4D20-8983-E2402472CF82    12


ID                                      SomeValue
E7166D18-5003-4D20-8983-E2402472CF82    12
E7166D18-5003-4D20-8983-E2402472CF82    14
E7166D18-5003-4D20-8983-E2402472CF82    1231

De même, on pourrait utiliser $IDENTITYpour les tables qui ont une IDENTITYcolonne.

Solomon Rutzky
la source