0

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   |
|--------------------------------------------------|

2 つの特定の URI に対して、複数の値が格納されないようにしたいと考えています。したがって、次の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 で結合して、異なるテーブルから特定の uri のペアのすべての値を含む結果を取得したい場合があります。

私は別のことを発見しました:私は次のように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() メソッドが同じパラメーターで 2 回呼び出されることはありません。

ご提案いただきありがとうございます。

4

1 に答える 1

0

自分の質問に答えて申し訳ありませんが、何時間も正気を疑った後、ようやく問題が見つかりました. キーの長さとは関係ありません。これで問題ありません。例外メッセージは、ある時点で切り捨てられたようです。本当の問題は、latin1_swedish_ciの小さなiは、キーが大文字と小文字を区別しないことを意味することでした! 実際、私のデータには、大文字と小文字だけが異なる 2 つの URI が含まれていました。追加する

DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

テーブル作成ステートメントに問題を解決しました。

コメントしてくださってありがとうございます。ただし、この動作がデフォルトである理由がよくわかりません。

于 2013-08-09T02:43:40.767 に答える