我需要在mysql数据库中存储大量的文本。它将有数百万条字段类型为LONGTEXT的记录,数据库大小将非常大。
所以,我想问,如果有一种安全的方法来压缩文本存储到文本字段,以节省空间,如果需要,能够提取它回来之前?
类似:
$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条记录,权重为4gb, 99%的查询是SELECT。我有充分的理由认为数字呈图表式增长。我不喜欢在文件中存储文本,因为有相当沉重的逻辑,我的网站有相当多的点击。
你打算索引这些文本吗?这个文本的读取负载有多大?插入负载?
你可以使用InnoDB数据压缩-透明和现代的方式。查看文档获取更多信息。
如果你有非常大的文本(比如,每个文本超过10MB),那么最好不要将它们存储在Mysql中。在文件系统中存储gzip压缩的文本,在mysql中只存储指针和元数据。您可以在将来轻松扩展存储并将其移动到例如DFS。
更新:在Mysql之外存储文本的另一个优点:DB保持小而快。负:数据不一致的概率很高。
更新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.
如果你正在压缩(例如。gzip),那么不要使用任何类型的TEXT字段。它们不是二进制安全的。输入/输出文本字段的数据受到字符集转换的影响,这可能会(尽管不一定)破坏压缩后的数据,并在检索/解压缩文本时给您一个损坏的结果。
使用BLOB字段代替,它是二进制透明的,不需要对数据进行任何转换。
最好将文本字段定义为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']);
您可能还想使用COMPRESS选项来启用数据包压缩。阅读有关该选项的一些信息:
- 在MySQL Connector/Net中使用压缩
- MySQL
对于PHP,我已经找到了MYSQLI_CLIENT_COMPRESS For mysqli_real_connect函数
您可以使用php函数gzdeflate和gzinflate来处理文本
压缩大数据没有任何好处文本进入数据库。
从长远来看,这些是你可能面临的问题:
- 如果服务器崩溃,数据可能很难恢复
- 不适合搜索
- mysql服务器和浏览器之间传输数据需要额外的时间。
- 备份耗时(不使用复制)。
我认为将这些大文本存储到磁盘文件中会更容易:
- 分布式备份(rsync).
- PHP处理文件上传。