Почему эти таблицы одинакового размера? - PullRequest
4 голосов
/ 27 апреля 2011

Я пытался измерить разницу между TINYINT и INT, когда наткнулся на что-то интересное. Для таблиц с небольшим количеством столбцов выбор типа данных не влияет на размер таблицы.

Версия сервера: 5.1.41-3ubuntu12.10 (Ubuntu)

Пример:

mysql> describe tinyint_test;
+----------+------------+------+-----+---------+-------+
| Field    | Type       | Null | Key | Default | Extra |
+----------+------------+------+-----+---------+-------+
| id       | int(11)    | YES  |     | NULL    |       |
| test_int | tinyint(4) | YES  |     | NULL    |       |
+----------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> describe tinyint_id_test;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | tinyint(4) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> describe int_test;
+--------+---------+------+-----+---------+-------+
| Field  | Type    | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| not_id | int(11) | YES  |     | NULL    |       |
+--------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from tinyint_test;
+------+----------+
| id   | test_int |
+------+----------+
|    1 |        1 |
|    2 |        2 |
|    3 |      127 |
|   10 |       50 |
+------+----------+
4 rows in set (0.00 sec)

mysql> select * from tinyint_id_test;
+------+
| id   |
+------+
|    1 |
|    2 |
|  127 |
|   50 |
+------+
4 rows in set (0.00 sec)

mysql> select * from int_test;
+--------+
| not_id |
+--------+
|      1 |
|      2 |
|    127 |
|     50 |
+--------+
4 rows in set (0.00 sec)

mysql> SELECT TABLE_NAME, DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA like '%test%';
+-----------------+-------------+
| TABLE_NAME      | DATA_LENGTH |
+-----------------+-------------+
| int_test        |          28 |
| tinyint_id_test |          28 |
| tinyint_test    |          28 |
+-----------------+-------------+
3 rows in set (0.00 sec)

Я смутно подозреваю, что в каждой строке может быть внутренний столбец или что минимальный размер данных для данной строки должен быть не меньше размера полного INT, но ни одно из этих подозрений на самом деле не объясняет происходящее здесь. То, что может иметь место, - мой выбор DATA_LENGTH - это неправильный инструмент для измерения истинного размера таблиц, и в этом случае приемлемый ответ укажет мне правильное направление для фактического измерения этих таблиц.

EDIT:

Я могу создать таблицу другого размера, используя два INT:

mysql> describe int_id_test;
+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| id       | int(11) | YES  |     | NULL    |       |
| test_int | int(11) | YES  |     | NULL    |       |
+----------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> select * from int_id_test;
+------+----------+
| id   | test_int |
+------+----------+
|    1 |        1 |
|    2 |        2 |
|    3 |      127 |
|   10 |       50 |
+------+----------+
4 rows in set (0.00 sec)

mysql> SELECT TABLE_NAME, DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA like '%test%';
+-----------------+-------------+
| TABLE_NAME      | DATA_LENGTH |
+-----------------+-------------+
| int_id_test     |          36 |
| int_test        |          28 |
| tinyint_id_test |          28 |
| tinyint_test    |          28 |
+-----------------+-------------+
4 rows in set (0.01 sec)

Ответы [ 3 ]

1 голос
/ 27 апреля 2011

столбец data_length указывает, сколько места на жестком диске выделяет операционная система. для стола.

Размер страницы базы данных mysql настраивается по умолчанию: 16 КБ, данные трех таблиц могут использовать одни и те же страницы, поэтому длина_данных одинакова !!

редактирование:

Размер страницы по умолчанию для движка innodb составляет 16 КБ, я не знаю этот размер для других движков

1 голос
/ 28 апреля 2011

Я нашел способ обойти эту проблему, а также кое-что из объяснения.

После просмотра структуры таблицы в шестнадцатеричном редакторе (на моих машинах Linux они были расположены в /var/lib/mysql/[DATABASE NAME]/[TABLE NAME].MYD),Я обнаружил, что во всех случаях записи создавались с использованием минимум 7 байтов для строки, независимо от используемых типов данных.Любые дополнительные байты, которые не использовались таблицей, были обнулены.

Вот пример с меньшим набором данных для иллюстрации:

mysql> describe int_test_2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from int_test_2;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

Глядя на этого парня в шестнадцатеричном редакторе,мы видим:

fd01 0000 0000 00fd 0200 0000 0000

Используя информацию из ссылки Нео, я смог расшифровать эту строку:

  • fd Запись битов заголовка.
  • 01000000 Целочисленное значение "1" (младший порядковый номер)
  • 0000 Потерянное пространство!
  • fd Запись битов заголовка.
  • 02000000 Целочисленное значение "2" (little endian)
  • 0000 Потраченное впустую пространство!

Однако обратите внимание на следующее:

mysql> alter table int_test_2 MAX_ROWS=50000000, AVG_ROW_LENGTH=4;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

Теперь файл MYD выглядит следующим образом:

fd01 0000 00fd 0200 0000

То есть используются правильные размеры.

0 голосов
/ 27 апреля 2011

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

Я подозреваю, что если вы действительно хотите определить размер таблиц, вам нужно будет заглянуть в сам файл MySQL и посмотреть, как они хранятся. Все данные хранятся в / var / lib / mysql / - ibdata & ib_logfile - это основные файлы. Откройте это в текстовом редакторе (Внимание - этот файл может быть ОГРОМНЫМ в зависимости от размеров ваших баз данных .. также НЕ изменять этот файл !!)

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

Редактировать: Я думаю, что некоторые данные в этих файлах могут храниться в шестнадцатеричном формате, поэтому, если это не имеет смысла, попробуйте шестнадцатеричный редактор.

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