2011-12-15 77 views
4

我正在从没有主键集的旧数据库/表中导入多于600.000.000行,此表位于sql server 2005数据库中。我创建了一个工具将这些数据导入到一个结构非常不同的新数据库中。问题是我想从任何原因(例如错误或网络错误)停止的地方恢复过程。由于此表没有主键,因此无法检查该行是否已导入。有谁知道如何识别每一行,以便我可以检查它是否已经导入或不?此表有重复的行,我已经尝试计算所有列的散列,但由于重复的行而不工作...如何唯一标识表中没有主键的行

谢谢!

+2

为什么不在目标表上创建唯一索引,然后在所有导入完成后将其删除? – fge 2011-12-15 19:07:44

+0

关于结构的一些额外信息将会有所帮助。如果不知道更多,我会将文件的一部分导入到目标服务器的工作表中,然后从那里处理它,这样您可以根据需要添加键和标志,并使用SQL Server中可用的资源来处理任何处理错误。 – Maess 2011-12-15 19:09:29

回答

4

如果这是来自另一个数据库 - 一个设置了标识的数据库,那么我会将这些行放入临时表中。然后,您可以识别除ID之外所有其他数据相同的行,并在尝试将其放入生产表之前删除重复项。

0

重复的行,即使row_number()会让你无处可去,因为它可以在查询之间切换(由于MSSQL存储数据的方式)。您需要将其带入带有标识列的登陆表,或者在现有表上添加一个带有标识的新列(alter table oldTbl add column NewId int identity(1,1))。

您可以使用row_number(),如果它们的数量超过新数据库中的计数,则返回最后的n行,但使用登陆表会更直接。

0

选项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列到你的大表。

  • 更改表,并添加唯一标识符或INT场
  • 更新与NEWSEQUENTIALID()函数或ROW_NUMBER()
  • 表:要在你应该做以下步骤执行的方式实现这一目标创建此字段的索引
  • 将id字段添加到目标表中。
  • 一旦所有的数据移动完毕,该字段就可以被删除。
1

因此:您正在加载非常多的bazillion行数据,行不能唯一标识,加载可能(并且显然会随时中断),并且希望能够尽管事实上从所有的实际目的来看,你都不能确定你离开的地方。好。

加载到包含额外标识列的表中将会工作,假设然而每当数据加载启动时,它始终始于相同的项目并以相同的顺序加载项目。效率极低,因为每次启动时都必须通读每一个字。

另一个笨拙的选择是首先将要加载到可管理大小的块(可能是10,000,000行)中的数据中断。通过块加载它们,跟踪你已经加载的块。使用临时表,以便您知道并可以控制某个块“完全处理”的时间。如果/当被中断时,你只会抛出你正在处理的大块中断,并恢复与该块的工作。