下面数据仅测试数字类型的存储
我也不知道这样的测试方法是否本身就有问题,希望知情者赐教。
int数据是如何存储的?
Myisam引擎,5.1.59-community-log版本1:测试最简单的INT,单个字段
mysql> create table test (id int);
Query OK, 0 rows affected (0.01 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 0 Oct 11 23:29 test.MYD
mysql> insert into test values(2);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 7 Oct 11 23:30 test.MYD
mysql>
#插入一条记录,占用了7个字节。
#用UltraEdit打开这个文件查看,内容如下:
FD 02 00 00 00 00 00 #16进制显示的,第二个字节存储的是数据。
猜的(第一位FD是记录开始标志位,2-5位是数据位,6-7是记录结束标志)
如果只有一个INT字段,那么一条记录就比标准的4字节,多出了3个字节。再测试2个字段的
mysql> drop table test;
Query OK, 0 rows affected (0.00 sec)mysql> create table test (id int,a tinyint);
Query OK, 0 rows affected (0.03 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 0 Oct 11 23:37 test.MYD
mysql> insert into test values(4,5);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 7 Oct 11 23:37 test.MYD
mysql> 2个字节,一条记录,也是占用7个字节
#用UltraEdit打开这个文件查看,内容如下:
F9 04 00 00 00 05 00
猜的(第1位变成F9了,第2-5位是第一个字段的数据位,第6位是第2个字段的数据位,第7位是记录结束位)再测试3个字段的
mysql> drop table test;
Query OK, 0 rows affected (0.00 sec)mysql> create table test (id int,a tinyint,b bigint);
Query OK, 0 rows affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 0 Oct 11 23:42 test.MYD
mysql> insert into test values(4,5,6);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 14 Oct 11 23:42 test.MYD
mysql>
#用UltraEdit打开这个文件查看,内容如下:
F1 04 00 00 00 05 06 00 00 00 00 00 00 00
猜的(第1位F1,2-5是第一个字段的数据位,第6位是第二个字段的数据位,第7-14位是第三个字段的数据位。记录开始位变了,没有结束位了)
3个字段的数据存储大小符合规则。1+4+1+8=14
第一位是记录开始标志位,这个基本肯定,而且标示了字段的数据类型。行记录字节数低于7字节的,用00补全,占用7字节。超过7字节的,按实际字段字节数存储。
用4个字段验证,字节数也是正确的。
我也不知道这样的测试方法是否本身就有问题,希望知情者赐教。
int数据是如何存储的?
Myisam引擎,5.1.59-community-log版本1:测试最简单的INT,单个字段
mysql> create table test (id int);
Query OK, 0 rows affected (0.01 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 0 Oct 11 23:29 test.MYD
mysql> insert into test values(2);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 7 Oct 11 23:30 test.MYD
mysql>
#插入一条记录,占用了7个字节。
#用UltraEdit打开这个文件查看,内容如下:
FD 02 00 00 00 00 00 #16进制显示的,第二个字节存储的是数据。
猜的(第一位FD是记录开始标志位,2-5位是数据位,6-7是记录结束标志)
如果只有一个INT字段,那么一条记录就比标准的4字节,多出了3个字节。再测试2个字段的
mysql> drop table test;
Query OK, 0 rows affected (0.00 sec)mysql> create table test (id int,a tinyint);
Query OK, 0 rows affected (0.03 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 0 Oct 11 23:37 test.MYD
mysql> insert into test values(4,5);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 7 Oct 11 23:37 test.MYD
mysql> 2个字节,一条记录,也是占用7个字节
#用UltraEdit打开这个文件查看,内容如下:
F9 04 00 00 00 05 00
猜的(第1位变成F9了,第2-5位是第一个字段的数据位,第6位是第2个字段的数据位,第7位是记录结束位)再测试3个字段的
mysql> drop table test;
Query OK, 0 rows affected (0.00 sec)mysql> create table test (id int,a tinyint,b bigint);
Query OK, 0 rows affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 0 Oct 11 23:42 test.MYD
mysql> insert into test values(4,5,6);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
-rw-rw---- 1 mysql mysql 14 Oct 11 23:42 test.MYD
mysql>
#用UltraEdit打开这个文件查看,内容如下:
F1 04 00 00 00 05 06 00 00 00 00 00 00 00
猜的(第1位F1,2-5是第一个字段的数据位,第6位是第二个字段的数据位,第7-14位是第三个字段的数据位。记录开始位变了,没有结束位了)
3个字段的数据存储大小符合规则。1+4+1+8=14
第一位是记录开始标志位,这个基本肯定,而且标示了字段的数据类型。行记录字节数低于7字节的,用00补全,占用7字节。超过7字节的,按实际字段字节数存储。
用4个字段验证,字节数也是正确的。
相关信息看这个帖子。
-rw-rw---- 1 mysql mysql 0 Oct 11 23:42 test.MYD
mysql> insert into test values(4,5,6);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/DB |grep test.MYD
mysql> drop table if exists test;
Query OK, 0 rows affected (0.00 sec)mysql> create table test (id int not null,a tinyint not null,b bigint not null, primary key(id)) engine = MyISAM;
delete from test where id = 2;
system ls -al /var/lib/mysql/test/test.MYD
system java Hex /var/lib/mysql/test/test.MYD
Query OK, 0 rows affected (0.05 sec)mysql> system ls -al /var/lib/mysql/test/test.MYD
-rw-rw---- 1 mysql mysql 0 2011-10-14 20:58 /var/lib/mysql/test/test.MYD
mysql> system java Hex /var/lib/mysql/test/test.MYDmysql> insert into test values (1,4,7);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/test/test.MYD
-rw-rw---- 1 mysql mysql 14 2011-10-14 20:58 /var/lib/mysql/test/test.MYD
mysql> system java Hex /var/lib/mysql/test/test.MYD
FF 01 00 00 00 04 07 00 00 00 00 00 00 00
mysql> insert into test values (2,5,8);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/test/test.MYD
-rw-rw---- 1 mysql mysql 28 2011-10-14 20:58 /var/lib/mysql/test/test.MYD
mysql> system java Hex /var/lib/mysql/test/test.MYD
FF 01 00 00 00 04 07 00 00 00 00 00 00 00 FF 02 00 00 00 05 08 00 00 00 00 00 00 00
mysql> insert into test values (3,6,9);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/test/test.MYD
-rw-rw---- 1 mysql mysql 42 2011-10-14 20:58 /var/lib/mysql/test/test.MYD
mysql> system java Hex /var/lib/mysql/test/test.MYD
FF 01 00 00 00 04 07 00 00 00 00 00 00 00 FF 02 00 00 00 05 08 00 00 00 00 00 00 00 FF 03 00 00 00 06 09 00 00 00 00 00 00 00
mysql> delete from test where id = 2;
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/test/test.MYD
-rw-rw---- 1 mysql mysql 42 2011-10-14 20:58 /var/lib/mysql/test/test.MYD
mysql> system java Hex /var/lib/mysql/test/test.MYD
FF 01 00 00 00 04 07 00 00 00 00 00 00 00 00 FF FF FF FF FF FF 00 00 00 00 00 00 00 FF 03 00 00 00 06 09 00 00 00 00 00 00 00
mysql> insert into test values (100,5,55555);
Query OK, 1 row affected (0.00 sec)mysql> system ls -al /var/lib/mysql/test/test.MYD
-rw-rw---- 1 mysql mysql 42 2011-10-14 21:04 /var/lib/mysql/test/test.MYD
mysql> system java Hex /var/lib/mysql/test/test.MYD
FF 01 00 00 00 04 07 00 00 00 00 00 00 00 FF 64 00 00 00 05 03 D9 00 00 00 00 00 00 FF 03 00 00 00 06 09 00 00 00 00 00 00 00
mysql>第一个字节FF是标志位,而且FF表示该行有效,00表示被“物理”删除。这行可能会在下次insert时被重复利用
00 FF FF FF FF FF FF 00 00 00 00 00 00 00标志位变00可以理解,但是字段位置为什么是这个样子?
如果有空洞,就先插入到空洞里面,如果没用,则写入文件尾端。非常需要shine333这样的人才来一起探讨。
数据位上的数字全部被FF替换了,非00的数据位之间的也被FF替换了。
可能它这么替换,能够刚快的找到删除后的空洞吧,我猜的。
仅仅是把bigint的最左面一位改成FF
字节都是从右到左,所以最后看上去全是00,那是因为你的测试数据较小。窃以为,如果是varchar,在每行该字段的开始位置,应该就是记录这个字段长度的字节,然后才是数据位。
int,tiny,bigint都是定长字段,所占字节为4,1,8,你测试的例子总长度已经超过7,到13了,所以没用在后面补00 ,如果不用bigint,就只有5字节,就会在后面补0另外找到了liunx下以16进制查看你文件的方法如下:
[root@localhost DB]# hexdump -C rows.MYD
00000000 00 ff ff ff ff ff ff 00 00 00 00 00 00 00 f1 0a |................|
00000010 00 00 00 07 08 00 00 00 00 00 00 00 |............|
0000001c
看这个帖子
http://topic.csdn.net/u/20111012/09/6110254b-a68e-49d9-a18a-a061e9bebe89.html?96807