Sql server 如何在没有主键的情况下唯一标识表中的行
我正在从一个没有主键集的旧数据库/表导入超过600.000.000行,该表位于sql server 2005数据库中。我创建了一个工具,将这些数据导入到一个结构完全不同的新数据库中。问题是,我想从进程因任何原因停止的位置恢复进程,如错误或网络错误。由于该表没有主键,因此无法检查该行是否已导入。是否有人知道如何识别每一行,以便我检查它是否已导入?此表有重复的行,我已经尝试计算所有列的哈希,但由于重复的行,它无法工作Sql server 如何在没有主键的情况下唯一标识表中的行,sql-server,Sql Server,我正在从一个没有主键集的旧数据库/表导入超过600.000.000行,该表位于sql server 2005数据库中。我创建了一个工具,将这些数据导入到一个结构完全不同的新数据库中。问题是,我想从进程因任何原因停止的位置恢复进程,如错误或网络错误。由于该表没有主键,因此无法检查该行是否已导入。是否有人知道如何识别每一行,以便我检查它是否已导入?此表有重复的行,我已经尝试计算所有列的哈希,但由于重复的行,它无法工作 谢谢 如果这些行来自另一个数据库,我会将它们放入一个暂存表中——一个上面设置了标识
谢谢 如果这些行来自另一个数据库,我会将它们放入一个暂存表中——一个上面设置了标识的数据库。然后,您可以识别除id之外所有其他数据都相同的行,并在尝试将其放入生产表之前删除重复的行。对于重复的行,即使是
row_number()
也不会有任何帮助,因为这可能会在查询之间发生变化(由于MSSQL存储数据的方式)。您需要将其带到具有标识列的登录表中,或者将具有标识的新列添加到现有表中(alter table oldTbl add column NewId int identity(1,1)
)
您可以使用row\u number()
,然后如果最后的n
行的数量超过新数据库中的计数,则可以将其放回,但只使用登录表更直接。选项1:可以删除重复项
尝试找到一个有点独特的字段组合。(允许重复)并通过存储在目标表中的其余字段的散列进行联接
假设一张表:
create table t_x(id int, name varchar(50), description varchar(100))
create table t_y(id int, name varchar(50), description varchar(100), hash varbinary(8000))
select * from t_x x
where not exists(select *
from t_y y
where x.id = y.id
and hashbytes('sha1', x.name + '~' + x.description) = y.hash)
尝试连接尽可能多的字段的原因是为了减少散列冲突的机会,而散列冲突在具有600.000.000条记录的数据集上是真实的
选项2:重复项很重要
如果您真的需要重复的行,您应该在大表中添加一个唯一的id列。要以有效的方式实现这一点,您应执行以下步骤:
- 更改表并添加一个uniqueidentifier或int字段
- 使用newsequentialid()函数或行号()更新表
- 在此字段上创建索引
- 将id字段添加到目标表中李>
- 一旦所有数据都被移动过来,该字段就可以被删除
另一个笨拙的选择是首先将正在加载的数据分解成可管理大小的块(可能是10000000行)。逐块加载它们,跟踪已加载的块。使用暂存表,这样您就可以知道并控制块何时被“完全处理”。如果/当被中断时,您只需丢弃中断时正在处理的数据块,然后继续使用该数据块。为什么不在目标表上创建一个唯一索引,然后在所有导入完成后将其删除?有关该结构的一些附加信息会很有帮助。在不了解更多信息的情况下,我会将文件的一部分导入到目标服务器的工作表中,并从中进行处理,这样您就可以根据需要添加键和标志,并使用SQL server中的可用资源来处理任何处理错误。@fge还有其他服务写入此表,如果我创建了唯一索引,他们会停止工作,不是吗?而且这张桌子大约有400GB大小,我认为这不是一件很酷的事情