我有一个表格,PK的增长相当快,但由于行被相当一致地删除,因此很快就会变成一个非常稀疏的表格:
ID VALUE
----------------
1 'Test'
5 'Test 2'
24 'Test 3'
67 'Test 4'
有没有办法可以自动在缺少的ID中插入下一个值,这样我就不会将ID增长到极大?例如,我想插入ID为2的“测试5”。
答案 0 :(得分:2)
我并不是在建议你做什么,但如果你想这样做,就是这样。我只回答这个问题,而不是解决问题。
在你的过程中,你要做什么来锁定你的桌子,这样你就不会偷偷摸摸。通过使用链接这个:
EXEC @result = sp_getapplock @Resource = @LockResource,
@LockMode = 'Exclusive'
和
EXEC sp_releaseapplock @Resource = @LockResource
表格强>
DECLARE @table TABLE ( id INT, val VARCHAR(20) )
数据强>
INSERT INTO @table
(
id,
val
)
SELECT 1,
'Test'
UNION ALL
SELECT 2,
'Test'
UNION ALL
SELECT 5,
'Test 2'
UNION ALL
SELECT 24,
'Test 3'
UNION ALL
SELECT 67,
'Test 4'
<强>查询强>
INSERT INTO @table
SELECT TOP 1
id + 1,
'TEST'
FROM @table t1
WHERE NOT EXISTS ( SELECT TOP 1
1
FROM @table
WHERE id = t1.id + 1 )
ORDER BY id
INSERT INTO @table
SELECT TOP 1
id + 1,
'TEST'
FROM @table t1
WHERE NOT EXISTS ( SELECT TOP 1
1
FROM @table
WHERE id = t1.id + 1 )
ORDER BY id
SELECT *
FROM @table
<强> RESULT 强>
id val
1 Test
2 Test
5 Test 2
24 Test 3
67 Test 4
3 TEST
4 TEST
答案 1 :(得分:2)
我不会这样做。
正如评论中其他人已经解释过的那样,通过重新填补数字中的空白,你什么也得不到。
另外,如果您在任何地方 引用这些ID,您甚至可能会无意中弄乱您的数据:
假设曾经有ID 2
行,你删除了它
然后插入一个完整的新行并重新使用ID 2
现在,如果您在引用ID 2
的任何地方有任何数据,它会突然链接到新值而不是旧值。
(对于挑剔者的注意事项:是的,如果正确设置了参照完整性,就不会发生这种情况。但到处都不是这种情况,所以谁知道......)
答案 2 :(得分:1)
我删除了关于身份的答案,因为他们没有参与。看看你是否使用它作为聚集索引键会很有趣,因为填补空白会违反严格增加值的经验法则。
通过自联接来填充间隙相对简单,并且由于您有一个主键,因此该查询应该快速运行以找到第一个间隙(当然,您如何处理同时插入和锁定?):
SELECT lhs.ID + 1 AS firstgap
FROM tablename AS lhs
LEFT JOIN tablename AS rhs
ON rhs.ID = lhs.ID + 1
WHERE rhs.ID IS NULL
插入批量记录需要单独完成每个插入,而IDENTITY可以为您处理...
答案 3 :(得分:-2)
如前所述:不要担心未使用的ID。
但是,当发生大量删除时,优化表是一种好习惯。
在MySQL中,你可以这样做:
optimize table tablename