【问题标题】:Are primay keys stored in sorted order or do they just appear sorted by SQL statement?主键是按排序顺序存储的,还是只是按 SQL 语句排序?
【发布时间】:2014-10-03 19:06:36
【问题描述】:

如果主键总是排序的,如何以随机顺序存储 Guid 作为主键。

【问题讨论】:

标签: sql sql-server guid


【解决方案1】:

不,表数据并不总是按主键顺序存储,但通常主键有聚集索引,数据总是按聚集索引顺序存储。

如果你不希望数据按照主键的顺序存储,你应该为它使用非聚集索引。

请注意,尽管您通常按存储顺序获取数据,但除非您使用order by 子句,否则无法保证该顺序。如果顺序很重要,您应该始终指定它应该是什么。

【讨论】:

  • 好吧.. 非聚集索引有什么缺点吗?谢谢你的回答。
  • @AKshayRaut:只有在索引中彼此相邻的记录不会在表中彼此相邻存储,因此获取一系列记录可能会慢一些。但是,为 guid 设置聚集索引会导致大量碎片,这会降低所有查询的性能,而不仅仅是一些特殊情况。
【解决方案2】:

嗯,主键不一定按排序顺序存储在磁盘上。但是聚集索引是。在绝大多数情况下,主键是聚集索引。虽然这并不一定保证结果的排序,只是结果通常默认按聚集索引排序。

如何以随机顺序存储 Guid 作为主键

正是由于这个原因,GUID 不能构成良好的聚集索引。 SQL Server 确实有一个叫做Sequential GUID 的东西来解决这个问题。生成的 GUID 不会是连续的,但它们将是连续的。不过,它有一些警告:

创建的 GUID 大于自 Windows 启动后指定计算机上此函数先前生成的任何 GUID

如果系统重新启动,则序列丢失。如果多个系统创建密钥,则序列丢失。此外,还有一个问题是我们仍然依赖 SQL Server 来生成密钥,这与使用 GUID 的一个重要理由不符。

一般来说,我建议不要将 GUID 用作聚集索引。作为替代方案,可以使用普通的IDENTITY 键作为聚集索引并创建一个单独的 GUID 列(可能有自己的索引,甚至是唯一约束,以确保应用程序不会尝试重新插入现有记录)。这个单独的列在业务逻辑意义上成为一种“全局标识符”,而不是在数据持久性实现意义上。

【讨论】:

  • 聚集索引并不意味着数据在磁盘上的顺序是必然的。 my answer here goes into more detail
  • @MartinSmith:我误解了文档吗? msdn.microsoft.com/en-us/library/ms190457.aspx"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."
  • 文档在这一点上极具误导性。它可能应该被纠正。
  • 好的,谢谢。此外,如果我使用 IDENTITY 列,我会让用户可以预测我的数据,例如我的 asp.net 网站上的用户 ID 包含指向他们的个人资料照片和其他一些详细信息的链接,这些链接以 txt 和 jpg 文件的形式存储在服务器文件夹中,一旦我使用 IDENTITY,这些文件将按顺序排列,因此对客户。由于 GUID 可能会对性能产生影响,我想我必须找到其他 IDing 方法。
  • @AKshayRaut:为什么可预测性不好?用户可能能够猜出正在使用的标识符,但这无关紧要。如果这是系统中的安全漏洞,那么我怀疑还有一个更重要的安全问题需要修复,与标识符无关。不要通过默默无闻来依赖安全性。
【解决方案3】:

没有主键并不总是按排序顺序存储。

聚簇索引也不总是按排序顺序存储,这与流行的误解相反。

如果您选择一个随机 GUID 作为聚集主键,那么您很可能很快就会得到一个高度碎片化的聚集索引,当页面变满并需要拆分时,物理和逻辑顺序会大相径庭。

通常,大多数聚集索引扫描按照页指针而不是分配(页码)顺序以逻辑(索引键)顺序发生。为了考虑分配有序扫描,您必须在未提交读隔离级别运行或必须持有表锁。

如果没有 order by,则无法保证结果的顺序。

【讨论】:

    猜你喜欢
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多