2012-10-04 26 views
6

注意:如果這是重複的但我找不到解決方案的道歉。mySQL - 使用自動增量ID將行從一個數據庫複製到另一個數據庫

我有兩個具有完全相同模式的數據庫(一個dev和一個live)。

爲了使事情更容易解釋,假設我有'客戶'表和'報價'表。兩個表都有自動增量標識符,而且引用表有一個'customerid'列作爲客戶表的外鍵。

我的問題是,我有我的開發數據庫中的一些行,我想要複製到實時數據庫。當我複製客戶行時,我可以輕鬆獲得新的ID,但我如何才能將新ID分配給「子」報價錶行?

我知道我可以手動編寫INSERTS腳本來解決問題,但有沒有更簡單的方法來做到這一點?

編輯: 這是一個簡單的例子,我有大約15桌所有這些使用自動增量鍵和外鍵形成一個層次。有相當的實時數據庫的詳細數據,以便在新的ID會更大(如dev.customer.id = 4,live.customer.id = 54)

回答

3

我終於成功地做到這一點(按照我的意見),但爲了做到這一點,我不得不寫一些代碼。最後,我創建了一些虛擬表格,以便跟蹤舊ID與新ID的關係。當用FK約束複製記錄時,我只是根據舊的查找新的ID。有點囉嗦,但它的工作。

這篇文章現在有點過時了,所以我將其標記爲答案。如果任何人有更好的想法/解決方案,我會高興地'取消'它作爲接受的答案。

編輯:這裏要求的是一些僞代碼,我希望解釋我是如何做到的。

我有兩個相關的表如下:

CREATE TABLE tblCustomers (
    Id int NOT NULL AUTO_INCREMENT, 
    Name varchar(50) DEFAULT NULL, 
    Address varchar(255) DEFAULT NULL, 
    PRIMARY KEY (Id) 
) 
ENGINE = MYISAM 
ROW_FORMAT = fixed; 

CREATE TABLE tblQuotes (
    Id int NOT NULL AUTO_INCREMENT, 
    CustomerId int(11) DEFAULT NULL, 
    QuoteReference varchar(50) DEFAULT NULL, 
    PRIMARY KEY (Id) 
) 
ENGINE = MYISAM 
ROW_FORMAT = fixed; 

我創造,我會用它來追蹤老IDS對新的ID

CREATE TABLE tblLookupId (
    Id int NOT NULL AUTO_INCREMENT, 
    TableName varchar(50) DEFAULT NULL, 
    OldId int DEFAULT NULL, 
    NewId int DEFAULT NULL, 
    PRIMARY KEY (Id) 
) 
ENGINE = MYISAM 
ROW_FORMAT = fixed; 

的想法是,我複製了額外的表tblCustomer一次一排地跟蹤ID,像這樣:

// copy each customer row from dev to live and track each old and new id 
// 
foreach (customer in tblCustomers) 
{ 
    // track the old id 
    var oldid = customer.id; // e.g. 1 

    // insert the new record into the target database 
    INSERT newdb.tblCustomers (...) VALUES (...); 

    // get the new id 
    var newid = SELECT LAST_INSERT_ID() // e.g. 245 

    // insert the old id and the new id in the id lookup table 
    INSERT idlookup (TableName, OldId, NewId) VALUES ('tblCustomers', oldid, newid); // this maps 1->245 for tblCustomers 
} 

當我來複制t能夠(tblQuote)與外鍵我必須先查找基於舊的新ID。

// copy each quote row from dev to live and lookup the foreign key (customer) from the lookup table 
// 
foreach(quote in tblQuotes) 
{ 
    // get the old foreign key value 
    var oldcustomerid = quote.CustomerId; // e.g 1 

    // lookup the new value 
    var newcustomerid = SELECT newid FROM tblIdLookup WHERE TableName='tblCustomers' AND oldid=oldcustomerid; // returns 245 

    // insert the quote record 
    INSERT tblQuotes (CustomerId, ...) VALUES (newcustomerid, ...); 
} 

我試圖保持這個簡短點和點(和語言不可知),所以可以看到技術。在我的真實場景中,我有大約15個'級聯'表,所以我必須跟蹤每個表的新ID,而不僅僅是tblCustomer

+0

你能更具體地說明你做了什麼來解決這個問題嗎?我知道這已經有一段時間了 - 但這是一個很好的問題,一個完整的答案會很棒。 – kittykittybangbang

+0

@kittykittybangbang我已經添加了一些僞代碼,我希望能解釋這種技術。我現在做了很多次,這不是很快,不漂亮,但它的作用像一個魅力。 –

+0

非常感謝! :d – kittykittybangbang

0

使用INSERT ... SELECT

insert into your_table (c1, c2, ...) 
select c1, c2, ... 
from your_table 

其中c1,c2,...,是除id以外的所有列。在不改變任何IDS

INSERT INTO to_database.to_table SELECT * FROM from_database WHERE some_id = 123; 

沒有必要,如果沒有需要重新映射到任何指定的列

+0

這將適用於第一個表格(客戶),但第二個(引用)如何? –

+0

可能是引用中的嵌套查詢,獲取客戶的正確ID – Anshu

+0

謝謝,聽起來我們正朝着正確的方向前進。你有可能提供一個例子嗎? –

10

最簡單的方法。

希望幫助...

+1

這對單個表格來說很好,但是我有一個FK約束表的層次結構。正如我所說,我知道它可以手動編寫腳本。 –

+1

值得一提的是,我已經通過創建沒有自動增量的臨時表來克服這個問題,而是使用GUID,然後映射表以提供每個表中每個記錄的「舊」ID的查找。 –

+1

有幫助是的,但需要更正:當我們運行這個查詢時,我們需要在from_database('from_database')上,但在查詢本身中,它應該說'from_table',它表示'from_database'。 –

相關問題