复制关系表数据
Posted
技术标签:
【中文标题】复制关系表数据【英文标题】:Copying Relational Table Data 【发布时间】:2011-03-16 00:36:27 【问题描述】:我希望我在这个问题上不会太啰嗦,我只是想确保我所问的内容完全清楚(我认为这很令人困惑:)。
我有一个包含一堆表的数据库,其中设置了我所有的外键约束。关系有时是几个表的深度,也有一个子表与多个父表相关的情况。我想插入我的“***”表行之一的副本,以及与之相关的所有子表数据(保持关系完整性)。也就是说我的新顶层行获得了自己的新主键(通过auto_increment),所有新的子行都获得了自己的主键(再次通过auto_increment),表的所有外键信息都与我复制的数据(现在才使用新创建的主键)。所以现在我将拥有一份与原始数据独立可变的关系数据的副本。
为了使我的示例更加具体,我煞费苦心地设置了一个类似但更简单的示例。让我们定义以下表格:
alt text http://www.freeimagehosting.net/uploads/ef22070a89.png
所有绿色的 id 字段都是 auto_update 主键,而黄色的是带有外键约束的索引列。假设数据库最初包含以下数据:
job_types
+----+----------+
| id | jobcode |
+----+----------+
| 1 | DEADBEEF |
| 3 | FEEDFACE |
+----+----------+
managers
+----+---------------+-------------+
| id | name | job_type_id |
+----+---------------+-------------+
| 1 | John | 1 |
| 3 | Michael Scott | 3 |
+----+---------------+-------------+
departments
+----+------+------------+
| id | name | manager_id |
+----+------+------------+
| 1 | H32 | 1 |
| 2 | X11 | 3 |
+----+------+------------+
employees
+----+-------------+---------------+------------+-------------+
| id | name | department_id | manager_id | job_type_id |
+----+-------------+---------------+------------+-------------+
| 1 | Billy Bob | 1 | 1 | 1 |
| 2 | Sandra Lee | 1 | 1 | 3 |
| 3 | Buddy Holly | 2 | 3 | 1 |
+----+-------------+---------------+------------+-------------+
现在说我想做的是制作部门 H32 (id=1) 的关系副本。
我应该得到如下结果(显然主键的实际值并不重要,参照完整性才是)。
job_types
+----+----------+
| id | jobcode |
+----+----------+
| 1 | DEADBEEF |
| 3 | FEEDFACE |
| 4 | DEADBEEF |
| 5 | FEEDFACE |
+----+----------+
managers
+----+---------------+-------------+
| id | name | job_type_id |
+----+---------------+-------------+
| 1 | John | 1 |
| 3 | Michael Scott | 3 |
| 4 | John | 4 |
+----+---------------+-------------+
departments
+----+------+------------+
| id | name | manager_id |
+----+------+------------+
| 1 | H32 | 1 |
| 2 | X11 | 3 |
| 3 | H32 | 4 |
+----+------+------------+
employees
+----+-------------+---------------+------------+-------------+
| id | name | department_id | manager_id | job_type_id |
+----+-------------+---------------+------------+-------------+
| 1 | Billy Bob | 1 | 1 | 1 |
| 2 | Sandra Lee | 1 | 1 | 3 |
| 3 | Buddy Holly | 2 | 3 | 1 |
| 4 | Billy Bob | 3 | 4 | 4 |
| 5 | Sandra Lee | 3 | 4 | 5 |
+----+-------------+---------------+------------+-------------+
实现此类复制操作的最有效执行方式是什么?值得我在 Grails 的上下文中使用 InnoDB 表引擎使用 mysql。我期待听到一些关于您如何以“正确方式”执行此类操作的好主意。
-- 问候,维克
我已经在 PasteBin 上发布了 a MySQLDump of the example 初始化。
编辑 对于它的价值,我发布了一个更简单/更广泛的问题here,我得到了普遍积极的回应,这表明我不是“只是做错了”......
【问题讨论】:
如果我可以问,您复制整个表格图表的动机是什么?你的问题是让数据异常警报在我脑海中响起。 @proflux,假设您有一个具有关系模型的系统。如果部门是关系结构的根,我想创建一个新部门,它绝对是部门的一个单独实例,但在我的示例中具有与部门 H32 相同的初始结构,在我看来,深层副本是方法来做到这一点。它仍然正常化,但我现在可以在不影响原件的情况下随意更改副本......为什么这对你来说似乎很奇怪?如果我的想法是错误的,我应该如何以不同的方式思考它? @Mark,我认为一组表要么被规范化,要么没有被规范化......在结构存在后你不能做一些事情来“非规范化”数据库...... @vic - 我不知道 grails 在执行克隆/深拷贝方面为您提供的任何灵丹妙药。您基本上被困在自己用 Groovy 或 SQL 编写深拷贝逻辑;根据您的应用,一个可能比另一个更好。 @prolux,你说得对,我的例子很糟糕;您的wiki示例更适合我的要求。我的问题的核心是,鉴于您需要对数据库进行深度复制,您如何有效地执行此操作以获得最佳性能?我人为的例子只是在可理解的上下文中回答的素材。我的真实案例太复杂了,无法描述,仅此而已...... 【参考方案1】:我使用INSERT INTO ... SELECT 语法做了类似的事情。 (C api 也有一个 MYSQL_OPTION_MULTI_STATEMENTS_ON ,您可以使用它来运行多个语句。或者您可以使用一个过程)。
这是最有效的,因为您不必在客户端和服务器之间移动数据。复制的值是创建新实体的模板。我不明白你为什么用这个特殊的数据模型来做这个。
【讨论】:
以上是关于复制关系表数据的主要内容,如果未能解决你的问题,请参考以下文章