我正在用SqlServer和Linq到Sql开始新项目。
对于表格中的代理键,哪种数据类型更好:identity
或uniqueidentifier
?
据我所知,identity
是在插入时自动生成的,而uniqueidentifier
应该在代码(GUID)中生成。
是否存在显着的性能差异?
例如插入后必须读取identity
值,因此插入后会有额外的数据库跳闸。
修改
我在另一个问题中找到了非常详细的答案:Tables with no primary keys。阅读所选答案。
编辑2:
关于代理键的答案:我比自然键更喜欢代理键。该决定已经完成,因此请不要建议重新考虑数据库设计。此外,请不要讨论自然和代理键的利弊。
答案 0 :(得分:4)
我同意这里的评论,你应该独立于数据访问方法设计你的数据库结构。无论是LINQ2SQL还是ADO.NET或NHibernate,无论您的PK是自动增量身份还是GUID,您都将获得相同的一系列好处/问题。
我实际上只能考虑使用GUID来支持INT作为PK的一个目的 - 在一个高度分布的应用程序中,其中有几个数据库需要与主服务器同步数据等。即便如此,您也可以使用不同增量的IDENTITY ,例如一个数据库服务器的IDENTITY(1,2),下一个的IDENTITY(2,2)等[当然只适用于固定数量的数据库服务器。]
GUID的主要“问题”是它占用更多空间(16个字节与4/8相比),不仅作为PK,还作为该表中任何索引的一部分,因为每个索引都隐式存储PK值。比较16个字节也会变慢(多少?你应该测量它,它取决于)
此外,由于GUID是随机的,因此在向表中插入行(尽管我相信SQL Server 2005或2008中有一个新函数可以生成连续的GUID)时,可以获得大量的页面拆分。在具有大量插入物的环境中,这一点非常昂贵。
答案 1 :(得分:1)
任何一个都没问题。这取决于你的设计。当你需要在客户端创建ID时,UNIQUEIDENTIFIER会工作,当你在建立一个你需要在发送到数据库之前在客户端上添加/删除/修改的对象列表时,这有时会很好。如果必须合并在不同系统上创建的数据,也会更好。
INT较小,因此它们可能会更快,而且当您使用数据进行调试时,它们更容易使用,因为它们更容易讨论。
简而言之,这里没有“最佳”答案。这是一个设计决定。
答案 2 :(得分:1)
我认为根据您使用LINQ-to-SQL的事实选择表的主键并不是一个好主意。在我看来,将主键用于其预期目的会更好 - 通过唯一标识特定行来确保数据完整性。整数或GUID PK不会保护您免受表中重复行的影响(当然,除了自动生成的列之外)。然后,关于自动生成密钥的专业人员和骗局的争论很激烈:)
答案 3 :(得分:0)
我根据预期的表大小使用identity和int或bigint。我希望LINQ执行一个结合插入和密钥读取的单个查询。
答案 4 :(得分:0)
uniqueidentifier
,也可以自动插入 NEWID()
。
答案 5 :(得分:0)
好的,我刚写了blog about this。我在下面重新发布以获取其他人的利益。
基本要点似乎是在ado.net博客上发表的评论,其中说明实体框架是获得Visual Studio 2010和Dot Net 4主要开发人员时间的唯一方法。
我们知道这个
我的回答是 - DUH。我们都知道这一点。微软在PDC 2007上公开表示,LINQ to SQL是SQL Server的短期版本,因为SQL Server没有其他LINQ故事。它仅适用于SQL Server。你不能编写一个LINQ to SQL提供程序 - 它没有模型。这是一种一次性技术,不可扩展。
实体框架=提供商
实体框架是Microsoft建立LINQ提供商的唯一途径。实体框架已经证明是非常具有相应性,但我认为部分原因在于LINQ to SQL今天拥有更好的程序员体验。实体框架将捕获并超越LINQ to SQL,因为它是Microsoft未来的ORM / Mapping工具。
我认为微软对我们,IBM,甲骨文等第三方供应商的实体框架进行了巨额投资。如果他们希望第三方开发人员和数据库支持LINQ,他们必须有一个可以写入的模型。实体框架就是答案。
我在去年看到了这个问题,当时他们用VS 2008而不是EF将LINQ转换为SQL。他们永远不应该发布一个有太多重叠的东西的封闭实现。我知道他们想要一个关系数据库故事,但我认为他们说错了。现在有很多严重混淆的开发人员要求我们提供LINQ to SQL提供程序。没有一个,因为你不能写一个。