令人困惑的t-sql考试答案有关序列或uniqueidentifier

时间:2016-05-05 03:54:10

标签: sql sql-server tsql sql-server-2012

我发现了一个t-sql问题及其答案。这太令人困惑了。我可以用一些帮助。

问题是:

您开发了一个数据库应用程序。您创建了四个表。每个表存储不同类别的产品。您在每个表上创建主键字段。

您需要确保满足以下要求:

  • 字段必须使用最小的空间量。
  • 字段必须是递增的一系列值。
  • 这四个表中的值必须是唯一的。

你应该怎么做?

  • 甲。创建ROWVERSION列。
  • B中。创建使用SEQUENCE数据类型的INTEGER对象。
  • ℃。使用INTEGER数据类型以及IDENTITY
  • d。使用UNIQUEIDENTIFIER数据类型以及NEWSEQUENTIALID()
  • 电子。创建TIMESTAMP列。

上述答案是D.但是,我认为更合适的答案是B.因为序列将使用比GUID更少的空间,并且它满足所有要求。

3 个答案:

答案 0 :(得分:3)

D是一个错误的答案,因为NEWSEQUENTIALID不能保证“递增的一系列值”(第二个要求)。

  

NEWSEQUENTIALID()

     

创建一个大于任何GUID的GUID   以前由此函数在指定的计算机上生成   Windows已启动。重新启动Windows后,GUID 可以启动   再次从较低的范围,但仍然是全球唯一的。

我会说B(sequence)是正确的答案。至少,如果您不手动重启/回收,则可以使用sequence来满足所有这三个要求。我认为这是满足所有三个要求的最简单方法。

答案 1 :(得分:1)

在提供的选项之间 D B是正确答案,因为它符合所有要求:

对于主键,

ROWVERSION是一个不错的选择,stated in MSDN

  

每次修改或插入具有rowversion列的行时,会在rowversion列中插入递增的数据库rowversion值。此属性使rowversion列成为键的不良候选者,尤其是主键。对该行进行的任何更新都会更改rowversion值,因此会更改键值。如果列在主键中,则旧键值不再有效,并且引用旧值的外键不再有效。

不推荐使用

TIMESTAMP,如同一页中所述:

  

不推荐使用时间戳语法。将在Microsoft SQL Server的未来版本中删除此功能。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。

IDENTITY列不保证唯一性,除非它的所有值都是自动生成的(您可以使用SET IDENTITY_INSERT手动插入值),也不保证任何值的表之间的唯一性。

实际上保证GUID对于每个系统都是唯一的,因此如果guid是所有4个表的主键,则它确保所有表的唯一性。 不满足的一个要求是存储大小 - 它的存储大小是int的四倍(16字节而不是4)。

SEQUENCE,如果不是declared as recycle, guarantee uniqueness,则存储空间最小。

  

数值序列以定义的间隔以升序或降序生成,并且可以配置为在耗尽时重新启动(循环)。

<强>然而下, 我实际上可能会一起选择一个不同的选项 - 创建一个带有单个标识列的基表,并将其与所有其他类别的1:1关系链接起来。然后对所有类别表使用一个而不是insert触发器,它将首先将记录插入基表,然后使用scope_identity()获取值并将其作为类别表的主键插入。 这将强制实现唯一性,并且可以在类别和产品之间使用单个外键引用。

答案 2 :(得分:0)

过去,这个问题已经得到了广泛的讨论:

http://blog.codinghorror.com/primary-keys-ids-versus-guids/

约束#3是SEQUENCE可能遇到问题的原因,因为每个表中存在更高的冲突风险/可能行数减少。