如何从应用程序级别复制数据?不是数据库级别
Posted
技术标签:
【中文标题】如何从应用程序级别复制数据?不是数据库级别【英文标题】:How to duplicate data from application level? Not database level 【发布时间】:2021-09-11 05:48:28 【问题描述】:我被我的应用程序中的重复数据卡住了。
假设我有:
PetBooks Table:
id
book_name
Pet:
id
book_id
code
name
type
Petbooks
1 MyPet
Pet:
1 1 CAT1 Josh Cat
2 1 CAT2 Ron Cat
3 1 DOG1 Max Dog
问题 1: 如何复制 Petbook 及其所有宠物?
所以在我复制宠物书后,它应该是这样的
Petbooks
1 MyPet
2 MyPet(Copy)
Pet:
1 1 CAT1 Josh Cat
2 1 CAT2 Ron Cat
3 1 DOG1 Max Dog
4 2 CAT1 Josh Cat
5 2 CAT2 Ron Cat
6 2 DOG1 Max Dog
我认为的解决方案是,获取所有book_id = 1的宠物,然后循环并一个一个插入,但是特别是在有很多数据的情况下,速度很慢。
【问题讨论】:
从数据库中获取所有数据,然后将其插入数据库(尽管我不确定您为什么要从应用程序中执行此操作)。另外,如果有很多数据,复制和粘贴所有数据确实需要一段时间。 @DavidLee 感谢您的评论。是的,我认为是获取所有数据并一一插入,但问题是当数据增长时,获取所有数据时会溢出内存。而且一个一个插入的时候很慢。 【参考方案1】:好吧,您可以稍微痛苦地执行此操作 - 假设 id 是自动分配的,并且除 id
之外的某些列在原始数据中是唯一的。让我将该专栏称为name
。
然后:
insert into petbooks (book_name)
select concat('Copy of ', book_name)
from petbooks;
那么对于pets
,我们必须查找新的id。我们可以使用聚合动态创建查找表:
insert into pets (book_id, code, name, type)
select pb.max_id, code, name, type)
from pets p join
(select name, min(id) as min_id, max(id) as max_id
from petbooks
group by name
) pb
on pb.min_id = p.book_id
【讨论】:
谢谢回答,不知道如果id是UUID,应该由应用生成呢? @SusiS 。 . .这让它有点棘手。您可以包含createdAt
日期/时间并改用它。【参考方案2】:
您可以一个一个地手动处理关系,并将它们组合成一个过程。您可以使用LAST_INSERT_ID()
函数获取最新的id
。例如:
CREATE PROCEDURE copy_petbook(petbook_id INT)
BEGIN
INSERT INTO PetBooks (book_name)
SELECT CONCAT(book_name, '(Copy)')
FROM Petbooks
WHERE id = petbook_id;
DECLARE last_insert_id BIGINT;
SET last_insert_id = LAST_INSERT_ID();
INSERT INTO Pet (book_id, code, name, type)
SELECT lid.last_insert_id , code, name, type
FROM Pet JOIN (SELECT last_insert_id) as lid
WHERE book_id = petbook_id;
END
如果您想为id
列使用UUID,您可以将签名更改为CHAR(36)
,然后使用UUID()
函数:
CREATE PROCEDURE copy_petbook(petbook_id CHAR(36))
BEGIN
DECLARE uuid CHAR(36);
-- Generate an UUID which has not been used.
REPEAT
SET uuid = UUID();
UNTIL (SELECT COUNT(*) FROM PetBooks WHERE id = uuid) = 0 END REPEAT;
-- Insert rows with the UUID
INSERT INTO PetBooks (id, book_name)
SELECT u.uuid, CONCAT(book_name, '(Copy)')
FROM Petbooks JOIN (SELECT uuid) as u
WHERE id = petbook_id;
INSERT INTO Pet (book_id, code, name, type)
SELECT u.uuid, code, name, type
FROM Pet JOIN (SELECT uuid) as u
WHERE book_id = petbook_id;
END
如果您还对其他表中的id
列使用 UUID,则可以以相同方式生成更多 UUID。
最后,只需调用过程:
CALL copy_petbook(/* Put the id here. */);
【讨论】:
以上是关于如何从应用程序级别复制数据?不是数据库级别的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SQL Query 在 SQL Server 中的表级别进行镜像或复制
如何在 dll 级别读取 app.config。? [复制]