Я использую Django и устанавливаю свой CharField (max_length = 255), хотя я только намерен использовать около 5 символов. Это менее эффективно? Я читал, что это не имеет особого значения с varchar, но затем прочитайте, что он сохранит пространство на жестком диске, чтобы указать только то, что вам нужно.Является ли varchar 2 более эффективным, чем varchar 255?
ответ
В общем, varchar (255) требует столько же хранения, сколько varchar (1). В каждом случае таблица хранит что-то вроде указателя в таблице строк и длине. Например. 4 байта смещения + 1 байтовый размер = 5 байт, фиксированный для каждой строки, только для накладных расходов.
Фактический контент, конечно, находится в таблице строк, которая до тех пор, пока в ней находится ваш магазин. Поэтому, если вы сохраняете 5-буквенное имя в поле varchar (255), оно будет использовать (скажем) 5 служебных байтов + 5 байтов содержимого = 10 байт.
Использование поля varchar (10) будет использовать точно такое же количество, но будет только обрезать строки длиной более 10 байт.
Конечно, конкретные цифры зависят от реализации механизма хранения.
Место на жестком диске дешево, но пространство кэша процессора дорого. Вы можете разместить более мелкие поля, чем большие поля.
Не думайте, что это займет больше места в памяти. Небольшое поле остается маленьким, даже с большой максимальной длиной. Конечно, если вы в итоге станете 200 символов, когда будет короче кодирование, это будет расточительно. – Thilo
Вместо ненужного использования большого пространства используйте пространство, которое не только дает вам больше места для хранения, но и обеспечивает быструю скорость выполнения, так как ему не нужно было считывать все символы. Если вы выберете varchar (255) и добавьте текст «abc», он будет читать символы «a», «b», «c» и другие как пробел.
Итак, всегда используйте пространство u, необходимое для хранения максимального пространства.
Не то, что вы описываете поле CHAR (x), а не поле VARCHAR (x)? –
VARCHAR не будет занимать больше места, чем строки хранятся в нем, помимо overhead for storing the string length:
+------------------------------------------+---------------------------------+
| Value | CHAR(4) Storage Required | VARCHAR(4) Storage Required |
+------------+-----------------------------+---------------------------------+
| '' | ' ' 4 bytes | '' 1 byte |
| 'ab' | 'ab ' 4 bytes | 'ab' 3 bytes |
| 'abcd' | 'abcd' 4 bytes | 'abcd' 5 bytes |
| 'abcdefgh' | 'abcd' 4 bytes | 'abcd' 5 bytes |
+------------+-----------------------------+---------------------------------+
Однако, если вы действительно требуют только 5 символов, то рекомендуется использовать CHAR (5), если в таблице нет других столбцов переменной ширины (т. е. varchars, text или blobs). Тогда вы будете иметь фиксированную длину запись, которая действительно несут некоторые performance advantages:
Для MyISAM таблиц, которые изменяются часто, вы должны стараться избегать всех столбцов переменной длины (VARCHAR, BLOB , и текста). Таблица использует формат динамической строки , если она содержит даже один столбец переменной длины. См. Глава 13, Двигатели хранения.
Одно из предостережений об использовании символа вместо varchar заключается в том, что набор символов влияет на пространство, которое должно быть выделено. Например, если набор символов для этого столбца - utf8, то возможно, что для хранения одного символа потребуется 3 байта.
Поскольку столбец char приводит к распределению фиксированного размера независимо от того, что хранится, база данных должна учитывать наихудший случай. Таким образом, MySQL должен всегда выделять 15 байт в строке для столбца char (5), даже если вы фактически сохраняете только 5 однобайтовых символов в каждой строке.
varchar использует только то, что необходимо для каждой строки, поскольку она хранится, поэтому те же 5 однобайтовых символов занимают всего 6 или 7 байт.Дополнительный байт или два предназначены для отслеживания фактической длины. Для varchar шириной до 255 в однобайтном наборе символов MySQL должен выделять только 1 байт, чтобы сохранить фактическую ширину. Для varchar шириной от 256 до 65535 требуется 2 байта для хранения длины, предполагая набор символов в один байт.
Поскольку для utf8 varchar (255) может потребоваться 255 * 3 байта памяти, MySQL должен выделить 2 байта для хранения длины. Большая часть этой информации содержится в документах MySQL here.
Хотя вы можете объявить ширину 65,535, максимальный эффективный размер в байтах составляет 65 532. Однако, в зависимости от набора символов и символов, которые вы храните, вы можете сохранить максимальное количество многобайтовых символов, чем это.
Как указывает Павел, вы все равно можете использовать символ, если это позволит фиксированной ширине всей строки. Среди прочего, некоторые поиски могут быть быстрее (например, пропускать первые 1000 строк) из-за фиксированного смещения.
Есть также проблемы с производительностью, которые необходимо учитывать вокруг обновлений столбца. Если у вас есть символ (5) и начать с 1 символа, а затем обновить значение до 5 символов, строка может быть обновлена на месте. С varchar, в зависимости от реализации механизма хранения, вся строка, возможно, потребуется переписать в новом месте.
Наконец, если MySQL необходимо создать временную таблицу в памяти для сортировки набора результатов из вашей постоянной таблицы, он использует записи фиксированной длины. Таким образом, он выделяет гораздо больше места в памяти для этих негабаритных столбцов varchar, чем вы могли подумать. Это описано в таблицах MySQL docs for Memory storage. Я полагаю, что MySQL также делает это для дисковых образов.
Длина занимает 1 байт? Таким образом, ограничение длины символа 256 символов? Какова ваша реализация sql? Например, Postgres хранит всего 4 байта + фактическую строку. –
Ну, старые версии MySQL (3.x и 4.x) хранят только 1 байтовую длину и, следовательно, ограничены 255 байтами содержимого. –
MySQL 5.0.3 и более поздние версии могут хранить до 65 535 символов в VARCHAR. –