在将文本存储在数据库中之前压缩文本

时间:2011-11-22 15:04:16

标签: php mysql compression archive

我需要在mysql数据库中存储大量文本。它将是数百万字段类型为LONGTEXT的记录,数据库大小将是巨大的。

所以,我想问一下,如果有一种安全的方法来压缩文本,然后将其存储到TEXT字段中以节省空间,是否有能力在需要时将其解压缩?

类似的东西:

$archived_text = compress_text($huge_text);
// saving $archived_text to database here
// ...

// ...
// getting compressed text from database
$archived_text = get_text_from_db();
$huge_text = uncompress_text($archived_text);

有没有办法用php或mysql做到这一点?所有文本都是utf-8编码。

更新

我的应用程序是一个大型文献网站,用户可以在其中添加文本。这是我的表格:

CREATE TABLE `book_parts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `book_id` int(11) NOT NULL,
  `title` varchar(200) DEFAULT NULL,
  `content` longtext,
  `order_num` int(11) DEFAULT NULL,
  `views` int(10) unsigned DEFAULT '0',
  `add_date` datetime DEFAULT NULL,
  `is_public` tinyint(3) unsigned NOT NULL DEFAULT '1',
  `published_as_draft` tinyint(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `key_order_num` (`order_num`),
  KEY `add_date` (`add_date`),
  KEY `key_book_id` (`book_id`,`is_public`,`order_num`),
  CONSTRAINT FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

目前它有大约800k记录和4 GB的权重,99%的查询是SELECT。我有理由认为数字会以图形方式增加。我不想在文件中存储文本,因为周围有很重的逻辑,我的网站有很多点击。

6 个答案:

答案 0 :(得分:12)

您要为这些文本编制索引吗?这篇文章的读取负载有多大?插入负载?

您可以使用InnoDB数据压缩 - 透明和现代的方式。有关详细信息,请参阅docs

如果你有大量的文本(比方说,每个文本大于10MB),那么好的想法就是不要将它们存储在Mysql中。存储在文件系统中的gzip文本压缩,只有mysql中的指针和元素。您可以在以后轻松扩展存储空间并将其移至例如DFS。

更新:在Mysql外部存储文本的另一个优点:数据库保持小而快。减:数据不一致的概率很高。

更新2:如果您有很多编程资源,请查看类似这样的项目:http://code.google.com/p/mysql-filesystem-engine/

最终更新:根据您的信息,您可以使用InnoDB压缩 - 它与ZIP相同。你可以从这些参数开始:

CREATE TABLE book_parts
 (...) 
 ENGINE=InnoDB
 ROW_FORMAT=COMPRESSED 
 KEY_BLOCK_SIZE=8;

稍后您将需要使用KEY_BLOCK_SIZE。请参阅SHOW STATUS LIKE 'COMPRESS_OPS_OK'SHOW STATUS LIKE 'COMPRESS_OPS'。这两个参数的比率必须接近1.0:Docs

答案 1 :(得分:7)

如果您正在压缩(例如gzip),则不要使用任何类型的TEXT字段。它们不是二元安全的。进出文本字段的数据受字符集转换的影响,可能(但不一定)会破坏压缩数据,并在检索/解压缩文本时给出损坏的结果。

改为使用BLOB字段,这些字段是二进制透明的,不会对数据进行任何转换。

答案 2 :(得分:6)

最好将文本字段定义为blob,并在PHP中压缩数据以节省通信成本。

CREATE TABLE book_parts (
    ......
    content blob default NULL,
    ......
)

在PHP中,使用gzcompress和gzuncompress。

$content = '......';
$query = sprintf("replace into book_parts(content) values('%s') ",
        mysql_escape_string(gzcompress($content)) );
mysql_query($query); 


$query = "select * from book_parts where id = 111 ";
$result = mysql_query($query);
if ($result && $row = mysql_fetch_assoc($result))
    $content = gzuncompress($row['content']);

答案 3 :(得分:2)

您可能还希望使用COMPRESS选项来启用数据包压缩。 阅读有关此选项的一些信息:

对于PHP,我发现了这个 - MYSQLI_CLIENT_COMPRESS for mysqli_real_connect function

答案 4 :(得分:1)

您可以使用php函数gzdeflate和gzinflate作为文本。

答案 5 :(得分:0)

压缩大型没有任何好处 将文本写入数据库。

从长远来看,以下是您可能遇到的问题:

  • 如果服务器崩溃,数据可能难以恢复。
  • 不适合搜索。
  • 在mysql服务器和浏览器之间传输数据需要额外的时间。
  • 备份耗时(不使用复制)。

我认为将这些大型文本存储到磁盘文件中会更容易:

  • 分布式备份(rsync)。
  • PHP来处理文件上传。