2014-10-29 22 views
0

我想有一个只是(自动)枚举行序列的列。 所以我有这个表:如何创建删除行后不跳过数字的自动递增列?

Nr Name 
1 Test 
2 Test2 
3 Abc 
4 Def 

在我第一次删除的最后一排,然后加入一个新的。问题是,表格然后看起来像这样:

Nr Name 
1 Test 
2 Test2 
3 Abc 
5 Ghi 

如何使它恢复4?

+0

[停止做出关于'IDENTITY'假设](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/12/bad-habits-to-kick-expecting-identity-to- mean-something.aspx),不要担心差距 - 他们真的不是**问题! – 2014-10-29 19:02:37

回答

4

正式的答案是,你补种值。 Here是做什么的一个描述。

真正的答案,但是,是不是担心它。身份值是而不是保证是连续的,有多种原因会出现间隙。即使没有删除。你应该习惯自动递增身份的差距。

如果你需要无间隙的连续值,也有解决方案。一个是计算输出值:

row_number() over (partition by id) 

工作得很好。

另一种是写一个触发强制所有您想要的规则。不过,你知道,编写数据库引擎的人知道每个人都希望身份无差距。但是,他们可能不希望保证这一点,所以他们在功能和性能方面有合理的妥协。如果您试图无差距地执行顺序性,则会影响性能,特别是对于大容量插入和删除。

1

你不能(通过自动递增值)。自动递增值呢,它的名字是在告诉你:它每次插入后(即使它是更新情况下,每个INSERT ... ON DUPLICATE KEY UPDATE语句后)自动递增。

可以手动设置下一自动增加值,是的 - 但这样做只会导致问题,因为那么MySQL将与ID 5进行,重复使用ID后4 - >已经在那里 - >错误。

如果你真的需要id没有间隙,你可以生成他们,但你应该保留代理id以及内部参考。 (只有和自然键是可靠准确地处理数据)

但创建可靠重用ID的系统是很难 - 特别是当它应该与多个客户实际使用的数据在运行时发生。您需要花费大量时间来同步每个表的ID使用情况!


ID是什么用户要进入触摸。用户不应该有任何不同的体验,一个元素的ID是否为3 3487563673.如果只是在一个枚举继续显示数字,您应该使用一个程序语言基础变量,或mysqls row_number()功能得到显示信息

1

简短的回答:不这样做

至少,不要用钥匙做到这一点 - 键应该是稳定的。

存在性能问题(通过外键关系以原子方式级联更新的键值 - 此处包含其他答案)以及逻辑问题(例如,存储在数据库系统之外的数据)。例如,使用上面的数据,删除'Def'(这是id 4)的行,然后将'Ghi'的行重新编号为id 4(它是id 5)。当顾客'Ghi'打电话并引用5的密钥时会发生什么,因为这是他们为其客户ID记录的内容?客户'Def'访问时会发生什么情况,携带打印的发票显示4键?

例如,您的银行每次向其他银行转账时,是否会为您提供新的银行帐号?在查询时

行号如果你想有一个“行数”的概念,然后用row_number()(SQL Server 2005中添加的)在查询时生成一个。

SELECT row_number(), <other columns> 
FROM schema.table 
ORDER BY <ordering criteria> ; 
-- or 
SELECT row_number() OVER (ORDER BY <ordering criteria>), <other columns> 
FROM schema.table ;