Do czego służy kolumna Row_GUID?

18

Kopałem w bazie danych AdventureWorks2012 i widzę Row_GUID używany w kilku tabelach.

Moje pytanie składa się z 2 części:

Kiedy powinienem dołączyć kolumnę Row_GUID?

Jakie są zastosowania i zalety kolumny Row_GUID?

SQLSuperHero
źródło

Odpowiedzi:

25

ROWGUIDCOLjest używany głównie do replikacji MERGE i jest również wymaganyFILESTREAM , ale może być stosowany w każdym scenariuszu, w którym chcesz niezmienną kolumnę oddzieloną od klucza podstawowego (np. w przypadku, gdy wartość klucza podstawowego może się zmienić, ale nadal chcesz być w stanie stwierdzić, który wiersz był przed i po zmianie).

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;

Teraz, jeśli replikacja, twoja aplikacja lub to, na co zwracasz uwagę, zauważy, że:

wprowadź opis zdjęcia tutaj

Zobacz tutaj , tutaj i sekcję „Uwagi dotyczące migawki” tutaj, aby uzyskać więcej informacji.

Aaron Bertrand
źródło
Dodanie ROWGUIDCOLUMN do replikowanych tabel gwarantuje, że silnik replikacji może użyć pola ROWGUIDCOLUMN do rozróżnienia rekordów o tych samych wartościach klucza podstawowego. - Bogaty Turner - stackoverflow.com/questions/4443036/…
Jewgienij Andriejiewicz Zhivago
2
@YevgrafAndreyevichZhivago Jak dwa wiersze mogą mieć takie same wartości klucza podstawowego? Miałeś na myśli klucze kandydujące (ale również nie zdefiniowane jednoznacznie )?
Aaron Bertrand
13

Oznaczenie kolumny jako ROWGUIDCOLumożliwiające odwołanie do niej $ROWGUIDw zapytaniach. Pozwala to uczynić zapytania bardziej ogólnymi, ponieważ nie trzeba sprawdzać, dla każdej tabeli, co to jest „unikalna” kolumna (jest to dość przydatne w przypadku funkcji takich jak Replikacja i FileStream, jak zauważyli odpowiednio @Aaron i @Martin ). Możesz utworzyć zapytanie w warstwie aplikacji, a nawet w dynamicznym SQL, które działa podobnie SELECT $ROWGUID AS [ID] FROM {table_name}i po prostu iteruje listę tabel.

Pamiętaj tylko, że ROWGUIDCOLoznaczenie nie wymusza wyjątkowości. Nadal będziesz musiał to egzekwować za pomocą klucza podstawowego, unikalnego indeksu lub unikalnego ograniczenia. Ta opcja nie wymusza również niezmienności kolumny. Do tego potrzebne byłyby uprawnienia AFTER UPDATETrigger lub uprawnienia DENY UPDATEna poziomie kolumny w tej kolumnie.

Na przykład:

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;

Zwraca coś podobnego do:

@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

Podobnie można użyć $IDENTITYdo tabel, które mają IDENTITYkolumnę.

Solomon Rutzky
źródło