【发布时间】:2014-10-03 19:06:36
【问题描述】:
如果主键总是排序的,如何以随机顺序存储 Guid 作为主键。
【问题讨论】:
-
这里有一篇很棒的文章讨论这个问题:blog.sqlauthority.com/2013/02/10/…
标签: sql sql-server guid
如果主键总是排序的,如何以随机顺序存储 Guid 作为主键。
【问题讨论】:
标签: sql sql-server guid
不,表数据并不总是按主键顺序存储,但通常主键有聚集索引,数据总是按聚集索引顺序存储。
如果你不希望数据按照主键的顺序存储,你应该为它使用非聚集索引。
请注意,尽管您通常按存储顺序获取数据,但除非您使用order by 子句,否则无法保证该顺序。如果顺序很重要,您应该始终指定它应该是什么。
【讨论】:
嗯,主键不一定按排序顺序存储在磁盘上。但是聚集索引是。在绝大多数情况下,主键是聚集索引。虽然这并不一定保证结果的排序,只是结果通常默认按聚集索引排序。
如何以随机顺序存储 Guid 作为主键
正是由于这个原因,GUID 不能构成良好的聚集索引。 SQL Server 确实有一个叫做Sequential GUID 的东西来解决这个问题。生成的 GUID 不会是连续的,但它们将是连续的。不过,它有一些警告:
创建的 GUID 大于自 Windows 启动后指定计算机上此函数先前生成的任何 GUID。
如果系统重新启动,则序列丢失。如果多个系统创建密钥,则序列丢失。此外,还有一个问题是我们仍然依赖 SQL Server 来生成密钥,这与使用 GUID 的一个重要理由不符。
一般来说,我建议不要将 GUID 用作聚集索引。作为替代方案,可以使用普通的IDENTITY 键作为聚集索引并创建一个单独的 GUID 列(可能有自己的索引,甚至是唯一约束,以确保应用程序不会尝试重新插入现有记录)。这个单独的列在业务逻辑意义上成为一种“全局标识符”,而不是在数据持久性实现意义上。
【讨论】:
"Clustered indexes sort and store the data rows in the table or view based on their key values. These are the columns included in the index definition. There can be only one clustered index per table, because the data rows themselves can be sorted in only one order."
没有主键并不总是按排序顺序存储。
聚簇索引也不总是按排序顺序存储,这与流行的误解相反。
如果您选择一个随机 GUID 作为聚集主键,那么您很可能很快就会得到一个高度碎片化的聚集索引,当页面变满并需要拆分时,物理和逻辑顺序会大相径庭。
通常,大多数聚集索引扫描按照页指针而不是分配(页码)顺序以逻辑(索引键)顺序发生。为了考虑分配有序扫描,您必须在未提交读隔离级别运行或必须持有表锁。
如果没有 order by,则无法保证结果的顺序。
【讨论】: