Сжатие текста перед его сохранением в базе данных

Мне нужно хранить очень большой объем текста в базе данных 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 

В настоящее время он имеет около 800 тыс. Записей и весит 4 ГБ, 99% запросов – SELECT. У меня есть все основания полагать, что цифры диаграмм увеличиваются. Я не хотел бы хранить тексты в файлах, потому что вокруг довольно много логики, и на моем сайте довольно много хитов.

Solutions Collecting From Web of "Сжатие текста перед его сохранением в базе данных"

Собираетесь ли вы индексировать эти тексты. Насколько велика читаемая нагрузка на эти тексты? Вставить нагрузку?

Вы можете использовать сжатие данных InnoDB – прозрачным и современным способом. Дополнительную информацию см. В документах .

Если у вас действительно огромные тексты (скажем, каждый текст выше 10 МБ), то хорошая идея – не хранить их в 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
  • Свойство сжатия в dotConnect для MySQL

Для PHP я нашел это – MYSQLI_CLIENT_COMPRESS для функции mysqli_real_connect .

Нет никаких преимуществ при сжатии больших текстов в базу данных.

Вот проблемы, с которыми вы можете столкнуться в долгосрочной перспективе:

  • Если сервер выйдет из строя, данные могут быть трудно восстановить.
  • Не идеально подходит для поиска.
  • Требуется дополнительное время для передачи данных между сервером mysql и браузером.
  • Время, затрачиваемое на резервное копирование (не использующее репликацию).

Я думаю, что хранить эти большие тексты в файл на диске будет проще:

  • Распределенное резервное копирование (rsync).
  • PHP для обработки загрузки файлов.

Вы можете использовать функции php gzdeflate и gzinflate для текста.