Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在将文本存储到数据库之前压缩文本_Php_Mysql_Compression_Archive - Fatal编程技术网

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

Php 在将文本存储到数据库之前压缩文本,php,mysql,compression,archive,Php,Mysql,Compression,Archive,我需要在mysql数据库中存储大量的文本。这将是数百万条字段类型为LONGTEXT的记录,数据库的大小将是巨大的 所以,我想问,在将文本存储到文本字段之前,是否有一种安全的方法来压缩文本以节省空间,如果需要,是否有能力将其提取回来 比如: $archived_text = compress_text($huge_text); // saving $archived_text to database here // ... // ... // getting compressed text fr

我需要在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查询。我有充分的理由认为数字会以图表的方式增加。我不想将文本存储在文件中,因为有很强的逻辑性,而且我的网站有很多点击率。

如果你正在压缩(例如gzip),那么就不要使用任何类型的文本字段。它们不是二进制安全的。输入/输出文本字段的数据需要进行字符集转换,这可能(尽管不一定)会损坏压缩的数据,并在检索/解压缩文本时导致损坏的结果


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

是否要为这些文本编制索引。这篇文章的阅读量有多大?插入负载

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

如果您有非常大的文本(比如,每个文本都超过10MB),最好不要将它们存储在Mysql中。在文件系统中存储由gzip压缩的文本,在mysql中只存储指针和元数据。您可以在将来轻松扩展存储并将其移动到DFS等位置

更新:在Mysql之外存储文本的另一个好处是:DB保持小而快。减:数据不一致的高概率

更新2:如果您有很多编程资源,请查看类似以下项目:

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

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

稍后您将需要使用
键块大小
。请参见
显示状态,如“压缩操作\u正常”
显示状态,如“压缩操作”
。这两个参数的比率必须接近1.0:。

压缩大型数据没有好处 将文本输入数据库

以下是您长期可能面临的问题:

  • 如果服务器崩溃,数据可能很难恢复
  • 不适合搜索
  • 在mysql服务器和浏览器之间传输数据需要额外的时间
  • 备份耗时(不使用复制)
我认为将这些大文本存储到磁盘文件中会更容易:

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

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

  • 在MySQL连接器/Net中
  • 在dotConnect for MySQL中

对于PHP,我发现-。

最好将文本字段定义为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']);

您可以使用php函数gzdeflate和gzflate来表示文本。

如果您存储的是二进制数据,请使用BLOB字段,而不是文本。您可能需要重新考虑您对基于文件的存储的否决权。我不知道你说的“重逻辑”是什么意思,但我不认为对于一个流量很大的网站来说,在数据库中存储文本会自动优于文件。谢谢你提供的关于数据类型的信息。但是压缩呢?压缩会删除搜索文本的功能,因为您必须解压缩才能再次获得原始测试。如果您永远不会使用数据库来搜索文本,那么首先不要将压缩(或原始)文本存储在数据库中。将其外部存储在文件中,并在DB中存储一些引用(文件名/路径)。gzcompress使用这种方法效果很好,但请考虑:如果您使用的是InnoDB,这就是方法。但是,使用不进行压缩的引擎。。。此外,我看到了很多不在数据库中“只存储指向文件的指针”的理由(还有很多这样做的理由——TIMTOWTDI,这真的取决于您需要什么)@Oroboros102请查看更新。我是否正确理解innodb压缩只压缩索引?这不是我的情况…不,压缩用于数据和所有索引(PK、secondary、component)。谢谢你的回答。我会这样做,因为这需要在我的应用程序中进行最小的更改。请不要忘记,压缩需要满足很多要求。从mysql版本开始到特殊的表存储方式。我记得,你需要“每桌文件”。所有这些你都可以在文件中找到:我不同意。解压缩gzip流所需的时间在任何普通服务器上都是无关的,与在线延迟相比,您可以完全忽略它。您不需要搜索每个文本字段,通常只需要访问它。