SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 06.03.2010 02:30:32

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Какой смысл делать VARCHAR(<255)?

Если все равно одна и та же информация будет занимать одинаковое место?
Почему во всех случаях не делать VARCHAR(255)?

Есть ли хоть какая-нибудь разница? (может быть, сервер будет поплотнее располагать данные на диске, если увидит, что поле короче, и из-за этого ему будет потом легче читать? или что-нибудь подобное вообще...)

Неактивен

 

#2 06.03.2010 02:33:21

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Какой смысл делать VARCHAR(<255)?

Например, индекс будет по-умолчанию того же размера, что и определение VARCHAR().

Неактивен

 

#3 06.03.2010 03:11:26

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

А что разве индекс в своих ветвях будет короткие строки нулями дописывать?

Неактивен

 

#4 06.03.2010 09:16:39

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Какой смысл делать VARCHAR(<255)?

Эксперимент показал, что нулями дописывать не будет, по крайней мере при хранении на диске в MyISAM. Возможно, при использовании он дописывает нулями в памяти

Неактивен

 

#5 06.03.2010 12:56:12

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

Возможно, при использовании он дописывает нулями в памяти

А как это можно точно узнать?
(просто хочется как-то раз и навсегда разрешить вопрос о том, стоит ли придумывать длину колонки меньше 255 или нет; указывать всегда 255 удобно, поскольку избавляет от возможных проблем, если длина окажется недостаточной).

Неактивен

 

#6 06.03.2010 17:09:24

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Какой смысл делать VARCHAR(<255)?

А если длина будет больше 255, то все равно не влезет. Индекс никто не запрещает делать только на начало колонки, чтобы не было проблем из-за его излишней длины - это совершенно очевидно, что часть алгоритмов используют индекс как запись фиксированного размера, хотя не посмотрев в исходники точно сказать какие именно не получится.

Неактивен

 

#7 07.03.2010 02:59:00

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

Да, мне тут тоже мысль пришла, что делать индекс по всему полю VARCHAR, даже если оно меньше 255 символов, - это обычно ни к чему.
Отсюда вывод, что раз индекс всё равно делается не по всему полю, а по левой части, само поле можно смело выставлять в 255 либо в 65535.

Неактивен

 

#8 07.03.2010 05:08:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Какой смысл делать VARCHAR(<255)?

Ну, вспомни еще про таблички MEMORY тогда. Они хранят их как CHAR().

Неактивен

 

#9 07.03.2010 12:42:07

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

Вот про это я забыл smile
Да, важно.

Кстати. Если MEMORY-таблицу делать как

CREATE TABLE ...
SELECT ... FROM tbl

при этом у tbl есть столбец VARCHAR(255), но самая длинная строка там фактически - например, 100, CHAR-столбец в MEMORY-таблице будет 100 или 255?

Неактивен

 

#10 07.03.2010 18:59:13

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Какой смысл делать VARCHAR(<255)?

Ну, ты бы и сам мог проверить wink

[aurica] root test > create table a (a varchar(255));
Query OK, 0 rows affected (0.36 sec)

[aurica] root test > insert a values ('blah');
Query OK, 1 row affected (0.00 sec)

[aurica] root test > create table b select * from a;
Query OK, 1 row affected (0.06 sec)
Records: 1  Duplicates: 0  Warnings: 0

[aurica] root test > alter table b engine=memory;
Query OK, 1 row affected (0.07 sec)
Records: 1  Duplicates: 0  Warnings: 0

