sybase中给表增加和删除字段时内部处理过程分析

来源:互联网 发布:人工智能技术体系架构 编辑:程序博客网 时间:2024/05/19 14:53

----------------------------------------------------------------------------

---- 本文为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上对应记录的信息。

 

删除表上的列的过程的日志信息,如下:

 

 

 

 

有兴趣的可以自己分析一下。