数据表设计时存储文章内容的字段使用的是text类型,这个类型最大只能存储65535个字节,遇到这个问题时最先想到的就是更改数据库的字段类型为mediumtext或者longtext。 t0 e$ \" b* [
虽然更改字段类型可以解决问题,但是突然想到还可以使用压缩的方式来解决这个问题。我们可以将文章内容使用压缩函数进行压缩后再存储。比如文章内容10万个字符,压缩后可能就只有5万个字符甚至更少。% N' F3 X* P* Q4 ], q, ~
在实际运用之前我们来看看PHP相关的压缩函数吧
) g- q1 p; U' S1 s# k8 W9 b PHP中又三个压缩函数,分别为gzcompress、gzdeflate及gzencode。对应的解压缩函数为gzuncompress、gzinflate及gzdecode
# j+ I& k! Q: V5 y: E <?php
$test = 'cdasbgfedty4r263gv43t5t632tgrewygrewhrt4wntgrdmnhtejrbgsdsfbgfsbfgsngfsjmhbdzgdrehwfdbnxnv cnbfddbfdbfdfdshgbfb cv54';
echo '原字符串:<br/>';
var_dump($test);
echo '<br/><br/>';
echo 'gzcompress压缩后:<br/>';
$gzcompress = gzcompress($test);
var_dump($gzcompress);
echo '<br/><br/>';
echo 'gzdeflate压缩后:<br/>';
$gzdeflate = gzdeflate($test);
var_dump($gzdeflate);
echo '<br/>';
echo 'gzencode压缩后:<br/>';
$gzencode = gzencode($test);
var_dump($gzencode);
echo '<br/><br/>';
echo 'gzcompress解压后:<br/>';
var_dump(gzuncompress($gzcompress));
echo '<br/><br/>';
echo 'gzdeflate解压后:<br/>';
var_dump(gzinflate($gzdeflate));
echo '<br/><br/>';
echo 'gzencode解压后:<br/>';
var_dump(gzdecode($gzencode)); 结果如下所示:( L' M' r7 ? B5 |
" R: W9 \ N8 a0 a 似乎压缩效果不是很好,但是我们把测试数据换成数字类型,压缩效果就很明显了。具体具体如下所示:
1 O: p. x, I( ]5 L+ H
2 S( W# ?6 q# j' X% c% A
从上面的压缩效果来看,不论原字符串是什么类型的数据,gzdeflate的压缩效果最好,gzencode压缩效果最差。
1 G( d: H' r( L# \ 为什么会造成这么大的差距呢?要明白其原因首先就要明白其工作的原理
! _, }( W4 Z. n$ | 压缩原理:
5 R- n, q' p& C. r" f 压缩文件的基本原理是查找文件内的重复字节,并建立一个相同字节的"词典"文件,并用一个代码表示,比如在文件里有几处有一个相同的词"AB"用一个代码表示并写入"词典"文件,这样就可以达到缩小文件的目的。
) {( M* Q, `( m* G1 h) R. @6 E- C( I1 B 由于计算机处理的信息是以二进制数的形式表示的,因此压缩就是把二进制信息中相同的字符串以特殊字符标记来达到压缩的目的
* L6 F8 j1 I- Q6 s2 a' g 总结:
+ O6 X) x( n! ^: \3 s4 h 数字字符串相同的字符很多毕竟数字只有0~9这十个,而非数字类的字符串就很多了,因此数字字符串压缩效果更好。! f# t8 ^5 s) E* v& Y3 t8 k, m
那么我们的文章能不能使用压缩呢,压缩效果好不好呢?实际实验了一下,压缩效果还可以。思考了一下原因,文章使用的是富文本编辑的,而富文本又有很多html标签,这些html标签大部分都是相同的,压缩后体积自然就变小了。9 r7 ^. t2 p4 d0 ?! F8 K/ y
压缩效果:gzdeflate > gzcompress > gzencode Q4 N3 \9 U8 w1 u; t8 x! d) E
使用数据库存储压缩数据时,可能会报如下错误:
9 U7 C" Z; _, ? M1 u+ P* i Malformed UTF-8 characters, possibly incorrectly encoded 主要原因是:压缩后会有特殊字符,这些字符可能是GBK、GB2312、BIG5等编码格式,而数据库及字段使用的是utf8编码。我们可以先将压缩后的数据使用base64_encode进行转换后再存储到数据库,获取数据时使用base64_decode转换回来再进行解压缩。 T. T; n, K8 K
特意实验了一下,一篇12021个字符串的文章使用gzdeflate压缩后只有2685个字符,再使用base64加密后字符长度为3580。虽然base64加密后内容变大了,但是相对原字符,压缩效果依然很乐观。