2

在 MSSQL Server 2005 上有一个 2 列的小表,其中包含大量信息,比如说大约 10 亿条记录,并且不断被写入。

表的定义是:

Create table Test(
id int identity(1,1) primary key ,
name varchar(30) )

Te PK 是 int,出于多种原因,我选择它而不是 uniqueidentifier。问题来自自动增量,我想在每次删除一行时重新组织“id”。这样做的目的是不留空隙。该表处于活动状态,并且向其中写入了很多行,因此删除一列不是一个选项,也会长时间锁定该表。

我想要完成的快速示例:

我有这个 :

id  | name
----+-------
 1  | Roy 
 2  | Boss 
 5  | Jane 
 7  | Janet

我想重新组织它,使它看起来像这样:

id  | name
----+-------
 1  | Roy
 2  | Boss
 3  | Jane
 4  | Janet

我知道 DBCC CHECKIDENT (TableName, RESEED, position) 但我不确定它是否会对我的情况有利,因为我的表很大,如果我没记错的话,重新定位也需要很长时间,它会锁定表很长一段时间。该表不被任何其他表使用。但是,如果您愿意,您可以针对相同的问题提交建议,同时记住该表已被其他表使用。

编辑 1:

目的是证明在删除行的情况下各行相互跟随,以便我可以看到它已被删除并恢复它。我正在考虑添加第三列,该列将包含上面行的哈希值,如果上面的行被删除了我会知道我有一个差距并且需要恢复它,在这种情况下顺序无关紧要,因为我可以比较has代码并查看它们是否匹配,所以我可以看到哪一行跟随哪一行。但仍然我想知道有没有更聪明、更安全的方法呢?也许涉及其他东西而不是哈希码,其他证明行相互跟随的方法,或者新行包含前一行的部分?

编辑 2:

如果我不能很好,我会尝试再解释一次,然后我不想浪费任何人的时间。

在完美的情况下,该表不会丢失任何内容,但由于服务器错误,某些数据可能会被删除,或者我的一些同事可能会浪费并因错误而将其删除。
我有日志并且可以恢复该数据,但我想证明这些记录是有序的,即使出现服务器错误并且它们中的一些被删除但后来又恢复了,它们也会相互跟随。有没有办法做到这一点 ?

示例:假设 7 被删除,然后恢复为 23 ,您将如何证明 23 是 7 ,这意味着 23 出现在 6 之后和 8 之前?

4

3 回答 3

5

我建议不要担心尝试重新设置Identity列的种子——让 SQL Server 为每一行维护它的唯一性。

通常,这需要用于表示逻辑,在这种情况下,您可以使用ROW_NUMBER()分析函数:

SELECT Row_Number() Over (Order By Id) NewId,
  Id, Name
FROM YourTable
于 2013-06-03T13:42:09.970 回答
0

这样做的方法是不实施您建议的修复。

留下身份。
如果标识 7 被删除,您知道它就在 6 之后和 8 之前。

如果您需要它们保持相同的顺序,那么简单。
对名称放置唯一约束。
不要删除记录。
只需为活动添加一个布尔列。

于 2013-06-04T13:18:00.953 回答
0

我同意其他人的观点,通常不应该这样做,但如果你绝对想这样做,你可以利用古怪的更新来快速完成它,应该是这样的:

DECLARE @prev_id INT = 0
UPDATE Test
SELECT id = CASE WHEN id - @prev_id = 1 THEN id
              ELSE @prev_id + 1
         END
   ,@prev_id = id
FROM test

您应该阅读有关 quirky update 的限制,主要是确保输出一致所必须满足的条件。这是一篇好文章,但他们烦人地让你登录,但你可以找到其他资源: http ://www.sqlservercentral.com/articles/T-SQL/68467/

编辑:实际上,在这种情况下,我认为您可以使用:

DECLARE @prev_id INT = 0
UPDATE Test
SELECT id = @prev_id + 1
          ,@prev_id = id
FROM Test 
于 2013-06-03T13:53:13.183 回答