2011-12-15 83 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行)中的數據中斷。通過塊加載它們,跟蹤你已經加載的塊。使用臨時表,以便您知道並可以控制某個塊「完全處理」的時間。如果/當被中斷時,你只會拋出你正在處理的大塊中斷,並恢復與該塊的工作。

相關問題