注意:如果这是重复的道歉,但我找不到解决方案。
我有两个数据库(一个dev和一个live),它们具有完全相同的模式。
为了便于解释,假设我有一个“客户”表和一个“引用”表。两个表都有自动增量ID,而引用表有一个'customerid'列,用作customer表的外键。
我的问题是我的dev数据库中有一些行要复制到实时数据库。当我复制客户行时,我可以很容易地获得一个新的ID,但是如何将新的id分配给“子”引用表行?
我知道我可以手动编写INSERTS脚本来克服这个问题但有更简单的方法吗?
编辑: 这是一个简化的例子,我有大约15个表,所有表都使用自动增量和外键形成层次结构。实时数据库中有相当多的数据,因此新的ID会更大(例如dev.customer.id = 4,live.customer.id = 54)
答案 0 :(得分:17)
最简单的方法,无需更改任何ID。
确保您当前位于要复制的记录所在的表中(源数据库)。
运行以下命令:
INSERT INTO to_database.to_table
SELECT * FROM from_table WHERE some_id = 123;
如果不需要重新映射任何内容,则无需指定列。
希望有所帮助!
答案 1 :(得分: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;
我创建了一个额外的表格,我将使用它来跟踪旧ID以及新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
}
当我使用外键复制表(tblQuote)时,我必须首先根据旧的ID查找新的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
答案 2 :(得分:0)
使用INSERT
... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
其中 c1,c2,... 是除id
以外的所有列。