如何将二维矩阵数据存储到MySQL表?求SQL语句与实现方案
二维矩阵数据存储到MySQL的方案分析
一、你的初始方案可行性分析
你想把矩阵的每一行(Liner、Rod等)作为表的列,这个思路仅适合存储单组数据(比如只保留矩阵中1列的数据)。但当前你的矩阵包含1、2、3三组数据(对应测试批次、设备编号这类维度),用你写的建表语句会无法区分这三组数据;而且后续如果新增4、5这类维度,必须修改表结构添加新列,扩展性极差,不符合数据库设计的最佳实践。
另外你写的建表语句注释是英文,这里给你翻译成中文的版本(仅作注释修正,结构问题仍存在):
-- 如何在数据库端存储这样的二维数组? -- 1 -- 2 -- 3 -- 4 -- 二维数组中的所有列: CREATE TABLE DAILY_MUD_REPORT ( liner INT, rod INT, stk DECIMAL(25, 4), eff INT, stroke INT, disp DECIMAL(25, 4));
二、推荐的两种存储方案
方案1:宽表适配多维度(兼容你的初始思路)
如果坚持用宽表形式,可新增一个维度列(比如batch对应矩阵的1、2、3),这样能同时存储多组数据:
建表语句
CREATE TABLE DAILY_MUD_REPORT ( batch INT COMMENT '批次/编号,对应矩阵的1、2、3', liner INT COMMENT 'Liner参数值', rod INT COMMENT 'Rod参数值', stk DECIMAL(5,2) COMMENT 'Stk参数值(无需25位精度,5位足够覆盖现有数据)', eff INT COMMENT 'Eff参数值', stroke INT COMMENT 'Stroke参数值', disp DECIMAL(6,4) COMMENT 'Disp参数值', PRIMARY KEY (batch) -- 批次作为主键,确保每组数据唯一 );
插入数据SQL
-- 插入批次1的数据 INSERT INTO DAILY_MUD_REPORT (batch, liner, rod, stk, eff, stroke, disp) VALUES (1, 6, 0, 8.5, 95, 0, 0.0706); -- 插入批次2的数据 INSERT INTO DAILY_MUD_REPORT (batch, liner, rod, stk, eff, stroke, disp) VALUES (2, 6, 0, 9.5, 98, 0, 0.0709); -- 插入批次3的数据 INSERT INTO DAILY_MUD_REPORT (batch, liner, rod, stk, eff, stroke, disp) VALUES (3, 6, 0, 12, 97, 59, 0.0997);
检索数据示例
-- 查询所有批次的Stk和Disp数据 SELECT batch, stk, disp FROM DAILY_MUD_REPORT; -- 查询批次3的所有参数 SELECT * FROM DAILY_MUD_REPORT WHERE batch = 3;
方案2:窄表(符合数据库第三范式,扩展性强)
如果后续可能新增更多参数(比如新增Temp、Press等行)或更多维度(比如4、5、6等),推荐用窄表结构,将参数名称作为列存储,灵活性更高:
建表语句
CREATE TABLE DAILY_MUD_PARAMS ( batch INT COMMENT '批次/编号,对应矩阵的1、2、3', param_name VARCHAR(20) COMMENT '参数名称:Liner、Rod、Stk等', param_value DECIMAL(10,4) COMMENT '参数值,统一用DECIMAL兼容整数和小数', PRIMARY KEY (batch, param_name) -- 批次+参数名作为复合主键,避免重复数据 );
插入数据SQL
-- 插入批次1的所有参数 INSERT INTO DAILY_MUD_PARAMS (batch, param_name, param_value) VALUES (1, 'Liner', 6), (1, 'Rod', 0), (1, 'Stk', 8.5), (1, 'Eff', 95), (1, 'Stroke', 0), (1, 'Disp', 0.0706); -- 插入批次2的所有参数 INSERT INTO DAILY_MUD_PARAMS (batch, param_name, param_value) VALUES (2, 'Liner', 6), (2, 'Rod', 0), (2, 'Stk', 9.5), (2, 'Eff', 98), (2, 'Stroke', 0), (2, 'Disp', 0.0709); -- 插入批次3的所有参数 INSERT INTO DAILY_MUD_PARAMS (batch, param_name, param_value) VALUES (3, 'Liner', 6), (3, 'Rod', 0), (3, 'Stk', 12), (3, 'Eff', 97), (3, 'Stroke', 59), (3, 'Disp', 0.0997);
检索数据示例
-- 查询所有批次的Liner参数 SELECT batch, param_value AS liner_value FROM DAILY_MUD_PARAMS WHERE param_name = 'Liner'; -- 查询批次3的所有参数,转成宽表格式展示 SELECT MAX(CASE WHEN param_name = 'Liner' THEN param_value END) AS liner, MAX(CASE WHEN param_name = 'Rod' THEN param_value END) AS rod, MAX(CASE WHEN param_name = 'Stk' THEN param_value END) AS stk, MAX(CASE WHEN param_name = 'Eff' THEN param_value END) AS eff, MAX(CASE WHEN param_name = 'Stroke' THEN param_value END) AS stroke, MAX(CASE WHEN param_name = 'Disp' THEN param_value END) AS disp FROM DAILY_MUD_PARAMS WHERE batch = 3;
三、总结
- 如果你的数据维度(1、2、3)和参数(Liner、Rod等)固定不会新增,方案1的宽表更直观,查询方便;
- 如果后续可能新增维度或参数,方案2的窄表扩展性更强,无需修改表结构。
内容的提问来源于stack exchange,提问作者YoYoYo
相关产品推荐
相关产品推荐

