下面数据仅测试数字类型的存储
我也不知道这样的测试方法是否本身就有问题,希望知情者赐教。
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个字段验证,字节数也是正确的。

解决方案 »

  1.   

    http://topic.csdn.net/u/20111012/09/6110254b-a68e-49d9-a18a-a061e9bebe89.html?seed=194308995&r=75946793#r_75946793和这个帖子的楼主探讨后作的实验。
    相关信息看这个帖子。
      

  2.   

    确实,精神可嘉,估计与系统、MYSQL的文件分配有关
      

  3.   

    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
      

  4.   

     & study..... 
     
      

  5.   

    呵呵,我也搞一个。HOLD ON
      

  6.   

    可能和原帖讨论有点不一致
    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时被重复利用
      

  7.   

    要开会,还没总结完。先抛出一个问题(可以通过其他表结构验证)。为什么删除的时候,FF 02 00 00 00 05 08 00 00 00 00 00 00 00
    00 FF FF FF FF FF FF 00 00 00 00 00 00 00标志位变00可以理解,但是字段位置为什么是这个样子?
      

  8.   

    第一个字节FF是标志位,而且FF表示该行有效,00表示被“物理”删除。这行可能会在下次insert时被重复利用shine333测试出了MYISAM表对于空洞的重新利用。从这个测试例子来看,当时的concurrent_insert =1
    如果有空洞,就先插入到空洞里面,如果没用,则写入文件尾端。非常需要shine333这样的人才来一起探讨。
      

  9.   


    数据位上的数字全部被FF替换了,非00的数据位之间的也被FF替换了。
    可能它这么替换,能够刚快的找到删除后的空洞吧,我猜的。
      

  10.   

    不是,主要是bigint,FF 31 DE 0B 00 01 71 B4 EA 1B 12 00 00 00 insert (777777,1,77777777777=0x12 1BEA B471)00 FF FF FF FF FF FF B4 EA 1B 12 00 00 00 delete
    仅仅是把bigint的最左面一位改成FF
      

  11.   

    忘了说一句,你前面“行记录字节数低于7字节的,用00补全,占用7字节”的论断不对int,tiny,bigint都是定长字段
    字节都是从右到左,所以最后看上去全是00,那是因为你的测试数据较小。窃以为,如果是varchar,在每行该字段的开始位置,应该就是记录这个字段长度的字节,然后才是数据位。
      

  12.   

    52楼有问题,插入在optimize之前,总是插入到空洞里面的,和concurrent_insert 参数没用关系,纠正一下。回55楼,我测试的“行记录字节数低于7字节的,用00补全,占用7字节”的论断不对,应该怎么测试呢?
    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
      

  13.   


    看这个帖子
    http://topic.csdn.net/u/20111012/09/6110254b-a68e-49d9-a18a-a061e9bebe89.html?96807
      

  14.   

    我的表结构和你不同,都是not null有pk