Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在没有主键的情况下唯一标识表中的行_Sql Server - Fatal编程技术网

Sql server 如何在没有主键的情况下唯一标识表中的行

Sql server 如何在没有主键的情况下唯一标识表中的行,sql-server,Sql Server,我正在从一个没有主键集的旧数据库/表导入超过600.000.000行,该表位于sql server 2005数据库中。我创建了一个工具,将这些数据导入到一个结构完全不同的新数据库中。问题是,我想从进程因任何原因停止的位置恢复进程,如错误或网络错误。由于该表没有主键,因此无法检查该行是否已导入。是否有人知道如何识别每一行,以便我检查它是否已导入?此表有重复的行,我已经尝试计算所有列的哈希,但由于重复的行,它无法工作 谢谢 如果这些行来自另一个数据库,我会将它们放入一个暂存表中——一个上面设置了标识

我正在从一个没有主键集的旧数据库/表导入超过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大小,我认为这不是一件很酷的事情