为什么这些表大小相同?

时间:2011-04-27 14:56:27

标签: mysql sql

当我遇到一些有趣的东西时,我试图测量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是用于测量表的真实大小的错误工具,在这种情况下,可接受的答案会指出我正确的方向来实际测量这些表。 / p>

编辑:

我可以使用两个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 个答案:

答案 0 :(得分:1)

data_length列是操作系统分配的硬盘空间大小  对于一张桌子。

mysql数据库页面大小可配置默认为16KB,三个表的数据可能使用相同的页面,所以data_length是相同的!!

编辑:

innodb引擎的默认页面大小是16KB,我不知道其他引擎的大小

答案 1 :(得分:1)

我找到了解决这个问题的方法以及一些解释。

在十六进制编辑器中查看表结构后(在我的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

使用来自Neo链接的信息,我能够解码这一行:

  • fd记录标题位。
  • 01000000整数值“1”(小端)
  • 0000浪费空间!
  • fd记录标题位。
  • 02000000整数值“2”(小端)
  • 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

也就是说,它使用正确的尺寸。

答案 2 :(得分:-1)

需要注意的一点是,括号中的数字不会影响该列的大小,即INT(4)在存储方面与INT(11)的大小相同,括号中的所有数字都是用空格填充返回的值,使其填充11或4个字符。

我怀疑如果你真的想要计算表的大小,你需要查看MySQL文件本身,看看它们是如何存储的。所有数据都存储在/ var / lib / mysql / - ibdata& ib_logfile是主要文件。在文本编辑器中打开它(注意 - 根据数据库的大小,此文件可能很大..也不要修改此文件!!)

所有表格和单元格都存储在此处,但它们没有被删除,因此很难看到一列结束和下一个列开始的位置 - 它都是基于您尝试建立的数据大小。如果你知道表格中的数据,你应该能够计算出结构。

编辑:我认为这些文件中的一些数据可能以十六进制存储,所以如果它没有立即有意义,请尝试使用十六进制编辑器。