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

包含多值属性的XML文件导入MySQL数据库的解决方案咨询

解决方案

一、数据库表结构设计

先按照关系型数据库第三范式设计两张关联表:

-- 图书主表,存储所有单值属性
CREATE TABLE books (
    book_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    author VARCHAR(255) NOT NULL,
    title VARCHAR(255) NOT NULL,
    UNIQUE KEY uk_book_info (author, title) -- 避免重复导入相同图书
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 图书分类关联表,存储多值分类属性
CREATE TABLE book_categories (
    book_id INT UNSIGNED NOT NULL,
    category VARCHAR(100) NOT NULL,
    PRIMARY KEY (book_id, category), -- 联合主键避免重复分类
    FOREIGN KEY (book_id) REFERENCES books(book_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、纯MySQL自动化导入方案(无需额外工具)

不需要修改原始XML,全程可脚本化执行,适配大文件场景:

1. 创建临时中间表存储原始XML节点

CREATE TEMPORARY TABLE temp_book_raw (
    raw_xml TEXT -- 存储完整的<Book>节点原始内容
) ENGINE=InnoDB;

2. 导入原始XML到临时表

LOAD XML LOCAL INFILE 'file.xml'
INTO TABLE temp_book_raw
ROWS IDENTIFIED BY '<Book>'
(@raw_node)
SET raw_xml = @raw_node;

3. 批量导入单值属性到图书主表

INSERT IGNORE INTO books (author, title)
SELECT 
    TRIM(ExtractValue(raw_xml, '//Author/text()')),
    TRIM(ExtractValue(raw_xml, '//Title/text()'))
FROM temp_book_raw;

4. 拆分多值分类插入关联表

用递归CTE拆分多值分类,支持任意数量的Category标签:

WITH RECURSIVE category_split AS (
    SELECT
        b.book_id,
        TRIM(ExtractValue(t.raw_xml, '//Category/text()')) AS all_category,
        1 AS pos,
        TRIM(SUBSTRING_INDEX(TRIM(ExtractValue(t.raw_xml, '//Category/text()')), ' ', 1)) AS category,
        TRIM(SUBSTRING(TRIM(ExtractValue(t.raw_xml, '//Category/text()')), LENGTH(SUBSTRING_INDEX(TRIM(ExtractValue(t.raw_xml, '//Category/text()')), ' ', 1)) + 2)) AS remaining
    FROM temp_book_raw t
    JOIN books b ON TRIM(ExtractValue(t.raw_xml, '//Author/text()')) = b.author 
        AND TRIM(ExtractValue(t.raw_xml, '//Title/text()')) = b.title
    WHERE TRIM(ExtractValue(t.raw_xml, '//Category/text()')) != ''
    UNION ALL
    SELECT
        book_id,
        all_category,
        pos + 1,
        TRIM(SUBSTRING_INDEX(remaining, ' ', 1)),
        TRIM(SUBSTRING(remaining, LENGTH(SUBSTRING_INDEX(remaining, ' ', 1)) + 2))
    FROM category_split
    WHERE remaining != ''
)
INSERT IGNORE INTO book_categories (book_id, category)
SELECT book_id, category FROM category_split;

三、大文件优化建议

  • 导入前执行SET FOREIGN_KEY_CHECKS=0; SET autocommit=0;关闭外键检查和自动提交,导入完成后执行COMMIT; SET FOREIGN_KEY_CHECKS=1;恢复配置,可提升导入速度数倍
  • 调整MySQL参数max_allowed_packet到1G以上,避免大XML节点导入时报截断错误
  • 若分类名称本身包含空格,可先对原始XML做简单正则替换,用|等特殊字符分隔多值分类,再对应修改拆分逻辑即可

内容的提问来源于stack exchange,提问作者Brandon Nielsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:24:04