----------------------------------------------------------------------------
---- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
---- 转载务必注明原始出处 : http://blog.csdn.net/andkylee
---- 关键字: 字段 增加 删除 日志 内部 internals
----------------------------------------------------------------------------
分析一下给表增加字段时sybase数据库的内部处理过程。
表原来的结构:
create table t(id int, col1 varchar(30))
向表中插入数据:
测试表t的object_id是:
1> select object_id('t')
2> go
-----------
608002166
利用dbcc log分析数据库的日志,可以看出上面的四条insert语句对应了四个单独的事务。因为sybase中默认是隐式提交的。
四条记录的页号和偏移分别是:
row1. pageno=801 offset=32
row2. pageno=801 offset=44
row3. pageno=801 offset=56
row4. pageno=801 offset=68
接着,向表中添加一个identity字段。
再利用dbcc log分析日志,我们可以看出在这四行数据上面发生了延迟更新(op=6,INSID在日志类型中是延迟更新的意思!)。
每行数据的页号和偏移变成了:
row1. pageno=801 offset=32
row2. pageno=801 offset=49
row3. pageno=801 offset=66
row4. pageno=801 offset=83
比较一下前后的各行的偏移量。我们发现:第一行没有移动,第二行向下移动了5(49-44)字节,第三行向下移动了10字节,第四行向下移动了15字节(83-68)。也就是说,每行增加了5个字节的数据。5个字节是因为:int类型占用4个字节再加一个字节的长度。
关于alter table add语法方面的
在向表添加列时是不能够添加not null 列的。错误如下所示:
1. 只能添加为空的字段。
2. 但是,本文前面的向表添加identity类型的int 非空字段却可以。alter table t add col2 int identity not null却可以。
3. 这似乎和SQL标准中的不太一致。
4. 分析page:801页面上的数据。发现最后添加的identity列居然是作为可变长字段进行存储的。字段col即使被定义为非空,但是物理存储上却是作为可变长存储的。因为是varchar类型。
注意: 后来我通过试验发现有一种例外情况。就是新增一个非空列的时候对这列指定默认值,就可以成功增加这列。
比如:alter table test add COLC char(1) default "0" not null
这条语句就能够成功执行!
删除表上的字段的时候报错:
报错的原因是表t所在的数据库testdb没有打开select into buklcopy选项。
打开testdb的select into/bulkcopy/pllsort 选项
再次执行删除列的操作,可以执行成功!
删除完col2之后,再次分析一下dbcc log的结果。
发现背后进行的操作有三步:
第一:删除表t在systabstats上的统计信息并重建;
第二:删除在系统表sysstatistics,sysobjects,syscolumns,sysindexes,syspartitions上对应记录的索引然后重建;
第三:更新在系统表sysstatistics,sysobjects,syscolumns,sysindexes,syspartitions上对应记录的信息。
删除表上的列的过程的日志信息,如下:
有兴趣的可以自己分析一下。