顶多在buffer里面会修改。数据表要么是堆表(没有聚集索引),要么是b-tree结构(有聚集索引),不会同时存在,如果按你的说法,就是同时存在,这是违反了定义

解决方案 »

  1.   

    做个试验,你就明白了:create table test(id int identity(1,1),name varchar(20))insert into test
    values('aaaaaaaaaaaaa')
    go 20
    --1.堆表
    select OBJECT_NAME(object_id) as tb_name,
           name,
           index_id,
           type_desc --堆表
    from sys.indexes
    where object_id = object_id('test')
    /*
    tb_name name index_id type_desc
    test NULL 0 HEAP
    */--2.建立聚集索引
    create clustered index cls_idx_test_id on test(id)
    --3.原来的堆表没有了,变为聚集索引
    select OBJECT_NAME(object_id) as tb_name,
           name,
           index_id,
           type_desc --聚集索引
    from sys.indexes
    where object_id = object_id('test')
    /*
    tb_name name index_id type_desc
    test cls_idx_test_id 1 CLUSTERED
    */
      

  2.   

    聚集索引以物理顺序存储
    这是其中一个最常见的误区,就是聚集索引按照物理顺序存储数据。其实想想就知道,如果真的按磁盘的物理位置存储,删改操作(有时候增加操作)会触发磁盘内数据的大面积移动和磁头的随机移动,作为一个成熟的数据库管理系统,SQLServer不会这么笨的。下面来演示一下:
    --创建测试表
    CREATE TABLE dbo.MythFive
        (
          RowID INT PRIMARY KEY CLUSTERED ,
          TestValue VARCHAR(20) NOT NULL
        );
    --注意RowID和TestValue是不对应的,3对应的是Second
    INSERT  INTO dbo.MythFive ( RowID, TestValue )
    VALUES  ( 1, 'FirstRecordAdded' );
    INSERT  INTO dbo.MythFive ( RowID, TestValue )
    VALUES  ( 3, 'SecondRecordAdded' );
    INSERT  INTO dbo.MythFive ( RowID, TestValue )
    VALUES  ( 2, 'ThirdRecordAdded' );
    GO
    --检查索引情况
    DBCC IND ('AdventureWorks2008R2', 'dbo.MythFive', 1);
    GO为了验证,这里使用DBCC PAGE来检查PageType=1即数据页的情况,我们重点关注页所在的内存位置移动(memory dump),在这个部分,显示了数据存在页中的位置。 
    DBCC TRACEON (3604);
    GO
    DBCC PAGE (AdventureWorks2008R2, 1, 140107, 2);--这个号要根据上面DBCC IND得出的号,不要直接用140107
    GO
    留意一下图中的最右边,显示数据的存放位置,是按照插入顺序,但是再回过头看看表定义,聚集索引(即本例中的主键),是按数据的大小顺序排列的,所以如果不带ORDER BY 直接SELECT 这个表,顺序应该是1、2、3,但是页中的实际数据对应起来反而是1、3、2。证明聚集索引并不是按物理顺序存放数据。