何时使用GUID作为主键?

4

可能是重复问题:
GUID / UUID数据库键的优缺点

在SQL Server 2005/8 DB中,是否有必要在某些情况下使用GUID作为主键?例如,MS Sync Framework的使用或数据复制是否强制使用GUID?


抱歉,这是一个重复的问题,已经在https://dev59.com/UHVD5IYBdhLWcg3wO5AD中有回答。我现在会关闭它! - Colin Desmond
3个回答

17
如果需要通过复制进行多个数据库的同步,可以使用GUID作为键。另一个使用GUID的原因是,如果您想要在某些远程客户端(例如WinForms应用程序)上创建行,然后通过Web服务等提交到服务器。如果这样做,我强烈建议您确保指定基于自动递增int而不是唯一的聚集索引。如果聚集索引是GUID,则向表中插入行可能会导致相当大的开销。
更新:以下是如何设置此类表的示例:
CREATE TABLE [dbo].[myTable](
[intId] [int] IDENTITY(1,1) NOT NULL,
[realGuidId] [uniqueidentifier] NOT NULL,
[someData] [varchar](50) NULL,
    CONSTRAINT [PK_myTable] UNIQUE NONCLUSTERED 
    (
   [realGuidId] ASC
    )
)

CREATE CLUSTERED INDEX [IX_myTable] ON [dbo].[myTable] 
(
[intId] ASC
)

您可以像平常一样插入到表中,例如:

INSERT INTO myTable VALUES(NEWID(), 'Some useful data goes here')

更新:我听了一期非常好的dotnetrocks节目,讨论了这个话题,值得一听 - Show #447


只是为了明确,我会将我的主键保留为GUID以便于分发/复制(这是我们需要的),但是引入一个新的非唯一聚集索引,该索引可能(在复制后)包含多个相同的条目。那么,我如何让SQL Server在插入时使用此索引而不是PK,还是它是自动的? - Colin Desmond
1
对于单独的聚集索引,加1。永远不要使用GUID作为聚集索引,性能极差。 - Robin Day
如果一个独立的聚集索引是未使用的列,那么它有什么用呢? - cjk
主要是性能问题。使用此方法可以保持所有索引的大小,并且可以帮助防止在使用GUID作为键时出现的索引碎片化问题。 - John Hunter
更新:事实证明,在高 I/O 系统中,使用非连续 GUID 作为聚集索引实际上可以极大地提高性能,因为页面分裂比尝试将所有内容插入到最后一页时造成的争用要便宜得多。请参考此链接了解详情:http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generating-scalable-keys/ - Triynko
显示剩余2条评论

3

我使用GUID作为主键,因为在构建与分布式数据库和一个中央数据库同步所有分布式数据库数据的应用程序时,我不想使用复合主键。使用GUID,我几乎确定当我从所有数据库中提取数据到中央数据库时不会发生冲突(约束违规)。

* 某个GUID在两个不同地方生成相同的概率很小,但不是不可能的。


1
我愿意冒GUID冲突的风险 ;) - Colin Desmond
是的,不要误会我的意思。虽然这种情况发生的概率不为零,但 GUID 对于那种用途非常合适。 :-) - Petros
请确保在 SQL Server 中不要将 GUID 用作聚集索引 - 它们在这方面非常糟糕。使用 INT(IDENTITY)或类似的东西 - 更好。 - marc_s

2

当数据库不是集中式的或者部分采集是远程执行的时候。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接