我在我们的 java 项目中遇到了 HSQLDB 的奇怪行为。非常简单的查询返回不一致的结果。我将问题追溯到某些表的索引不是最新的。不幸的是,我既不是 SQL 专家,也不是处理 java 数据库的专家。
HSQLDB 版本是 2.2.8。我试图更新到 2.2.9 但这没有帮助。
我们的数据库非常简单。它包含几个独立的表。他们之间没有任何关系。每个表都配备了索引,其中一个是结合了几列的唯一索引。这是一个例子:
CREATE CACHED TABLE PUBLIC.MYTABLE(
A BIGINT DEFAULT -9999 NOT NULL,
B BIGINT DEFAULT -9999 NOT NULL,
C NUMERIC(12,7) DEFAULT -9999.0000000 NOT NULL,
D INTEGER DEFAULT -9999 NOT NULL);
CREATE INDEX IDX1 ON PUBLIC.MYTABLE( A );
CREATE INDEX IDX2 ON PUBLIC.MYTABLE( B );
CREATE INDEX IDX3 ON PUBLIC.MYTABLE( C );
CREATE UNIQUE INDEX MYTABLE_PRIMARY_KEY ON PUBLIC.MYTABLE( A, B );
我们通常从 java 程序中插入行和查询表,从不更新现有行。插入操作看起来像这样:
Connection con = ...; // get connection from
PreparedStatement stmt;
con.setAutoCommit( false );
stmt = this.con.prepareStatement(
String.format(
"insert into %s values (?,?,?,?)", "MYTABLE"));
stmt.setLong(1, data1);
stmt.setLong(2, data2);
stmt.setDouble(3, data3);
stmt.setInt(4, data4);
stmt.addBatch()
在其他地方我们执行批处理
stmt.executeBatch();
stmt.clearBatch();
con.commit();
代码循环执行,之后我们关闭语句并使用适当的方法连接。此外,连接 url 末尾有“shutdown=true”,所以我们希望数据库能够正确关闭。
正如我前面提到的,我在 SQL 查询时注意到了这个问题,例如
SELECT COUNT(*) FROM MYTABLE
开始返回不合理的结果,例如它只返回了预期行数的大约一半。作为一项实验,我从表中删除了唯一索引,并且所有查询都正常工作。这就是为什么我认为由于某种原因索引在插入时没有正确更新。查看索引的线索来自谷歌搜索和阅读留言板和论坛上的评论。
如在我使用的 HSQLDB 中禁用并重建索引中所述
SHUTDOWN COMPACT
并且修复了我们数据库中的所有表,所有数据都在那里,所有查询都返回正确的结果。我怀疑该问题的作者遇到了与我类似的问题。
好的,我的数据是安全的,所以我想了解并纠正问题的根源。
索引是否应该在插入时更新?或者这是一个错误的假设,我们每次更新数据库时都需要执行 SHUTDOWN COMPACT?
多列的唯一索引是否可能是问题的根源?
我将不胜感激任何建议或指示。