我有一个应用程序,在几乎所有的表中使用GUID作为主键,我读到使用GUID作为主键时存在性能问题。老实说,我还没有看到任何问题,但我要开始一个新的应用程序,我仍然想使用GUID为主键,但我在考虑使用一个复合主键(GUID和可能另一个字段)。

我之所以使用GUID,是因为当你有不同的环境,如“生产”、“测试”和“开发”数据库时,它们很好且易于管理,而且还用于在数据库之间迁移数据。

我将使用实体框架4.3,我想在应用程序代码中分配Guid,然后将其插入数据库。(例如,我不想让SQL生成Guid)。

为了避免与此方法相关的性能损失,创建基于gui的主键的最佳实践是什么?


当前回答

使用顺序ID会让黑客或数据挖掘者更容易破坏你的网站和数据。在为网站选择PK时,请记住这一点。

其他回答

使用顺序ID会让黑客或数据挖掘者更容易破坏你的网站和数据。在为网站选择PK时,请记住这一点。

我目前正在用EF Core开发一个web应用程序,下面是我使用的模式:

我所有的类(表)都有一个int PK和FK。 然后,我有一个类型为Guid的附加列(由c#构造函数生成),列上有一个非聚集索引。

EF中所有表的连接都是通过int键管理的,而所有来自外部(控制器)的访问都是通过guid完成的。

这个解决方案允许在url上不显示int键,但保持模型整洁和快速。

好吧,如果您的数据从来没有达到数百万行,那就没问题了。如果你问我,我从来不使用GUID作为任何类型的数据库标识列,包括PK,即使你强迫我用霰弹枪在头上设计。

使用GUID作为主键是一个决定性的缩放停止器,而且是一个关键的。 我建议您检查数据库标识和序列选项。序列是独立于表的,可以为您的需求提供解决方案(MS SQL有序列)。

如果你的表最多达到几千万行,例如5000万行,你将无法在可接受的时间读/写信息,甚至标准的数据库索引维护也将变得不可能。

然后您需要使用分区,并且可扩展到5亿甚至1- 20亿行。添加分区的方式不是最简单的事情,所有读/写语句必须包括分区列(完整的应用程序更改!)

这些数字(5000万和5亿)当然是为轻选择使用。如果您需要以复杂的方式选择信息和/或有大量的插入/更新/删除,对于一个非常苛刻的系统,这些甚至可能是1-2百万和5千万。如果您还添加了完整恢复模型、高可用性和无维护窗口等现代系统常见的因素,情况就会变得非常糟糕。

注意,在这一点上,20亿是int的限制,看起来很糟糕,但int是4倍小,是一个顺序类型的数据,小的大小和顺序类型是数据库可伸缩性的首要因素。你可以使用big int,它只小了两倍,但仍然是顺序的,顺序是非常重要的,甚至比大小更重要,当涉及到数百万或数十亿行的时候。

如果GUID也是聚集的,情况就更糟了。插入一个新行实际上会随机存储在物理位置的任何位置。

即使只是一个列,不是PK或PK部分,只是索引它是麻烦的。从碎片化的角度来看。

有一个guid列是完全可以的,就像任何varchar列一样,只要你不使用它作为PK部分,通常作为连接表的键列。您的数据库必须有自己的PK元素,使用它们过滤和连接数据-过滤后也通过GUID是完全可以的。

不要在用户界面中公开Id的另一个原因是,竞争对手可以看到您的Id在一天或其他时间段内的增量,从而推断出您正在做的业务量。

如果您使用GUID作为主键并创建聚集索引,那么我建议使用默认的NEWSEQUENTIALID()值。