我在Ubuntu 13.04上使用mysql 5.5来存储URI之间的相似性度量[-1,1]。 我的表格布局非常简单:
|--------------------------------------------------|
| uri1 | uri2 | value |
|--------------------------------------------------|
|http://foo.com/bar | http://bar.net/foo | 0.8 |
|http://foo.com/bar1 | http://bar.net/foo2 | 0.4 |
|--------------------------------------------------|
我想确保对于两个特定的uris,存储的值不超过一个。因此,我使用followin sql来创建表:
CREATE TABLE IF NOT EXISTS db.table(
uri1 VARCHAR(255) NOT NULL ,
uri2 VARCHAR(255) NOT NULL ,
value DOUBLE NULL ,
PRIMARY KEY (uri1, uri2),
INDEX (value) )
不幸的是,当我批量插入数据(通过Java JDBC)时,我得到如下的异常:
java.sql.BatchUpdateException: Duplicate entry
'http://xmlns.com/foaf/0.1/Document-http://purl.org/linked-data/c'
for key 'PRIMARY'
似乎主键不足以存储两个URI,因此当前缀相同时(通常在我的数据中),我会得到重复的条目异常。 我已经检查过,没有插入“真正的”重复项。 有没有办法设置主键的长度,以便它始终包含两个URI?或者通常有更好的方法来建模数据吗?
我不想在每次插入数据时检查是否已经存在提供了uri1和uri2的行,而是在实际发生这种情况时处理异常(不应该这样)。因此,我认为,仅使用递增整数作为主键是不可行的。
在我的应用程序中,我将为不同的度量创建这样的几个表,并且稍后可能希望通过uri1和uri2加入它们,这样我得到的结果包含来自不同表的特定一对uris的所有值
我发现了别的东西: 我用Java设置连接:
conn = DriverManager.getConnection(
"jdbc:mysql://localhost/db?useServerPrepStmts=false&rewriteBatchedStatements=true",
"user","pass");
当我不使用“rewriteBatchedStatements = true”时,它似乎工作正常。不幸的是,我真的不得不使用它,因为如果不这样做,批量插入会慢几个数量级。
这是额外请求的代码:
//Initialized in Constructor
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db?useServerPrepStmts=false&rewriteBatchedStatements=true",
"user","pass");
PreparedStatement pst = conn.prepareStatement(String.format("INSERT INTO %s.%s values (?, ?, ?)", dbName, tableName));
//
public void queue(ResDescriptor row, ResDescriptor column, double simil) {
if(!operational()) return;
try {
String uri1 = row.getType();
String uri2 = column.getType();
pst.setString(1, uri1);
pst.setString(2, uri2);
pst.setDouble(3, simil);
pst.addBatch();
if(++batchCount%maxBatch == 0){
pst.executeBatch();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
getType()总是返回一个URI-String,并且确保从不使用相同的参数调用queue()方法两次。
非常感谢您的任何建议!
答案 0 :(得分:0)
我很抱歉回答我自己的问题,但经过几个小时的质疑,我终于找到了问题。它与钥匙的长度无关,这很好。 Exception消息似乎在某些时候被截断了。真正的问题是latin1_swedish_ci中的小 i 意味着密钥不区分大小写!事实上,我的数据确实包含两个URI,这些URI的大小写只有不同。 添加
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
表创建语句解决了问题。
感谢您的评论。但我无法理解为什么这种行为是默认行为。