0

我将在 mySQL 表中加载十亿行,其中一列 - BINARY(20) - 是其他几个列的 SHA1 哈希值,连接在一起。副手我看不到如何使用 LOAD 命令加载二进制值,因为它似乎依赖于分隔符。

显然,速度在这里很重要,这就是我想使用 LOAD 的原因。有谁知道如何使用 LOAD 加载固定长度的二进制值?这可能是触发器的工作吗?(我以前从未使用过触发器。)或者我可以在 LOAD 命令中调用一个函数(例如 UNHEX)吗?

(因为这似乎是一个常见问题:不,我不想以 base64 或十六进制表示法存储它。BINARY(20) 是必需的。)

4

2 回答 2

0

二进制数据又LOAD DATA INFILE不是朋友。文件格式说明符需要一个分隔符,并且任意二进制数据是长度分隔的,而不是字段分隔的。

你最好的选择是使用大型多INSERT语句并坚持下去。这些可以处理将十六进制编码的字符串解码并自动放入BINARY列中。

不过,我不确定为什么有人会希望自己遭受这种痛苦。与标准十六进制表示法相比,每行保存 20 个字节是不值得的。

如果你真的需要加载数以千计的行,也许 MySQL 不是最好的平台。您应该做的是将数据分片到多个表或数据库中,或者使用 NoSQL 存储更有效地将其拆分。

于 2013-01-31T03:30:11.000 回答
0

这似乎是一个合理的方法:使用 SET 形式的 LOAD,使用变量并调用诸如 UNHEX 和 CONCAT 之类的函数。

例如:

假设 mytable 有四列:

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

列 mysha1 是 a、b 和 c 的 sha1 哈希,并与 '|' 连接 作为分隔符。

并假设输入文件是三个字段的制表符分隔的文本行:

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;

更新:在一般情况下,对于无法使用内置函数(如 SHA1)计算的任意二进制值,二进制值必须在 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 回答