gpt4 book ai didi

java - 无法将大数据集加载到 h2 数据库中

转载 作者:行者123 更新时间:2023-12-01 05:50:17 25 4
gpt4 key购买 nike

问题是:在我的公司,我们有一个大型数据库,我们希望在其中执行一些自动化操作。为了测试这一点,我们获取了大约 6 个 10MB 大小的 csv 文件的数据小样本。我们想用H2来测试我们程序在里面的结果。 H2 似乎与我们之前的简历配合得很好,尽管它们最多有 1000 个条目长。当涉及到任何 10MB 文件时,命令

insert into myschema.mytable (select * from csvread('mycsvfile.csv'));

报告失败,因为其中一个注册表可能是重复的并且违反了我们的主键约束。

Unique index or primary key violation: "PRIMARY_KEY_6 ON MYSCHEMA.MYTABLE(DATETIME, LARGENUMBER, KIND)"; SQL statement:
insert into myschema.mytable (select * from csvread('src/test/resources/h2/data/mycsvfile.csv')) [23001-148] 23001/23001

将 mycsvfile.csv 分成更小的部分,我发现在插入大约 10000 行后问题开始出现(尽管数字因我使用的数据而异)。然而,如果我将文件分成几部分然后单独运行命令,我可以插入超过 10000 行。但即使我设法手动插入所有数据,我也需要一种自动化方法来填充数据库。

由于运行命令不会给我导致问题的行,我猜测问题可能是 csvread 例程中的某些缓存。

然后我创建了一个小型java程序,可以手动将数据插入H2数据库中。无论我是否批处理命令、关闭并打开 1000 行的连接,h2 都报告我正在尝试复制数据库中的条目。

org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_6 ON MYSCHEMA.MYTABLE(DATETIME, LARGENUMBER, KIND)"; SQL statement:
INSERT INTO myschema.mytable VALUES ( '1997-10-06 01:00:00.0',25485116,1.600,0,18 ) [23001-148]

使用 emacs 对该注册表进行正常搜索,我可以发现注册表没有重复,因为日期时间列在整个数据集中是唯一的。

我无法提供该数据供您测试,因为该公司出售该信息。但这是我的表定义的样子。

create table myschema.mytable (
datetime timestamp,
largenumber numeric(8,0) references myschema.largenumber(largecode),
value numeric(8,3) not null,
flag numeric(1,0) references myschema.flag(flagcode),
kind smallint references myschema.kind(kindcode),
primary key (datetime, largenumber, kind)
);

这就是我们的 csv 的样子:

datetime,largenumber,value,flag,kind
1997-06-11 16:45:00.0,25485116,0.710,0,18
1997-06-11 17:00:00.0,25485116,0.000,0,18
1997-06-11 17:15:00.0,25485116,0.000,0,18
1997-06-11 17:30:00.0,25485116,0.000,0,18

以及将填充我们的测试数据库的java代码(请原谅我丑陋的代码,我绝望了:)

private static void insertFile(MyFile file) throws SQLException {
int updateCount = 0;
ResultSet rs = Csv.getInstance().read(file.toString(), null, null);
ResultSetMetaData meta = rs.getMetaData();
Connection conn = DriverManager.getConnection(
"jdbc:h2:tcp://localhost/mytestdatabase", "sa", "pass");
rs.next();
while (rs.next()) {
Statement stmt = conn.createStatement();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < meta.getColumnCount(); i++) {
if (i == 0)
sb.append("'" + rs.getString(i + 1) + "'");
else
sb.append(rs.getString(i + 1));
sb.append(',');
}
updateCount++;
if (sb.length() > 0)
sb.deleteCharAt(sb.length() - 1);

stmt.execute(String.format(
"INSERT INTO myschema.mydatabase VALUES ( %s ) ",
sb.toString()));
if (updateCount == 1000) {
conn.close();
conn = DriverManager.getConnection(
"jdbc:h2:tcp://localhost/mytestdatabase", "sa", "pass");
updateCount = 0;
}
}
if (!conn.isClosed()) {
conn.close();
}
rs.close();
}

如果需要,我很乐意提供更多信息。

编辑

@Randy 我总是在运行命令之前检查数据库是否干净,并且在我的 java 程序中,我有一个例程从无法插入的文件中删除所有数据。

 select * from myschema.mytable where largenumber  = 25485116;
DATETIME LARGENUMBER VALUE FLAG KIND
(no rows, 8 ms)

最佳答案

我唯一能想到的是表上有一个触发器将时间戳设置为“现在”。虽然这不能解释为什么您在几行上成功,但它可以解释为什么主键被违反。

关于java - 无法将大数据集加载到 h2 数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4890633/

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