0

mySQLテーブルに10億行をロードします。そのうちの1つの列(BINARY(20))は、連結された他のいくつかの列のSHA1ハッシュです。区切り文字に依存しているように見えるため、LOADコマンドを使用してバイナリ値をロードする方法がわかりません。

もちろん、ここでは速度が重要なので、LOADを使用したいと思います。LOADを使用して固定長のバイナリ値をロードする方法を知っている人はいますか?これはおそらくトリガーの仕事ですか?(これまでトリガーを使用したことはありません。)または、LOADコマンドで関数(UNHEXなど)を呼び出すことはできますか?

(よくある質問のようですが、いいえ、base64または16進表記で格納したくありません。BINARY(20)が必須です。)

4

2 に答える 2

0

バイナリデータとLOAD DATA INFILEは友達ではありません。ファイル形式指定子には区切り文字が必要であり、任意のバイナリ データはフィールド区切りではなく長さで区切られます。

あなたの最善の策は、大きなマルチINSERTステートメントを使用して、それを強化することです。これらは、16 進数でエンコードされた文字列をデコードしてBINARY列に自動的にドロップすることを処理できます。

とはいえ、なぜ誰もがこの惨めさを自分自身に望んでいるのかはわかりません. 標準の 16 進表記と比べて 1 行に 20 バイトを節約することは、問題に値するものではありません。

膨大な数の行をロードする必要がある場合、MySQL は最適なプラットフォームではない可能性があります。あなたがすべきことは、そのデータを複数のテーブルまたはデータベースにシャーディングするか、NoSQL ストアを使用してより効果的に分割することです。

于 2013-01-31T03:30:11.000 に答える
0

これは妥当なアプローチのようです: LOAD の SET 形式を使用し、変数を使用し、UNHEX や CONCAT などの関数を呼び出します。

例えば:

mytable に 4 つの列があるとします。

mysha1  BINARY(20)
a       VARCHAR(20)
b       VARCHAR(20)
c       VARCHAR(20)

列 mysha1 は、'|' で連結された a、b、および c の sha1 ハッシュです。区切りとして。

そして、入力ファイルがそれぞれ 3 つのフィールドのタブ区切りのテキスト行であるとします。

abel\tbaker\tcharlie\t\n
dog\teasy\tfor\t\n
etc\tetc\tetc\t\n

テーブルをロードする方法は次のとおりです

LOAD DATA INFILE '/foo/bar/input.txt' INTO TABLE mytable 
FIELDS TERMINATED BY '\t' ESCAPED BY '\\' LINES TERMINATED BY '\n' 
(@f1, @f2, @f3) SET mysha1 = UNHEX(SHA1(CONCAT_WS('|', @f1, @f2, @f3))), 
a=@f1, b=@f2, c=@f3;

UPDATE : 一般に、SHA1 などの組み込み関数で計算できない任意のバイナリ値の場合、バイナリ値を表示可能な 16 進文字列として INFILE で表現し、@variable に読み取ってから、 UNHEX 関数でバイナリに変換します。例えば:

マイテーブル:

mybin8    BINARY(8)
a         VARCHAR(20)
b         VARCHAR(20)
c         VARCHAR(20)

入力ファイル:

abel\tbaker\tcharlie\t0123456789abcdef\n
dog\teasy\tfox\t2468ace13579bdf\n
etc\tetc\tetc\t0000000000000000\n

ロード コマンド:

LOAD DATA INFILE '/foo/bar/input.txt' INTO TABLE mytable 
FIELDS TERMINATED BY '\t' ESCAPED BY '\\' LINES TERMINATED BY '\n' 
(a, b, c, @myhex) SET mybin8 = UNHEX(@myhex);
于 2013-02-01T21:29:56.883 に答える