I've been digging around in the AdventureWorks2012 database and see Row_GUID used in several tables.
There are 2 parts to my question:
When should I include a Row_GUID column?
What are the uses and benefits of a Row_GUID column?
I've been digging around in the AdventureWorks2012 database and see Row_GUID used in several tables.
There are 2 parts to my question:
When should I include a Row_GUID column?
What are the uses and benefits of a Row_GUID column?
ROWGUIDCOL is primarily used for MERGE replication, and is also required for FILESTREAM, but can be used in any scenario where you want an immutable column separate from the primary key (e.g. in the case where a primary key value can change, but you still want to be able to tell which row was which before and after the change).
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;
Now, if replication, or your application, or what have you is paying attention, it will notice that:
See here, here, and the "Snapshot Considerations" section here for more info.
Marking a column as ROWGUIDCOL allows it to be referenced via $ROWGUID in queries. This allows for making queries more generic since you wouldn't need to look up, per each table, what the "unique" column is (this is quite useful for features such as Replication and FileStream as noted by @Aaron and @Martin, respectively). You could have a query constructed in the app layer, or in Dynamic SQL even, that does something like SELECT $ROWGUID AS [ID] FROM {table_name} and simply iterate over a list of tables.
Just keep in mind that the ROWGUIDCOL designation does not enforce uniqueness. You will still need to enforce that via a Primary Key, a Unique Index, or a Unique Constraint. Nor does this option enforce that the column is immutable. For that you would need either an AFTER UPDATE Trigger or column-level permissions to DENY UPDATE on that column.
For example:
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;
Returns something similar to:
@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
Similarly, one could use $IDENTITY for tables that have an IDENTITY column.