gpt4 book ai didi

java - 在 mysql 模式下使用 h2 INSERT IGNORE 引发主键违规

转载 作者:行者123 更新时间:2023-11-29 15:50:38 25 4
gpt4 key购买 nike

我正在将 Scopus 数据抓取到 h2 文件数据库中。数据中有超过 46,000,000 条记录,每条记录都被视为不同的,这意味着数百 GB 的数据是重复的(因此是关系数据库)。为了减少所有这些数据的插入时间,我首先创建一组没有约束的临时表,然后使用 SELECT DISTINCT 和 GROUP BY 将数据复制到实际表中以强制唯一性。

唯一的异常(exception)是文档表和引用文档表。由于数据的格式,我可以保证每条记录代表一个唯一的文档,因此我可以插入文档表,然后仅连接引用文档表中具有文档表中尚未包含的 ID 的行。

相关代码如下:

CREATE TABLE document (docid varchar NOT NULL, title varchar, abstract varchar, docType varchar NULL, ref boolean);

CREATE TABLE refdoc (refid varchar NOT NULL, title varchar);

INSERT INTO document (docid, title, abstract, docType, ref)
VALUES ('2-s2.0-0000098715', 'title', 'abstract', 'ab', 'false');

INSERT INTO refdoc (refid, title)
VALUES ('2-s2.0-0000098715', 'title'),
VALUES ('2-s2.0-33947184743', 'title');

ALTER TABLE document
ADD PRIMARY KEY (docid);

ALTER TABLE document
ADD FOREIGN KEY (docType) REFERENCES doctype(abbrev);

INSERT IGNORE INTO document (docid, title, ref)
SELECT refid, title, 'true' FROM refdoc;

  • 创建文档表
  • 创建引用文档表
  • 在文档表中插入一条记录
  • 将两条记录插入 refdoc 表,包括重复的记录
  • 使用主键更改文档表
  • 使用外键更改文档表
  • 插入 refdoc 中与文档不冲突的行

INSERT IGNORE 查询抛出:org.h2.jdbc.JdbcSQLException:唯一索引或主键冲突:“CONSTRAINT_INDEX_6 ON PUBLIC.DOCUMENT(DOCID)

我还尝试使用 WHERE NOT EXISTS:

INSERT INTO document (docid, title, ref)
SELECT refid, title, 'true'
FROM refdoc
WHERE NOT EXISTS (
SELECT refid FROM refdoc
INNER JOIN document
ON document.docid = refdoc.refid );

但是尝试连接未索引的表实际上是不可能的 - 我尝试过的涉及连接的尝试都不起作用。

作为最后的手段,我可​​以使用 FileHashMap 并转储 refdoc 表的内容,然后构建一个巨大的PreparedStatement,例如:

INSERT INTO document (docid, title, ref)
SELECT ?, ?, 'true'
WHERE NOT EXISTS (
SELECT docid FROM document
WHERE docid = ? );

但我显然不想这样做,因为这会花费很长时间。

最佳答案

终于找到了一个不涉及构建100,000,000条记录的批处理语句的解决方案。问题是我需要强制我插入到文档中的 refdocs 尚未在文档表中,并且我只插入 refdoc 表中的唯一行。在此之前我的所有解决方案要么未能避免冲突,要么未能强制执行唯一性,要么涉及没有索引的表上的联接。

这是解决方案 SQL:

CREATE TABLE document (docid varchar NOT NULL, title varchar, abstract varchar, docType varchar NULL);

CREATE TABLE refdoc (refid varchar NOT NULL, title varchar);

INSERT INTO document (docid, title, abstract, docType)
VALUES ('2-s2.0-0000098715', 'title', 'abstract', 'ab');

INSERT INTO refdoc (refid, title)
VALUES ('2-s2.0-0000098715', 'title'),
VALUES ('2-s2.0-33947184743', 'title');

INSERT IGNORE INTO document (docid, title)
SELECT refid, MAX(title)
FROM refdoc
WHERE refid NOT IN (
SELECT docid FROM document )
GROUP BY refid;

ALTER TABLE document
ADD PRIMARY KEY (docid);

ALTER TABLE document
ADD FOREIGN KEY (docType) REFERENCES doctype(abbrev);

现在的逻辑是:

  • 创建文档表
  • 创建引用文档表
  • 在文档表中插入一条记录
  • 将两条记录插入 refdoc 表,包括重复的记录
  • 插入 refdoc 中不与文档冲突且唯一的行
  • 使用主键更改文档表
  • 使用外键更改文档表

这样做的额外好处是,在插入完成之前不会对文档表建立索引。

我仍然不完全清楚为什么我在没有主键的表上遇到主键约束违规,但这听起来像是要提交到 h2 github 作为错误报告。

关于java - 在 mysql 模式下使用 h2 INSERT IGNORE 引发主键违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56778305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com