在他对哪个更好的回答中:标识列还是生成的唯一 id 值?mrdenny 说:
当 SQL Denali 出现时,它将支持比身份更高效的序列,但您无法自己创建更高效的东西。
我不确定。知道 Oracle 的序列后,我要么为插入创建触发器,将每个插入封装到存储过程的调用中,要么祈祷我在执行临时插入时不要忘记正确使用序列。
我怀疑序列的优势是否如此明显。
我们正在开发一个 Web 应用程序,用户尚无法访问。我的老板注意到新创建的记录的 ID 超过 10 000,即使表中只有不到 100 条记录。她假设 Web 界面出于某种原因创建了比实际记录多 100 倍的临时记录(并删除了它们),这可能导致我们在发布后的几个月内超出范围。
我不认为她关于 ID 膨胀的原因是正确的(可以回答这个问题的同事正在休假,所以我们不确定),但让我们假设她是。她说她讨厌使用 bigint 列,她希望我们停止自动递增 ID 列并编写服务器端代码,选择第一个“未使用”的整数并将其用作 ID。
我是一名计算机科学研究生,几乎没有实践经验,担任初级开发人员的角色。她在管理我们组织的所有数据库和设计其中大部分数据库方面拥有多年经验。我认为在这种情况下她是不正确的,bigint ID 没有什么可害怕的,并且模仿 DBMS 功能的反模式气味。但我还不相信我的判断。
支持和反对每个立场的论据是什么?如果我们使用 bigint 会发生什么坏事,重新发明轮子自动递增功能有什么危险?有没有比任何一种都更好的第三种解决方案?她想要避免身份证面值膨胀的原因是什么?我也有兴趣了解实际原因 - 也许 bigint ID 理论上可行,但在实践中会引起头痛?
该应用程序预计不会处理大量数据。我怀疑它会在未来几年内达到 10 000 条实际记录。
如果它有任何区别,我们正在使用 Microsoft SQL 服务器。该应用程序是用 C# 编写的,并使用 Linq to SQL。
更新
谢谢,我发现现有的答案和评论很有趣。但恐怕你误解了我的问题,所以它们包含了我想知道的。
我并不真正关心高 ID 的真正原因。如果我们自己找不到它,我可以问一个不同的问题。我感兴趣的是了解这种情况下的决策过程。为此,请假设应用程序将每天写入 1000 条记录,然后删除其中的 9999 条。我几乎可以肯定事实并非如此,但这就是我的老板提出要求时所相信的。那么,在这些假设情况下,使用 bigint 或编写我们自己的代码来分配 ID(以重用已删除记录的 ID 的方式,以确保没有间隙)的优缺点是什么?
至于实际原因,我强烈怀疑这是因为我们曾经写过代码从另一个数据库中导入数据,作为概念证明,以后可以在一定程度上进行迁移。我认为我的同事在导入过程中实际上创建了数千条记录,后来又删除了它们。我必须确认是否确实如此,但如果是,则甚至不需要采取行动。
我提出关于迪纳利序列的问题,在这里和关于Oracle全球表标识列的仿真另外一个问题在这里。
我一直认为我可以相信身份值会不断增加。另一方面,我知道使用序列我永远无法确定它们中没有一些空白。
是时候适应序列中的差距,还是留在临时表中的标识列会更好?
sql-server sequence identity sql-server-2012 temporary-tables
我有一个使用以下 T-SQL 创建的表:
CREATE TABLE [dbo].[TableName](
[id] [int] IDENTITY(1,1) NOT NULL
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我今天查看了这张表,注意到 id 列正在跳过值:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26、27、1027、1028、1029、1030、1031、1032、1033、1034、1035、2034、2035、3034
我不担心这个或任何事情(我的应用程序不关心主键是什么),我只是想知道可能导致这种情况发生的原因。似乎确实有一种模式,每次“跳跃”发生时跳跃 1000。
我的应用程序使用实体框架插入这些行,如果这有什么不同的话。
sql-server entity-framework auto-increment identity sql-server-2012