char/varchar — длина в байтах или символах?
На какой-то борде прочитал, что *char отличается от *text тем, что первый измеряет длину в символах, а второй в байтах. То есть, по логике, char(255) запишет строку кириллицей в юникоде все 255 знаков, а text(255) должен ее обрезать примерно до половины. Так вот вопрос: сколько реально байт будет выделено под хранение фиксированного типа char(10) в сравнении utf8_general_ci ? Где искать правду? таблица разрослась до миллионов записей, запросы выполняются неприлично долго, ищу способы увеличения быстродействия. Алсо, узнал, что оказывается, если в таблице есть хотя бы одно поле переменной длины, все поля char автоматически преобразуются в varchar < /оффтоп>
Отслеживать
задан 14 мар 2016 в 13:40
511 1 1 золотой знак 6 6 серебряных знаков 27 27 бронзовых знаков
Если запросы выполняются долго, значит они не оптимизированы, возможно отсутствуют индексы. Размер самих записей влияет на общую производительность, но он не первостепенен. А в юникоде все Русские символы всегда занимают два байта, они меньше в юникоде занимать физически не могут
14 мар 2016 в 13:48
С индексами разобрался в первую очередь и оптимизировал насколько можно (explain).
14 мар 2016 в 13:54
@kanaris, без должного опыта можно с натяжкой говорить с индексами разобрался. оптимизировал насколько можно, поэтому я бы продолжал копать в этом направлении. В частности, когда есть группировка, mysql автоматически выполняет сортировку по этой группировке, поэтому если сортировка не нужна — надо делать order by null Кроме explain будет полезно так же посмотреть и на профилирование через set profiling = 1 и дальнейшего show profile for query. и т.д. И прочитайте эту книжку (на русском только второе издание видел)
14 мар 2016 в 14:32
так же можно несколько улучшить производительность произведя тонкую настройку параметров конфига, про это так же можно прочитать в книге. Еще — если выполняется копирование во временную таблицу на диске, возможно, имеет смысл настроить tmpfs для использования под эти временные таблицы и т.д.
Как задать максимальную длинну Varchar? MySQL
Аувиз
И сколько вместиться символов при кодировке windows-1251?
Дополнено (1). длину.
Дополнено (2). VARCHAR(65535) не ту ли альтернативы? Наподобие «VARCHAR max»
И самое главное сколько туда влезет символов при кодировке windows-1251?
Дополнено (3). stopkran: не верю.
Дополнено (4). Enyby: спокойно задаю VARCHAR(20000)
Дополнено (5). Enyby: Как зависит длина от кодировки? То есть Просто вместиться меньше символов так как один символ кодируется двумя байтами, или в varchar придется вводить меньшее значения типа 65532/2 = varchar(32766).
Дополнено (6). Enyby: Следовательно если кодировка UTF-8 то VARCHAR(21 844), а не VARCHAR(65532)?
или VARCHAR(65532) но вместиться туда 21 844 сиволов в кодировке UTF-8?
stopkran
Varchar(255)
255 символов
Enyby
255. Именно. Если надо больше — TEXT, MEDIUMTEXT, LONGTEXT.
Enyby
Storage Requirements for String Types
Column Type Storage Required
CHAR(M) M bytes, 0 VARCHAR(M) Prior to MySQL 5.0.3: L + 1 bytes, where L BINARY(M) M bytes, 0 VARBINARY(M) L+1 bytes, where L <= M and 0 TINYBLOB, TINYTEXT L+1 byte, where L < 28
BLOB, TEXT L+2 bytes, where L < 216
MEDIUMBLOB, MEDIUMTEXT L+3 bytes, where L < 224
LONGBLOB, LONGTEXT L+4 bytes, where L < 232
ENUM(‘value1′,’value2’,…) 1 or 2 bytes, depending on the number of enumeration values (65, 535 values maximum)
SET(‘value1′,’value2’,…) 1, 2, 3, 4, or 8 bytes, depending on the number of set members (64 members maximum)
Enyby
Я очень рад за вас. У вас версия MySQL старше чем 5.03. Там максимальная длина 65532, хотя, на деле, может зависеть от кодировки.
Enyby
Именно. 65532 — это предел в байтах для VARCHAR в мускуле старше 5, 03. Если у вас кодировка utf-8, то это будет 65 532/3 = 21 844 символов. Почему 3? Потому что максимальная длина в utf-8 для символа в MySQL — 3 байта. Как узнал? — SHOW CHARSET.
Enyby
лучший ответ VARCHAR(21 845) — но это в теории. На практике, для InnoDB и MyISAM есть ограничение на длину записи в 65535 байт. В это ограничение не вписываются BLOB и TEXT, так как Для них текст хранится отдельно от записи. В виду этого ограничения, больше чем VARCHAR(21 844) поля вы не создадите, причем это будет единственное поле таблицы.
А теперь немного о грустном. VARCHAR отличается от CHAR тем, что первый занимает, обычно меньше места по той причине, что его размер зависит от размера контента. Второй же честно резервирует число символов объявленных в типе. CHAR(21844) с одним символом занимает почти 65 кб при кодировке utf-8. А теперь на десерт — при сортировках, MySQL может использовать временные таблицы на диске. Обычно эти таблицы создаются когда памяти не хватет для сортировки. При создании таблицы имеют fixed-row строение, а это значит, что все VARCHAR разворачиваются в CHAR. Причина проста — fixed-row намного быстрее и удобнее сортировать. Но в вашем случае это обратится в ужас летящий на крыльях ночи. У вас будут «из ниоткуда» возникать гигантские временные таблицы с размерами под гигабайты и выше. Соответственно, производительность дисковой системы просядет и сервак может уйти в коллапс.
- Какую максимальную длину пароля можно задать в БД MySQL для входа?
- SQL-запрос: CREATE TABLE Users (Username varchar (40) PRIMARY KEY, PASSWORD varchar (32 Ответ MySQL
- Как в PHP определить длинну строки кирилицы?
- Как поставить максимальную и минимальную длину логина и пароля на своём сайте, php & mysql
- Mysql дата заполнена как VARCHAR как реализовать сортировку по убыванию в этом случае?
Новые вопросы
- Как упорядочивать номера записей в базе данных mysql?
- Код на PHP + mySQL механизм взаимодействия
- MySQL Error Not connection задолбала
- КАК СОЗДАТЬ СТОЛБЕЦ В MYSQL SAMP
- PHP MySQL выдернуть записи и тут же их удалить вернув результат
Форум пользователей MySQL
Зачем нужно указывать длину ячейки varchar меньше 255-и символов, если на расход памяти это вроде как не влияет?
#2 12.01.2013 22:48:57
deadka Администратор Зарегистрирован: 14.11.2007 Сообщений: 2416
Re: Зачем указывать длину varchar меньше 255?
. Что значит «не влияет на расход памяти»? И что за привязка такая к числу 255? В-общем, поясните свою мысль.
Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли.
#3 12.01.2013 23:25:58
Имя занято Участник Зарегистрирован: 26.10.2011 Сообщений: 17
Re: Зачем указывать длину varchar меньше 255?
deadka, а что тут пояснять-то?)
Разница между ячейками CHAR(10) и VARCHAR(10) в том, что CHAR(10) всегда занимает 10 байт, даже если в ней записана только одна буква. А ячейка VARCHAR(10) будет занимать от 1-го до 11-и байт в зависимости от содержимого.
http://dev.mysql.com/doc/refman/5.6/en/char.html
Так зачем писать VARCHAR(10), если всегда можно писать VARCHAR(255) и не париться?
255 потому что:
1) до версии MySQL 5.0.3 это была максимальная длина
2) если указать больше 255-и, то к длине каждой записи будет прибавляться 2 байта вместо одного
http://dev.mysql.com/doc/refman/5.6/en/ … ments.html
3) если нужно хранить в ячейке большой текст, то для этого есть тип TEXT
Отредактированно Имя занято (12.01.2013 23:27:08)
11.4.1. CHAR и VARCHAR Типы
CHAR и VARCHAR типы подобны, но отличаются по способу, которым они сохранены и получаются. Они также отличаются по максимальной длине и по тому, сохраняются ли конечные пробелы.
CHAR и VARCHAR типы объявляются с длиной, которая указывает на максимальное количество символов, которые Вы хотите сохранить. Например, CHAR(30) может содержать до 30 символов.
Длина a CHAR столбец фиксируется к длине, которую Вы объявляете, когда Вы составляете таблицу. Длина может быть любым значением от 0 до 255. Когда CHAR значения сохранены, они дополняются правом пробелами к указанной длине. Когда CHAR значения получаются, конечные пробелы не удаляются если PAD_CHAR_TO_FULL_LENGTH Режим SQL включается.
Значения в VARCHAR столбцы являются строками переменной длины. Длина может быть определена как значение от 0 до 65 535. Эффективная максимальная длина a VARCHAR подвергается максимальному размеру строки (65 535 байтов, который совместно используется среди всех столбцов), и используемый набор символов. См. Раздел E.10.4, «Пределы на Столбце таблицы граф и Размер Строки».
В отличие от CHAR , VARCHAR значения сохранены как 1-байтовый или 2-байтовый префикс длины плюс данные. Префикс длины указывает на число байтов в значении. Столбец использует байт одной длины, если значения требуют не больше, чем 255 байтов, два байта длины, если значения могут потребовать больше чем 255 байтов.
Для VARCHAR столбцы, конечные пробелы сверх длины столбца являются усеченными до вставки, и предупреждение сгенерировано, независимо от режима SQL в использовании. Для CHAR столбцы, усечение избыточных конечных пробелов от вставленных значений выполняется тихо независимо от режима SQL.
VARCHAR значения не дополняются, когда они сохранены. Конечные пробелы сохраняются, когда значения сохранены и получаются в соответствии со стандартным SQL.
Следующая таблица иллюстрирует различия между CHAR и VARCHAR показывая результат хранения различной строки оценивает в CHAR(4) и VARCHAR(4) столбцы (предполагающий, что столбец использует однобайтовый набор символов такой как latin1 ).
Значение | CHAR(4) | Необходимое хранение | VARCHAR(4) | Необходимое хранение |
---|---|---|---|---|
» | ‘ ‘ | 4 байта | » | 1 байт |
‘ab’ | ‘ab ‘ | 4 байта | ‘ab’ | 3 байта |
‘abcd’ | ‘abcd’ | 4 байта | ‘abcd’ | 5 байтов |
‘abcdefgh’ | ‘abcd’ | 4 байта | ‘abcd’ | 5 байтов |
Значения, показанные как сохраненный в последней строке таблицы, применяют только если не использующий строгий режим ; если MySQL работает в строгом режиме, значения, которые превышают длину столбца, не сохранены , и ошибка заканчивается.
Если данное значение сохранено в CHAR(4) и VARCHAR(4) столбцы, значения, полученные от столбцов, являются не всегда тем же самым, потому что конечные пробелы удаляются из CHAR столбцы после извлечения. Следующий пример иллюстрирует это различие:
mysql>CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)mysql>INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.00 sec)mysql>SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+| CONCAT('(', v, ')') | CONCAT('(', c, ')') |+---------------------+---------------------+| (ab ) | (ab) |+---------------------+---------------------+1 row in set (0.06 sec)
Значения в CHAR и VARCHAR столбцы сортируются и сравниваются согласно сопоставлению набора символов, присвоенному столбцу.
Все сопоставления MySQL имеют тип PADSPACE . Это означает что все CHAR , VARCHAR , и TEXT значения в MySQL сравниваются без отношения с любыми конечными пробелами. «Сравнение» в этом контексте не включает LIKE оператор сопоставления с образцом, для которого конечные пробелы являются существенными. Например:
mysql>CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec)mysql>INSERT INTO names VALUES ('Monty');
Query OK, 1 row affected (0.00 sec)mysql>SELECT myname = 'Monty', myname = 'Monty ' FROM names;
+------------------+--------------------+| myname = 'Monty' | myname = 'Monty ' |+------------------+--------------------+| 1 | 1 |+------------------+--------------------+1 row in set (0.00 sec)mysql>SELECT myname LIKE 'Monty', myname LIKE 'Monty ' FROM names;
+---------------------+-----------------------+| myname LIKE 'Monty' | myname LIKE 'Monty ' |+---------------------+-----------------------+| 1 | 0 |+---------------------+-----------------------+1 row in set (0.00 sec)
Это — истина для всех версий MySQL, и не влияется режимом SQL сервера.
Для тех случаев, где запаздывающие символы-заполнители разделяются или сравнения игнорируют их, если у столбца будет индексирование, которое требует уникальных значений, вставляя в значения столбцов, которые отличаются только по числу запаздывающих символов-заполнителей, то приведет к двойной ключевой ошибке. Например, если таблица содержит ‘a’ , попытка сохранить ‘a ‘ вызывает двойную ключевую ошибку.