mysql - 如何在不将这些列作为主键或唯一列的情况下对 2 个值的组合执行类似插入忽略的操作?
问题描述
我有一张像
create table dados(
id INT AUTO_INCREMENT,
id2 VARCHAR(18) NOT NULL,
id3 VARCHAR(18) NOT NULL,
...
PRIMARY KEY (id));
我需要允许具有相同组合(id2,id3)的行,但我想将数据本地 infile 加载到此表中,从而跳过这些组合的匹配项。
我试过将文件加载到临时表中
create temporary table temp_tbl like dados;
从那里我尝试了这些(这里的语法不一定正确):
insert into dados select * from temp_tbl where not exists
( select 1 from dados where dados.id2=temp_tbl.id2 and dados.id3=temp_tbl.id3);
和
insert into dados select * from temp_table left join dados
on dados.id2=temp_table.id2 and dados.id3=temp_table.id3
where dados.id2 is null and dados.id3 is null;
但是这两个查询都需要永远,因为表有几百万个条目。
作为这些的替代方案,我考虑创建另一个列,该列的值要么为 id3,要么在重复组合 (id2,id3) 的情况下,将其设置为 id3_'此处的其他增量数字',所以我会有
create table dados(
id INT AUTO_INCREMENT,
id2 VARCHAR(18) NOT NULL,
id3 VARCHAR(18) NOT NULL,
...
other_identification varchar(25) NOT NULL,
PRIMARY KEY (id,other_identification));
但我想避免这种解决方案,因为它会在已经非常大的表中创建一个可能不必要的列。我想做的另一件事是让主键为 (id,id2,id3) 并且在插入时可能有一个 IGNORE 或一个 ON DUPLICATE KEY,但只使用 id2 和 id3 作为键,但是我找不到类似的东西这。
任何帮助将不胜感激。
解决方案
无论您尝试哪种方法,如果没有索引,它都会很慢(id2, id3)
。
我会做以下事情:
在原表中定义索引:
alter table dados add index (id2, id3);
创建具有唯一索引的临时表(id2, id3)
。它实际上可以是主键:
create temporary table temp_tbl(
id2 VARCHAR(18) NOT NULL,
id3 VARCHAR(18) NOT NULL,
...
PRIMARY KEY (id2, id3)
使用LOAD DATA INFILE
with IGNORE
, 忽略 CSV 文件中的重复项:
LOAD DATA INFILE '/path/to/file.csv'
IGNORE INTO TABLE temp_tbl
...
使用 DELETE .. JOIN 查询删除现有的 (id2, id3) 组合:
delete t
from temp_tbl t
join dados d on d.id2 = t.id2 and d.id3 = t.id3;
将临时表中的数据插入到原始表中:
insert into dados (id2, id3, ...)
select id2, id3, ...
from temp_tbl;
推荐阅读
- javascript - 计算值为 A 的复选框总数
- apache-spark - 用涉及复杂数据类型的嵌套模式替换火花数据框中的空值
- typescript - 类型的最佳方法 - Typescript 前端 TCL 后端
- apache-spark - 如何合并火花数据框中的两行以在输出中获取空值
- http - 如何使用 cURL 将文件从远程服务器下载到远程服务器?
- python - pyspark 删除重复列
- r - 绘制来自多列的值组合(带有 R 的 ggplot2)
- ios - AppStore 元数据拒绝指南 2.3
- c++ - 没有 malloc 的链表实现失败
- amazon-web-services - 无法访问 ECS 集群中的 EC2 实例