[aurica] root test > show create table b;
+-------+-----------------------------------------------------------------------------------------+
| Table | Create Table                                                                            |
+-------+-----------------------------------------------------------------------------------------+
| b     | CREATE TABLE `b` (
  `a` varchar(255) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

[aurica] root test > show table status like 'b'\G
*************************** 1. row ***************************
           Name: b
         Engine: MEMORY
        Version: 10
     Row_format: Fixed
           Rows: 1
Avg_row_length: 768
    Data_length: 129696
Max_data_length: 16690176
   Index_length: 0
      Data_free: 0
Auto_increment: NULL
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

Неактивен

 

#11 08.03.2010 15:32:06

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Какой смысл делать VARCHAR(<255)?

А как посмотреть show table status для временной таблицы? Вроде бы в этом случае varchar() конвертится в char() максимальной длины, указанной при объявлении varchar().


И ещё хотел убедиться, что в случае использования полей типа TEXT, BLOB для временных таблиц используется не HEAP engine, а MyISAM и данные пишутся на диск.


test >create table a (q text);
Query OK, 0 rows affected (0.17 sec)

test >insert into a values('blah');
Query OK, 1 row affected (0.44 sec)

test >flush status;
Query OK, 0 rows affected (0.00 sec)

test >create temporary table b select * from a;
Query OK, 1 row affected (0.48 sec)
Records: 1  Duplicates: 0  Warnings: 0

test >show session status like 'created%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0     |
| Created_tmp_files       | 0     |
| Created_tmp_tables      | 0     |
+-------------------------+-------+
3 rows in set (0.00 sec)
 

А он мне пишет, что создано 0 временных таблиц. В чем прикол?

Неактивен

 

#12 09.03.2010 14:00:04

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Какой смысл делать VARCHAR(<255)?

Если ты внимательно посмотришь на вот это, то обнаружишь, что там считаются
только внутренние временные таблицы, т.е. те, которые используются, например,
при большом join без индексов.

Неактивен

 

#13 11.03.2010 03:01:51

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

paulus написал:

Ну, ты бы и сам мог проверить

Самостоятельно не допёр вот до этого:

alter table b engine=memory

А так всё наглядно, спасибо.
Только не понятно, откуда Data_length: 129696 ? Там ведь одна запись длиной в четыре буквы.
И Avg_row_length тоже должно быть не 768, а 256*2*4 - 2048.

Неактивен

 

#14 11.03.2010 12:39:53

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Какой смысл делать VARCHAR(<255)?

Так UTF8, три байта, 256*3 = 768
А память выделяется страничками, тут уж никуда не денешься.

Неактивен

 

#15 12.03.2010 02:05:27

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

Так UTF8, три байта, 256*3 = 768

Да, забыл, что английские буквы. Если три байта - ты, наверное, вставлял 'bla', а не 'blah' (а то бы было четыре).

память выделяется страничками

[раз уж затронули эту тему] Всегда хотел узнать, что есть такое страничка и зачем вообще хранить данные по страничкам?

Неактивен

 

#16 12.03.2010 12:00:11

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Какой смысл делать VARCHAR(<255)?

Я вставлял именно blah. Мог бы вставить blahminor, размер бы не поменялся. Вопрос
на понимание: почему? Кажется, ты путаешь некоторые размеры wink

Страничка — это некоторый блок памяти, работа с которым идет атомарным образом.
Просто удобный способ работы с данными. Допустим, у тебя есть твой шаблонизатор.
Для того, чтобы распарсить какой-то блок, ты берешь всю структуру загруженных
шаблонов и работаешь с ней. Если бы твое приложение было многопоточным (например,
держало все шаблоны в памяти), то тебе приходилось бы ставить mutex на обращении
к дереву. Потом бы ты обнаружил, что блокировка всего дерева неэффективна, т.к.
это эффективно сводит многопоточное приложение к однопоточной работе. Ты решишь
брать mutex на куски деревьев. Потом этого мало и ты решишь, что надо блокировать
куски кусков — странички wink

Неактивен

 

#17 14.03.2010 04:13:17

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

Кажется, ты путаешь некоторые размеры

Видимо, да :0
Поясни, пожалуйста.

Про страницы: т.е в рамках одной страницы получается все-таки однопоточность?

Неактивен

 

#18 14.03.2010 11:45:28

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Какой смысл делать VARCHAR(<255)?

1. Кодировка utf8: 1-3 байта на символ.
2. VARCHAR(255): 0-255 символов для хранения информации + 1 символ для
    хранения живой длины строки
3. Переделываем в MEMORY и 2 пункт эффективно выделяет полную память
    в 256 * 3 байт. Вне зависимости от того, что там хранится.

--

Ну, так есть, например, в BDB. В InnoDB пошли еще дальше и ставят
блокировки на строки (а страничка стала некоторым атомарным куском в
таблице; например, если ты меняешь данные на страничке одной транзакцией
при том, что другие транзакции находятся в уровне изоляции выше, чем
READ UNCOMMITTED и читали эту страничку, страничка дублируется и
изменения применяются к дублю), но оперируются данные все равно
постранично, т.к. это удобно.

Неактивен

 

#19 16.03.2010 17:19:09

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Какой смысл делать VARCHAR(<255)?

Да, я че-то забыл, что на один символ нужно 1-3 байта,а не 256*1-3 smile (бывают иногда такие помутнения)

В общем, ясно, спасибо.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson