繁体   English   中英

将几行及其相关子行从一个表移动到另一个表的最佳方法

[英]Best way to move few rows and their related child rows from one table to another table

  • 我们提供基于 SAAS 的产品,对于数据库,我们使用 MYSQL 兼容 AWS Aurora 5.7。
  • 为了克服一个表中有大量行的问题,我们创建了多组表(g1_、g2_、g3_等)。 就像我们的应用程序有大约 350 个表,然后有 350 个带有 g1_ 前缀的表,350 个带有 g2_ 前缀的表,依此类推。
  • 每个组都有我们的多个客户的数据,例如g1_customer表有 5 个我们客户的客户。

现在,每个表中的行数都在增长,我们希望将一个特定客户端的所有数据从一组移动到另一组。

  1. 我们想到的解决方案1:我们可以保留每个表(master和child)的client id,并通过client id从每个源表中获取所有数据,并将其插入到目标组的相应表中。

问题:子表的行映射,目标组表可以有已有的行,而源组主表的行会在这里得到一个新的自增id,所以各个子表的行映射是不可能的。

  1. 我们心中的解决方案2:编写一个脚本,将获取单行并将其插入到目标表中,然后将智利表中的相关行插入到目标子表中,map 和新的自动增量id,等等。

问题:对于大型数据集(210 万行),此过程将非常缓慢

请分享您的最佳想法或实现它的任何工具。

让我们回过头来看看建议的解决方案是否是最好的。

通常,将一个表(在一组表上)拆分为一组相同的表会适得其反。 它涉及更改客户端代码以首先选择哪个表,然后继续使用所需的表。 通常,性能会受到影响而不是受益。

无论采用哪种方法,我们都无法真正为您提供帮助

SHOW CREATE TABLE
and the various queries that would be impacted by the change.

为什么您不使用 mySQL 分区表来提出您的建议,当然如果我能理解您的建议。 我一直在使用 PARTITION 表来提出很多建议,我们有一些表几乎有 1 亿份报告。

这里有一些例子。

按客户组名称创建客户分区表:

CREATE TABLE customers (
    id INT NOT NULL,
    name VARCHAR(30),
    customer_group CHAR(10),
    settings JSON, # very useful when you are working with no structured data
    created_at DATETIME
)
PARTITION BY LIST(store_id) (
    PARTITION g1 VALUES IN ('customer1'),
    PARTITION g2 VALUES IN ('customer2'),
    PARTITION g3 VALUES IN ('customer3')
);

现在您可以插入一些数据:

INSERT INTO `customers` VALUES(1, 'Customer 1', 'customer1', '{}', NOW());
INSERT INTO `customers` VALUES(2, 'Customer 2', 'customer2', '{}', NOW());
INSERT INTO `customers` VALUES(3, 'Customer 3', 'customer3', '{}', NOW());

当然,如果你没有一个有很多结果的大表,我认为这些例子可能对你没有多大帮助。 但是想象一下,您想要添加来自其他客户的数据,并且您不希望这些数据与我们的其他客户造成混乱。 因此,如果您尝试在表customers中插入“customer4”,您会被 mySql 阻止,为此您需要包含另一个分区,如下所示:

ALTER TABLE `customers` ADD PARTITION (PARTITION `customer4` VALUES IN ('customer4'));

因此,如果您现在需要从一个大表中删除一些数据并仅通过参数传递客户组,这将需要一些时间,但是,当您使用分区表时,您可以这样做。

如果要删除所有 customer4 数据:

ALTER TABLE `customers` TRUNCATE PARTITION `customer4`;

或者,如果您想删除一些 PARTITION,例如 customer1 和 3,而不影响整个客户表:

ALTER TABLE `customers` DROP PARTITION `customer1`,`customer3`;

如果您想在查询中使用客户引用使您的系统更加严格,您可以在查询中使用 PARTITION 名称:

SELECT * FROM `customers` PARTITION(`customer2`);

此查询的结果将是一条带有 customer2 数据的简单行。

这些是您可以使用 PARTITIONS 表执行的一些简单示例,我不知道您是否已经阅读过它,如果我不认为这可能是您的选择,否则我认为我不明白你的问题很好,我很抱歉。 希望有帮助!

这些更多参考

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM