|
mysql CHAR vs VARCHAR | ☑ | ||
---|---|---|---|---|
0
Помогите
10.01.17
✎
20:53
|
Друзья, объясните кто в теме, такая ситуация:
Делаю колонку с типом CHAR(32) для хранения там строки длинной 32 символа. Таблица на ~ 23,060,801 записей в итоге занимает около 2 гигов. Меняю тип колонки на VARCHAR(32), таблица начинает занимать 1.6 гига. Других колонок нет. Почему CHAR занимает больше чем VARCHAR? Почему таблица все равно занимает места в 2 раза больше чем данные в ней хранящиеся? |
|||
1
Помогите
10.01.17
✎
20:55
|
ответ на последний вопрос наверное в кодировке utf8. Хотя все символы в английском алфавите и цифры.
|
|||
2
Ufo_Attack
10.01.17
✎
21:33
|
||||
3
Помогите
10.01.17
✎
22:26
|
(1) оказалось utf8 тут ни при чем. В 1251 то же самое.
АП! |
|||
4
NorthWind
10.01.17
✎
22:36
|
(3) ответ в названии типа. Var это переменная длина
|
|||
5
Остап Сулейманович
10.01.17
✎
22:37
|
(3) Чего АП?
(2) уже изучил? "Величины типа CHAR при хранении дополняются справа пробелами до заданной длины. ... в противоположность CHAR, при хранении величин типа VARCHAR используется только то количество символов, которое необходимо, плюс один байт для записи длины. Хранимые величины пробелами не дополняются, наоборот, концевые пробелы при хранении удаляются" |
|||
6
H A D G E H O G s
10.01.17
✎
22:37
|
(0) Не все строки у тебя длинной 32 символы.
|
|||
7
NorthWind
10.01.17
✎
22:38
|
Т.е. в случае char место под строку всегда выделяется в том количестве символов, которое указано в скобках. Под varchar - столько места, сколько строка занимает реально, но не более того что указано в скобках.
|
|||
8
Помогите
10.01.17
✎
22:39
|
(4) Друзья, я же конкретный вопрос задал, а не просто описание типов. Зачем мне изучать то что и так давно известно
|
|||
9
Помогите
10.01.17
✎
22:40
|
(6) Откуда это?
|
|||
10
Помогите
10.01.17
✎
22:41
|
(7) Молодец. Тогда почему (0) противоречит тому что ты написал?
|
|||
11
NorthWind
10.01.17
✎
22:44
|
(10) если файл таблицы (или базы, я не знаю как там у мускуля это) открыть на просмотр фаром по F3, там реально какая кодировка текста?
|
|||
12
NorthWind
10.01.17
✎
22:46
|
в чем противоречие? Если среди этой кучи строк есть строки меньше 32 символов, то в случае с варчаром таблица будет занимать меньше места. Об этом тут все и толкуют. Так и получилось - было 2, стало 1.6. Все вроде логично
|
|||
13
Помогите
10.01.17
✎
22:47
|
(11) Не проверял еще, но ты уверен что в этом дело? Я под линуксом не знаю каким редактором можно безопасно открыть большой файл, для меня это сложно.
|
|||
14
Помогите
10.01.17
✎
22:48
|
(12) еще раз повторяю, нет там никаких строк меньше 32 символов.
|
|||
15
NorthWind
10.01.17
✎
22:49
|
(13) чтобы понять что происходит - нужно увидеть. Запись таблицы наверняка содержит служебку помимо вашей строки - какой-нибудь идентификатор, думаю что он никак не меньше 64 бит, а может и все 128. Вы это учли?
|
|||
16
Помогите
10.01.17
✎
22:51
|
(15) Ну я про это и спрашиваю, что такого я не учел, из-за чего меняется размер таблицы.
Все строки такого вида: "000068486B4921A563F132080AA6FB1D" |
|||
17
NorthWind
10.01.17
✎
22:52
|
ну естественно что строка таблицы содержит служебную информацию для того чтобы база могла работать со строками. А как иначе?
|
|||
18
Помогите
10.01.17
✎
22:54
|
(17) да пусть содержит, я только за! Но от чего размер меняется при смене типа? для CHAR хранится больше служебной информации чем для VARCHAR?
|
|||
19
NorthWind
10.01.17
✎
23:04
|
По логике, тут существенного отличия быть не должно. Интересно было бы визуально сравнить базу с одним вариантом типа и с другим. Тип CHAR в некоторых источниках полагают устаревшим и рекомендуют использовать строки переменной длины.
|
|||
20
NorthWind
10.01.17
✎
23:06
|
возможно, что "играют" страничные выравнивания или еще какие-то особенности хранения данных именно в вашей БД.
|
|||
21
youalex
10.01.17
✎
23:27
|
(1) utf - это nvarchar и nchar
|
|||
22
Torquader
10.01.17
✎
23:31
|
Вообще-то, если у нас записи в таблице, то длина каждой записи у нас постоянна, а к VarChar будет добавлено ещё два байта длины.
Сервер не может использовать записи переменной длины, так как тогда при увеличении длины строки в поле ему нужно будет перемещать всю запись. Не забываем ещё про служебную информацию, индексы и т.п. Также, если вы хотите что-то сравнивать, то нужно сначала создать таблицу, а потом её заполнить. P.S. если у вас UTF-8, то для CHAR могут выделить по три байта на символ, а вот что там выделяется под VarChar - нужно смотреть - вполне вероятно, что два байта. |
|||
23
Помогите
10.01.17
✎
23:43
|
Ну ладно. Будем считать что CHAR просто устаревший, и на него разработчики забили.
Всем спасибо, темку можно грохнуть |
|||
24
NorthWind
11.01.17
✎
08:16
|
(22) не буду спорить, но некоторые источники утверждают, что в случае с VARCHAR при хранении количество используемой памяти все же зависит от фактической длины строки. Например здесь: http://phpclub.ru/mysql/doc/char.html. А такая ли уж великая проблема перемещение записи, если есть возможность огромной экономии пространства? там же могут быть десятки раз в случае массива строк сильно различающихся длин.
|
|||
25
Torquader
11.01.17
✎
12:28
|
(24) У версионников, типа FireBird действительно так - у них при изменении даже одного поля пишется новая версия записи и в другое место.
MySql версионником не является, так что в режиме хранилища у него должны быть записи одинаковой длины. Хотя, у него есть MemoryDb, то есть хранение данных в памяти - там, вполне вероятно, что всё зависит от длины строк, и очень велика вероятность, что строки вообще хранятся отдельно от основной записи. И что касается "переменного хранения", то его смысл в экономии количества передаваемых байтов в процессе обработки - система просто свёртывает все строки переменной длины и получает запись меньшего размера, но в файле выделяется стандартный максимальный размер, просто запись располагается в начале выделенного блока. P.S. В описании типа данных FireBird было явно сказано, что в случае применения UTF-8 под каждый символ выделяется 3 байта. Правда, если внимательно читать, то становится понятно, что разницы между CHAR и VARCHAR там нет - просто количество байт рассчитывается от количества символов. Что касается MySql, то у него есть совершенно разные модели хранения, и похоже, что в ISAM действительно переменный размер записи. http://www.mysql.ru/docs/man/MyISAM.html Про это здесь написано "свободный блок может быть получен при обновлении записи". |
|||
26
Это_mike
11.01.17
✎
12:30
|
(18) для чар служебной информации не содержится вообще. а еще у тебя есть скрытая служебная колонка.
|
|||
28
Fragster
гуру
11.01.17
✎
12:54
|
SELECT Avg( length(поле) )
FROM таблица |
|||
29
mistеr
11.01.17
✎
14:30
|
(0) Покажи CREATE TABLE.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |