有什么方法可以减少文本的大小?

时间:2012-09-22 19:00:29

标签: php mysql sql encoding

说明:我有一个巨大的MySQL数据库表。总大小约为10太字节。它只包含文本。

此数据库表格中的示例文字:

  

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

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

我尝试了什么?

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

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

  

SW4gb3RoZXIgY2FzZXMsIHNvbWUgY291bnRyaWVzIGhhdmUgZ3JhZHVhbGx5IGxlYXJuZW   QgdG8gcHJvZHVjZSB0aGUgc2FtZSBwcm9kdWN0cyBhbmQgc2VydmljZXMgdGhhdCBwcmV2   aW91c2x5IG9ubHkgdGhlIFUuUy4gYW5kIGEgZmV3IG90aGVyIGNvdW50cmllcyBjb3VsZC   Bwcm9kdWNlLiBSZWFsIGluY29tZSBncm93dGggaW4gdGhlIFUuUy4gaGFzIHNsb3dlZC4 =

我想要完成什么?

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

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

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

任何减少文本大小的方法? Base64对我不起作用,还有其他方法吗?

4 个答案:

答案 0 :(得分:11)

请注意,base64encryption都不是为减少字符串长度而设计的。你应该看到的是压缩,我认为你应该看看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

答案 1 :(得分:3)

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

答案 2 :(得分: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存储在某处。

您需要有一个表格来保持textskeywords之间的关系。它将是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

现在,想象一下如果有人搜索large text会更容易(特别是对于MySQL!)!

就我在网上发现的情况而言,如果你是关键字或最多50,000 - 60,000字,那将是600,000700,000字词。只需将所有内容保存为关键字。因此,您可以简单地猜测50,000个单词远远少于10 TB基于文本的数据。

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

答案 3 :(得分:1)

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

对于Apache Lucene,你有一个非常好的提示,还有其他选项,如Sphinxsearch。这是一个比较的快速线程:

Comparison of full text search engine - Lucene, Sphinx, Postgresql, MySQL?