6

描述:我有一个巨大的 MySQL 数据库表。总大小约为 10 TB。它只包含文本。

此数据库表中的示例文本:

在其他情况下,一些国家逐渐学会生产以前只有美国和其他几个国家才能生产的相同产品和服务。美国的实际收入增长已经放缓。

大约有 500 亿种不同的文本。

我尝试了什么?

我已经尝试将它们全部压缩。实际上它起作用了,减小了总尺寸。但是,我需要进行搜索,当它们位于 zip 文件中时,我无法搜索任何数据。

我试过 PHP 的base64编码。它使我的示例文本数据为:

SW4gb3RoZXIgY2FzZXMsIHNvbWUgY291bnRyaWVzIGhhdmUgZ3JhZHVhbGx5IGxlYXJuZW QgdG8gcHJvZHVjZSB0aGUgc2FtZSBwcm9kdWN0cyBhbmQgc2VydmljZXMgdGhhdCBwcmV2 aW91c2x5IG9ubHkgdGhlIFUuUy4gYW5kIGEgZmV3IG90aGVyIGNvdW50cmllcyBjb3VsZC Bwcm9kdWNlLiBSZWFsIGluY29tZSBncm93dGggaW4gdGhlIFUuUy4gaGFzIHNsb3dlZC4 =

我想完成什么?

我想在将它们发送到 MySQL 之前减小文本的大小。首先,我不知道我怎么能做这份工作。我正在考虑加密和解密数据。

所以,这是我想做的一个例子:

我想在存储之前加密文本数据。然后,我想从 MySQL 调用加密数据以进行解密。

有什么办法可以减小文本的大小?Base64 对我不起作用,还有其他方法吗?

4

4 回答 4

13

请注意,既不是base64也不encryption 是为减少字符串长度而设计的。你应该看的是压缩,我认为你应该gzcompressgzdeflate

使用文本的解码版本的示例

$original = "In other cases, some countries have gradually learned to produce the same products and services that previously only the U.S. and a few other countries could produce. Real income growth in the U.S. has slowed." ;
$base64 = base64_encode($original);
$compressed = base64_encode(gzcompress($original, 9));
$deflate = base64_encode(gzdeflate($original, 9));
$encode = base64_encode(gzencode($original, 9));


$base64Length = strlen($base64);
$compressedLength = strlen($compressed) ;
$deflateLength  = strlen($deflate) ;
$encodeLength  = strlen($encode) ;

echo "<pre>";
echo "Using GZ Compress   =  " , 100 - number_format(($compressedLength / $base64Length ) * 100 , 2)  , "% of Improvement", PHP_EOL;
echo "Using Deflate       =  " , 100 - number_format(($deflateLength / $base64Length ) * 100 , 2)  , "% of Improvement", PHP_EOL;
echo "</pre>";

输出

Using GZ Compress   =  32.86%  Improvement
Using Deflate       =  35.71%  Improvement
于 2012-09-22T19:10:08.223 回答
4

Base64 不是压缩或加密,它是编码。您可以在将文本数据存储到数据库之前通过 gzip 压缩算法 (http://php.net/manual/en/function.gzcompress.php) 传递文本数据,但这基本上会使数据无法通过 MySQL 查询进行搜索。

于 2012-09-22T19:10:33.610 回答
2

好吧,真的很有挑战性!(至少对我来说!)......你有 10 TB 的文本,你想将它加载到你的 MySQL 数据库中并在表上执行全文搜索!

也许在一个好的硬件上的一些集群或一些性能棘手的方法对你有用,但如果不是这样,你可能会发现它很有趣。

首先,您需要一个脚本来一个接一个地加载这 500 亿段文本,将它们拆分为一些words并将它们视为关键字,这意味着给它们一个数字 id,然后将它们保存在一个表格中。顺便说一句I am piece of large text.,会是这样的:

[1: piece][2: large][3: text]

并且I'm the next large part!将是:

[4: next][2: large][5: part]

顺便说一句I, am, of, I'm, the,加号已被消除,因为它们通常在搜索., !中没有任何作用。keyword-based但是,如果您愿意,您也可以将它们保留在关键字数组中。

给原文一个唯一的id。您可以计算md5原始文本的,或者只是简单地给出一个数字 id。然后将其存储在id某个地方。

texts您将需要有一个表来保持和之间的关系keywords。它将是这样的many-to-many结构:

[text_id][text]
1 -> I am piece of large text.
2 -> I'm the next large part!

[keyword_id][keyword]
1 -> piece
2 -> large
3 -> text
4 -> next
5 -> part

[keyword_id][text_id]
1 -> 1
2 -> 1
3 -> 1
4 -> 2
2 -> 2
5 -> 2

现在,想象一下如果有人搜索会容易得多(尤其是对于 MySQL!)large text

据我在网上找到的,如果您只是将所有内容都保留为关键字,那么它将是您的关键字或最大50,000字数。因此,您可以简单地猜测 50,000 个单词将远远少于基于文本的数据。60,000600,000700,00010 TB

我希望它有所帮助,如果您需要,我可以解释更多或帮助您以某种方式使其工作!:)

于 2012-09-22T19:53:38.237 回答
1

虽然这两个答案都解决了问题并提供了文本压缩选项,但我认为压缩将有助于解决您的问题。搜索大量数据从来都不是 MySQL 等关系型数据库的目的。

您已经获得了 Apache Lucene 的一个非常好的提示,还有其他选项,例如 Sphinxsearch。这是一个比较的快速线程:

全文搜索引擎对比——Lucene、Sphinx、Postgresql、MySQL?

于 2012-09-22T19:28:46.357 回答