MySQL набор символов для сжатия чисел - PullRequest
0 голосов
/ 05 августа 2020

Я хотел бы сохранить много чисел в одной ячейке и сэкономить место. Идея состоит в том, чтобы закодировать каждый из них в строку постоянной длины и сохранить их в текстовом поле (предположительно MEDIUMTEXT). Какие символы можно использовать, чтобы они составляли только 1 байт? Я предполагаю, что специальные символы хранятся таким образом, чтобы использовать более 1 байта. Я могу использовать, например, base64, но я не уверен, сколько символов кодировки я могу добавить к базе, прежде чем MySQL фактически использует больше места для их хранения, чем мне удается сохранить.

1 Ответ

0 голосов
/ 05 августа 2020

Вы говорите «числа». Что вы имеете в виду на самом деле?

  • Цифры? См. Выше.
  • Целые числа? (без десятичной точки, без дроби)
  • Плавает? (с показателем степени, et c)

Некоторые примечания по цифрам, сжатию и т.д. c:

  • 1 байт на символ Ascii - 8 бит
  • 1 байт на di git, поскольку это символ ascii
  • Один случайный di git при максимальном теоретическом сжатии составляет около 0,332 байта. Визуализируйте это так: 1000 - это 3 цифры, а 1024 - 10 бит.
  • MySQL Тип данных DECIMAL помещает 2 цифры в один байт для меньших чисел; для больших чисел он хранит 9 цифр в 4 байтах.
  • Если вы заархивируете миллион цифр числа Пи, это будет очень близко к описанному выше сжатию.
  • Простое практическое правило состоит в том, что "text" сжимает 3: 1.
  • Base64 расширяет байтов на 8/6, потому что один 8-битный байт представлен 64 (2 ^ 6) разными символами.
  • Base64 более полезен для исключения специальных символов; это не совсем метод сжатия.
  • 4-байтовый MySQL INT (диапазон от -2 миллиардов до +2 миллиардов, но обычно просто положительный и неравномерно распределенный), при преобразовании в base64 будет занимает более 5 байтов для 9-10 цифр.

Общие методы

Сжатие клиента : Для 123,2345,88,22 вот один способ справиться с этим. Фактически, я рекомендую это практически для любой обработки текста, где требуется сжатие в MySQL.

  1. используйте compress() (или аналогичную функцию) в вашем клиенте.
  2. используйте BLOB (до 64 КБ) или MEDIUMBLOB (до 16 МБ) в таблице
  3. используйте uncompress() после получения большого двоичного объекта.

Для массива чисел, используйте json_encode для массива, затем введите в compress + blob, как указано выше. Он будет работать для «чисел» любого размера и обеспечит почти максимальное сжатие.

Вы не можете эффективно добраться до MEDIUMTEXT или BLOB, чтобы получить одно число из массива. Будет получена вся ячейка.

Это приводит к еще одному общему утверждению ... Если у вас есть много вещей, которые вам не нужно ни сортировать, ни получать по отдельности, JSON - хороший подход. Думайте об этом как о с точки зрения MySQL о непрозрачном пятне. Приложение записывает и перечитывает его как одну большую вещь, а затем разбирает.

JSON, возможно, закодирует приведенный выше пример как ["123","2345","88","22"], который после сжатия станет немного толще. Но любой хороший алгоритм сжатия заметит и воспользуется преимуществом повторения.

Воспользуйтесь преимуществами данных

17,22738 48,77795 300 
17,22792 48,77795 297 
17,22853 48,77764 294 
17,22874 48,77743 297 
17,22887 48,77704 300 
17,22968 48,77671 305 
17,23069 48,77563 296 
17,23092 48,77561 292 

->

17,22738 48,77795 300 
54 0 -3
61 -31 -3
21 -21 3
13 -39 3
81 -33 5
1 -108 -9
23 -2 -4

Числа остаются относительно постоянными. Воспользуйтесь этим, начав с необработанных данных, а затем переключившись на дельты. Попробуйте это примерно в 10 раз больше данных; Я подозреваю, что вы продолжите получать лучше, чем 2-кратное сжатие до сжатия, но, возможно, чуть меньше 2-кратного после сжатия. (При архивировании можно использовать повторение 48,777; я использую его больше, выбрасывая большую часть.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...