您的位置:首页 > 数据库

如何访问数据库中的数据

2016-07-15 20:51 225 查看

数据表的基本结构

    一张新表被创建的时候,系统将在磁盘中分配一段以8K为单位的连续空间,当字段的值从内存写入磁盘时,就在这一既定空间随机保存,当一个8K用完的时候,数据库指针会自动分配一个8K的空间。每个8K空间被称为一个数据页,又称页面或者数据页面,并分配从0-7的页号,每个文件的第0页记录引导信息,叫文件头;每8个数据页(64K)的组合形成扩展区,称为扩展。全部数据页的组合形成堆。
    SQL Server规定不能跨越数据页,所以,每行记录的最大数据量只能为8K。这也是char和varchar这两种字符串类型容量要限制在8K以内的原型,存储超过8K的数据应使用text类型,实际上,text类型的字段值不能直接录入和保存,它只是存储一个指针,指向由若干8K的文本数据页所组成的扩展区,真正的数据正是放在这些数据页中的。
    页面有空间页面和数据页面分。当一个扩展区的8个数据页中既包含了空间页面又包括了数据或索引页面时,称为混合扩展,每张表都以混合扩展开始;反之,称为一致扩展,专门保存数据及索引信息。表被创建时,SQL
Server在混合扩展中为其分配至少一个数据页面,随着数据量的增长,SQL Server可即时在混合扩展中分配出7个页面,当数据超过8个页面时,则从一致扩展中分配数据页面。
   空间页面专门负责数据空间的分配和管理,包括:PFS页面:记录一个页面是否已分配、位于混合扩展还是一致扩展以及页面上还有多少可用空间等信息;GAM页面和SGAM页面:用来记录空闲的扩展或含有空闲页面的混合扩展的位置。SQL Server综合利用这三种类型的页面文件在必要时为数据表创建新空间。
    数据页或索引页则专门保存数据及索引信息,SQL Server使用4种类型的数据页面来管理表或索引:它们是IAM页、数据页、文本/图像也和索引页。
    在WINDOWS中,我们对文件执行的每一步操作,在磁盘上的物理位置只有系统才知道;SQL Server沿袭了这种工作方式,在插入数据的过程中,不但每个字段值在数据页面中的保存位置是随机的,而且每个数据页面在“堆”中的排列位置也只有系统才知道。
    因为OS之所以能管理DISK,是因为在系统启动时首先加载了文件分配表:FAT(File Allocation Table),正是由它管理文件系统并记录对文件的一切操作,系统才得以正常运行;同理,作为管理系统级的SQL Server,也有这样张类似FAT的表存在,是索引分布映像页IAM。
    IAM的存在,使SQL Server对数据表的物理管理有了可能。
    IAM页从混合扩展中分配,记录了8个初识页面的位置和该扩展区的位置,每个IAM页面能管理512,000个数据页面,如果数据量太大,SQL Server也可以增加更多的IAM页,可以位于文件的任何位置。第一个IAM页被称为FirstIAM,其中记录以后的IAM页的位置。  

SqlServer怎样访问没有建立任何索引的数据表

   数据值被写进数据页时,由于每一行记录之间没有特定的排列顺序,所以行与行的顺序就是随机无序的,而表中的数据页也就是无序的,那么表中所有数据页就形成了“堆”。一张没有索引的数据表,就像一个只有书柜而没有索引卡片柜的图书馆,书库里面塞满了一堆乱七八糟的图书。当读者对管理员提交查询请求后,管理员就一头钻进书库,对照查找内容从头开始一架一柜的逐本查找,运气好的话,在第一个书架的第一本书就找到了,运气不好的话,要到最后一个书架的最后一本书才找到。
    SQL Server在接到查询请求的时候,首先会分析系统视图sysindexes中的索引标识符(indid:index ID)字段的值,如果该值为0,表示这是一张数据表而不是索引表,SQLS就会使用sysindexes表的另一个字段——也就是在前面提到过的FirstIAM值中找到该表的IAM页链——也就是所有数据页集合。这就是对一个没有建立索引的数据表进行数据查找的方式,是不是很没效率?对于没有索引的表,对于一“堆”这样的记录,SQLS也只能这样做,而且更没劲的是,即使在第一行就找到了被查询的记录,SQLS仍然要从头到尾的将表扫描一次。这种查询称为“遍历”,又叫“表扫描”。

SQLS怎样访问建立了非聚集索引的数据表:

    非聚集索引可以建多个具有B树结构,其叶级节点不包含数据页,只包含索引行。假定一个表中只有非聚集索引,则每个索引行包含了非聚集索引键值以及行定位符(ROW ID,RID),他们指向具有该键值得数据行。每个RID由文件ID、页编号和在页中行的编号组成。当sysindexes中的字段indid的值在2-250之间时,意味着表中存在非聚集索引页。此时,SQL
Server调用ROOT字段的值指向非聚集索引B树的ROOT,在其中查找与被查询最相近的值,根据这个值找到在非叶级节点中的页号,然后在叶级节点相应的页面中找到该值的RID,最后根据这个RID在heap中定位所在的页和行并返回到查询端。
    例如:假定在Lastname上建立了非聚集索引,则执行Select * From Member Where Lastname=’Ota’时,查询过程是:

    ①SQLS 查询INDID值为2;
    ②立即从根出发,在非叶级节点中定位最接近Ota的值“Martin”,并查到其位于叶级页面的第61页;
    ③仅在叶级页面的第61 页的Martin下搜寻Ota的RID,其RID显示为N∶706∶4,表示Lastname字段中名为Ota的记录位于堆的第707页的第4行,N表示文件的ID值,与数据无关;
    ④根据上述信息,SQLS立马在堆的第 707页第4行将该记录“揪”出来并显示于前台(客户端)。视表的数据量大小,整个查询过程费时从百分之几毫秒到数毫秒不等。

SQLS怎样访问建立了聚集索引的数据表:

    在上一篇博客中提到聚集索引的物理存储顺序和索引顺序完全相同,所以在聚集索引中索引的索引键值也就是具体的数据页。它的原理和非聚集索引的查询类似。
例:假定在Lastname字段上建立了聚集索引,则执行Select * From Member Where Lastname=’Ota’时,查询过程是:
    ①SQLS查询INDID值为1,这是在系统中只建立了聚集索引的标志;
    ②立即从根出发,在非叶级节点中定位最接近Ota的值“Martin”,并查到其位于叶级页面的第120页;
    ③在位于叶级页面第120页的Martin下搜寻到Ota条目,而这一条目已是数据记录本身;
    ④将该记录返回客户端。

SQLS怎样访问既有聚集索引、又有非聚集索引的数据表:

    非聚集索引的情况下,每个叶级节点所指向的是该聚集索引的索引键值,即数据记录本身。

例:假设聚集索引建立在Lastname上,而非聚集索引建立在Firstname上,当执行Select * From Member Where Firstname=’Mike’时,查询过程是:
    ①SQLS查询INDID值为2;
    ②立即从根出发,在Firstname的非聚集索引的非叶级节点中定位最接近Mike的值“Jose”条目;
    ③从Jose条目下的叶级页面中查到Mike逻辑位置——不是RID而是聚集索引的指针;
    ④根据这一指针所指示位置,直接进入位于Lastname的聚集索引中的叶级页面中到达Mike数据记录本身;
    ⑤将该记录返回客户端。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: