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

多列SQL表去重合并问题及MySQL索引1070报错求助

解决MySQL多列唯一索引限制&批量去重插入的方案

嘿,我完全懂你的困扰——列数多到爆炸的时候,不管是写NOT EXISTS的匹配条件还是创建唯一索引都要写疯,还撞上了MySQL的32列索引硬限制。下面给你几个接地气的解决思路,一步步来:

一、用哈希列绕过32列唯一索引限制

这是解决1070错误最直接的方法:把所有需要判断重复的非datetime列,拼接成字符串后计算哈希值,用这个哈希值做唯一索引——这样只需要一个索引列,直接避开32列的限制。

步骤1:给表添加哈希计算列

先给目标表新增一个存储哈希值的生成列(MySQL 5.7+支持),它会自动计算所有非datetime列的哈希:

ALTER TABLE audi_all 
ADD COLUMN hash_cols CHAR(32) AS (
  MD5(CONCAT(
    COALESCE(Vehicle, 'NULL'), -- 处理NULL值,避免拼接后整个结果变成NULL
    COALESCE(`listed Price`, 'NULL'),
    COALESCE(Anunciante, 'NULL'),
    -- 继续把所有非datetime的列都加进来,字段名有空格记得加反引号
    COALESCE(your_other_column, 'NULL'),
    COALESCE(your_last_column, 'NULL')
  ))
) STORED;

小提醒:如果有数字类型的列,最好用CAST转成字符串(比如CAST(listed Price AS CHAR)),避免不同格式的数字拼接后哈希不一致;要是对碰撞概率要求极高,可以把MD5换成SHA256,对应列类型改成CHAR(64)。

步骤2:创建唯一索引

现在只需要给哈希列创建唯一索引就行:

CREATE UNIQUE INDEX unq_audi_hash ON audi_all(hash_cols);

以后插入数据时,只要非datetime列完全相同,哈希值就会重复,唯一索引会自动拦截重复插入。

二、批量去重插入的简化写法

如果不想依赖唯一索引,直接做去重插入,也可以用哈希对比代替逐列写匹配条件:

INSERT INTO TABLE1
SELECT DISTINCT *
FROM TABLE2 A
WHERE NOT EXISTS (
  SELECT 1
  FROM TABLE1 X
  WHERE 
    MD5(CONCAT(
      COALESCE(A.Vehicle, 'NULL'),
      COALESCE(A.`listed Price`, 'NULL'),
      -- 所有非datetime列和上面保持一致
      COALESCE(A.your_last_column, 'NULL')
    )) = MD5(CONCAT(
      COALESCE(X.Vehicle, 'NULL'),
      COALESCE(X.`listed Price`, 'NULL'),
      COALESCE(X.your_last_column, 'NULL')
    ))
);

这样不用逐列写A.col = X.col,代码瞬间清爽很多。

三、合并表的终极方案:临时表去重

如果是要一次性合并两个表并去重,可以先把所有数据导入临时表,再分组去重后插入目标表:

-- 1. 创建和目标表结构一致的临时表
CREATE TEMPORARY TABLE temp_audi LIKE audi_all;

-- 2. 把两个表的数据都导进去
INSERT INTO temp_audi SELECT * FROM TABLE1;
INSERT INTO temp_audi SELECT * FROM TABLE2;

-- 3. 去重后插入目标表(如果目标表已有数据,可跳过TRUNCATE改用NOT EXISTS逻辑)
TRUNCATE TABLE audi_all; 
INSERT INTO audi_all
SELECT 
  Vehicle, `listed Price`, Anunciante, ..., MAX(datetime_column) AS datetime_column
FROM temp_audi
GROUP BY Vehicle, `listed Price`, Anunciante, ... -- 所有非datetime列

这里用MAX(datetime_column)是为了保留每组中最新的时间记录,你也可以换成MIN或者其他逻辑,完全按需调整。

为什么会出现1070错误?

MySQL的InnoDB引擎对唯一索引的键部分数量有硬限制——最多32个,这是引擎底层的限制,没法直接突破,所以用哈希列的方法就是最实用的绕道路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:54:10