You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL中从一张表生成两张互相关联的新表?

在MySQL中从单表拆分出两张关联新表的实现方案

针对从现有plan表创建关联的plana和planb表的需求,以下是分步实现方案:

1. 先创建目标表结构

首先按照需求创建plana和planb表,其中plana存储计划基础信息,planb存储计划对应的功能项,通过plana_id建立一对多关联:

-- 创建plana表
CREATE TABLE `plana` (
    id INT AUTO_INCREMENT PRIMARY KEY,
    plan_id INT NOT NULL,
    `name` VARCHAR (25) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 创建planb表
CREATE TABLE `planb` (
    id INT AUTO_INCREMENT PRIMARY KEY,
    plana_id INT NOT NULL,
    feature_id INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2. 同步基础数据到plana表

从原plan表提取计划的plan_id和name字段,插入到plana中:

INSERT INTO plana (plan_id, `name`)
SELECT plan_id, `name` FROM `plan`;

注:plana的created_at字段会自动使用默认的当前时间戳,无需手动指定。

3. 拆分功能字段并插入planb表

原表的features是逗号分隔的字符串,需要拆分为单个功能项后,关联plana的主键插入到planb,这里提供两种适配不同MySQL版本的方法:

方法一:递归CTE(MySQL 8.0及以上版本适用)

利用递归CTE逐步拆分逗号分隔的字符串,再关联plana插入数据:

WITH RECURSIVE split_features AS (
    SELECT 
        p.id AS original_plan_id,
        p.name AS plan_name,
        SUBSTRING_INDEX(p.features, ',', 1) AS feature_id,
        SUBSTRING(p.features, LOCATE(',', p.features) + 1) AS remaining_features
    FROM `plan` p
    WHERE p.features IS NOT NULL AND p.features != ''
    
    UNION ALL
    
    SELECT 
        original_plan_id,
        plan_name,
        SUBSTRING_INDEX(remaining_features, ',', 1) AS feature_id,
        SUBSTRING(remaining_features, LOCATE(',', remaining_features) + 1) AS remaining_features
    FROM split_features
    WHERE remaining_features IS NOT NULL AND remaining_features != ''
)
INSERT INTO planb (plana_id, feature_id)
SELECT 
    pl.id AS plana_id,
    sf.feature_id
FROM split_features sf
JOIN plana pl ON sf.plan_name = pl.`name` AND sf.original_plan_id = pl.plan_id;

方法二:数字辅助表(兼容MySQL 5.x版本)

如果你的MySQL版本不支持递归CTE,可以先创建一个数字辅助表,再拆分插入:

-- 创建数字辅助表(这里创建1-10的数字,可根据features的最大条目数调整)
CREATE TABLE numbers (n INT PRIMARY KEY);
INSERT INTO numbers VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

-- 拆分并插入数据
INSERT INTO planb (plana_id, feature_id)
SELECT 
    pl.id AS plana_id,
    SUBSTRING_INDEX(SUBSTRING_INDEX(p.features, ',', n.n), ',', -1) AS feature_id
FROM `plan` p
JOIN numbers n ON n.n <= LENGTH(p.features) - LENGTH(REPLACE(p.features, ',', '')) + 1
JOIN plana pl ON p.`name` = pl.`name` AND p.plan_id = pl.plan_id
WHERE p.features IS NOT NULL AND p.features != '';

4. 添加外键约束(可选但推荐)

为了保证两张表的数据一致性,建议给planb的plana_id添加外键约束,关联plana的主键:

ALTER TABLE planb
ADD CONSTRAINT fk_planb_plana FOREIGN KEY (plana_id) REFERENCES plana(id)
ON DELETE CASCADE ON UPDATE CASCADE;

注:ON DELETE CASCADE表示删除plana中的记录时,planb中对应的关联记录会自动删除;ON UPDATE CASCADE表示更新plana的主键时,planb的plana_id会同步更新。

内容的提问来源于stack exchange,提问作者S Hussain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 09:10:34