`
redis
  • 浏览: 27060 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

从2000万条开房数据谈检索

阅读更多

看到以前一个帖子 2000万条开房数据,如何快速查询(数据库优化)。(按照规矩,先把福利贴上 http://kfxx.info

 

一、引言

对数据库索引的关注从未淡出我的们的讨论,那么数据库索引是什么样的?聚集索引与非聚集索引有什么不同?希望本文对各位同仁有一定的帮助。有不少存疑的地方,诚心希望各位不吝赐教指正,共同进步。[最近首页之争沸沸扬扬,也不知道这个放在这合适么,苦劳?功劳?……]

 

 

二、B-Tree

我们常见的数据库系统,其索引使用的数据结构多是B-Tree或者B+Tree。例如,MsSql使用的是B+TreeOracleSysbase使用的是B-Tree。所以在最开始,简单地介绍一下B-Tree

 

B-Tree不同于Binary Tree(二叉树,最多有两个子树),一棵M阶的B-Tree满足以下条件:
1)每个结点至多有M个孩子;
2)除根结点和叶结点外,其它每个结点至少有M/2个孩子;
3)根结点至少有两个孩子(除非该树仅包含一个结点);
4)所有叶结点在同一层,叶结点不包含任何关键字信息;
5)有K个关键字的非叶结点恰好包含K+1个孩子;

另外,对于一个结点,其内部的关键字是从小到大排序的。以下是B-TreeM=4)的样例:

  

对于每个结点,主要包含一个关键字数组Key[],一个指针数组(指向儿子)Son[]。在B-Tree内,查找的流程是:使用顺序查找(数组长度较短时)或折半查找方法查找Key[]数组,若找到关键字K,则返回该结点的地址及KKey[]中的位置;否则,可确定K在某个Key[i]Key[i+1]之间,则从Son[i]所指的子结点继续查找,直到在某结点中查找成功;或直至找到叶结点且叶结点中的查找仍不成功时,查找过程失败。

接着,我们使用以下图片演示如何生成B-TreeM=4,依次插入1~6):
从图可见,当我们插入关键字4时,由于原结点已经满了,故进行分裂,基本按一半的原则进行分裂,然后取出中间的关键字2,升级(这里是成为根结点)。其它的依类推,就是这样一个大概的过程。

  

 

三、数据库索引

1.什么是索引

在数据库中,索引的含义与日常意义上的“索引”一词并无多大区别(想想小时候查字典),它是用于提高数据库表数据访问速度的数据库对象。
A)索引可以避免全表扫描。多数查询可以仅扫描少量索引页及数据页,而不是遍历所有数据页。
B对于非聚集索引,有些查询甚至可以不访问数据页。
C聚集索引可以避免数据插入操作集中于表的最后一个数据页。
D一些情况下,索引还可用于避免排序操作。

 

当然,众所周知,虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引。

 

 

2.索引的存储

一条索引记录中包含的基本信息包括:键值(即你定义索引时指定的所有字段的值)+逻辑指针(指向数据页或者另一索引页)。

  

当你为一张空表创建索引时,数据库系统将为你分配一个索引页,该索引页在你插入数据前一直是空的。此页此时既是根结点,也是叶结点。每当你往表中插入一行数据,数据库系统即向此根结点中插入一行索引记录。当根结点满时,数据库系统大抵按以下步骤进行分裂:
A)创建两个儿子结点
B)将原根结点中的数据近似地拆成两半,分别写入新的两个儿子结点
C)根结点中加上指向两个儿子结点的指针

 

通常状况下,由于索引记录仅包含索引字段值(以及4-9字节的指针),索引实体比真实的数据行要小许多,索引页相较数据页来说要密集许多。一个索引页可以存储数量更多的索引记录,这意味着在索引中查找时在I/O上占很大的优势,理解这一点有助于从本质上了解使用索引的优势。

 

 

3.索引的类型

A聚集索引,表数据按照索引的顺序来存储的。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。
B非聚集索引,表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,该层紧邻数据页,其行数量与数据表行数据量一致。

 

在一张表上只能创建一个聚集索引,因为真实数据的物理顺序只可能是一种。如果一张表没有聚集索引,那么它被称为堆集Heap)。这样的表中的数据行没有特定的顺序,所有的新行将被添加的表的末尾位置。

 

 

4.聚集索引

在聚集索引中,叶结点也即数据结点,所有数据行的存储顺序与索引的存储顺序一致。

  

1)聚集索引与查询操作

如上图,我们在名字字段上建立聚集索引,当需要在根据此字段查找特定的记录时,数据库系统会根据特定的系统表查找的此索引的根,然后根据指针查找下一个,直到找到。例如我们要查询“Green”,由于它介于[Bennet,Karsen],据此我们找到了索引页1007,在该页中“Green”介于[Greane, Hunter],据此我们找到叶结点1133(也即数据结点),并最终在此页中找以了目标数据行。

 

此次查询的IO包括3个索引页的查询(其中最后一次实际上是在数据页中查询)。这里的查找可能是从磁盘读取(Physical Read)或是从缓存中读取(Logical Read),如果此表访问频率较高,那么索引树中较高层的索引很可能在缓存中被找到。所以真正的IO可能小于上面的情况。

 

 

2)聚集索引与插入操作

最简单的情况下,插入操作根据索引找到对应的数据页,然后通过挪动已有的记录为新数据腾出空间,最后插入数据。

 

如果数据页已满,则需要拆分数据页(页拆分是一种耗费资源的操作,一般数据库系统中会有相应的机制要尽量减少页拆分的次数,通常是通过为每页预留空间来实现):
A在该使用的数据段(extent)上分配新的数据页,如果数据段已满,则需要分配新段。
B调整索引指针,这需要将相应的索引页读入内存并加锁。
C大约有一半的数据行被归入新的数据页中。
D
如果表还有非聚集索引,则需要更新这些索引指向新的数据页。

 

特殊情况:
A如果新插入的一条记录包含很大的数据,可能会分配两个新数据页,其中之一用来存储新记录,另一存储从原页中拆分出来的数据。
B通常数据库系统中会将重复的数据记录存储于相同的页中。
C类似于自增列为聚集索引的,数据库系统可能并不拆分数据页,页只是简单的新添数据页。

 

 

3)聚集索引与删除操作

删除行将导致其下方的数据行向上移动以填充删除记录造成的空白。

如果删除的行是该数据页中的最后一行,那么该数据页将被回收,相应的索引页中的记录将被删除。如果回收的数据页位于跟该表的其它数据页相同的段上,那么它可能在随后的时间内被利用。如果该数据页是该段的唯一一个数据页,则该段也被回收。

 

对于数据的删除操作,可能导致索引页中仅有一条记录,这时,该记录可能会被移至邻近的索引页中,原索引页将被回收,即所谓的“索引合并”。

 

 

5.非聚集索引

非聚集索引与聚集索引相比:
A叶子结点并非数据结点
B叶子结点为每一真正的数据行存储一个-指针
C叶子结点中还存储了一个指针偏移量,根据页指针及指针偏移量可以定位到具体的数据行。
D
类似的,在除叶结点外的其它索引结点,存储的也是类似的内容,只不过它是指向下一级的索引页的。

 

聚集索引是一种稀疏索引,数据页上一级的索引页存储的是页指针,而不是行指针。而对于非聚集索引,则是密集索引,在数据页的上一级索引页它为每一个数据行存储一条索引记录。

 

对于根与中间级的索引记录,它的结构包括:
A索引字段值
BRowId(即对应数据页的页指针+指针偏移量)。在高层的索引页中包含RowId是为了当索引允许重复值时,当更改数据时精确定位数据行。
C下一级索引页的指针

 

对于叶子层的索引对象,它的结构包括:
A
索引字段值
BRowId

  

1)非聚集索引与查询操作

针对上图,如果我们同样查找“Green”,那么一次查询操作将包含以下IO3个索引页的读取+1个数据页的读取。同样,由于缓存的关系,真实的IO实际可能要小于上面列出的。

 

 

2)非聚集索引与插入操作

如果一张表包含一个非聚集索引但没有聚集索引,则新的数据将被插入到最末一个数据页中,然后非聚集索引将被更新。如果也包含聚集索引,该聚集索引将被用于查找新行将要处于什么位置,随后,聚集索引、以及非聚集索引将被更新。

 

 

3)非聚集索引与删除操作

如果在删除命令的Where子句中包含的列上,建有非聚集索引,那么该非聚集索引将被用于查找数据行的位置,数据删除之后,位于索引叶子上的对应记录也将被删除。如果该表上有其它非聚集索引,则它们叶子结点上的相应数据也要删除。

 

如果删除的数据是该数所页中的唯一一条,则该页也被回收,同时需要更新各个索引树上的指针。

 

由于没有自动的合并功能,如果应用程序中有频繁的随机删除操作,最后可能导致表包含多个数据页,但每个页中只有少量数据。

 

 

6.索引覆盖

索引覆盖是这样一种索引策略:当某一查询中包含的所需字段皆包含于一个索引中,此时索引将大大提高查询性能。

 

包含多个字段的索引,称为复合索引。索引最多可以包含31个字段,索引记录最大长度为600B。如果你在若干个字段上创建了一个复合的非聚集索引,且你的查询中所需Select字段及Where,Order By,Group By,Having子句中所涉及的字段都包含在索引中,则只搜索索引页即可满足查询,而不需要访问数据页。由于非聚集索引的叶结点包含所有数据行中的索引列值,使用这些结点即可返回真正的数据,这种情况称之为索引覆盖

 

在索引覆盖的情况下,包含两种索引扫描:
A)匹配索引扫描
B)非匹配索引扫描

 

 

1)匹配索引扫描

此类索引扫描可以让我们省去访问数据页的步骤,当查询仅返回一行数据时,性能提高是有限的,但在范围查询的情况下,性能提高将随结果集数量的增长而增长。

 

针对此类扫描,索引必须包含查询中涉及的的所有字段,另外,还需要满足:Where子句中包含索引中的引导列Leading Column),例如一个复合索引包含A,B,C,D四列,则A引导列。如果Where子句中所包含列是BCD或者BD等情况,则只能使用非匹配索引扫描。

 

 

2)非配置索引扫描

正如上述,如果Where子句中不包含索引的导引列,那么将使用非配置索引扫描。这最终导致扫描索引树上的所有叶子结点,当然,它的性能通常仍强于扫描所有的数据页。

分享到:
评论

相关推荐

    2000万开房数据怎么打开?.docx

    本资源主要讲述了如何打开和恢复 SQL Server 数据库备份文件(bak 文件),并对其中的数据进行查询。下面是对应的知识点: 1. SQL Server 数据库备份文件(bak 文件) * SQL Server 数据库备份文件的格式是 bak ...

    酒店2000w练习数据(2)

    我的导入SQL2005的方法为:先将csv数据导为access数据库格式,然后再将access数据导入为sql2005表。此数据练习并发操作比较不错,尤其对于大数据量的查询优化极有帮助! 注:因上传文件受大小限制影响,共分两部分,...

    测试数据管理与隐私数据漂白解决方案.pptx

    根据统计,2011年12月,CSDN网站600万用户信息泄露事件,2014年1月,2000万酒店开房数据泄漏,2014年12月25日,13万个12306用户信息遭泄露,等等。这些事件表明,数据安全问题是非常严重的。 同时,随着法规的出台...

    企业信息数据防泄漏解决方案.pptx

    例如,2011 年 12 月 CSDN 网站 600 万用户信息泄露事件、2014 年 1 月 2000 万酒店开房数据泄漏、2014 年 12 月 25 日,13 万个 12306 用户信息遭泄露等事件都表明了企业信息数据的安全问题的严重性。 解决方案 ...

    基于大数据分析的网络攻击检测

    - **连锁酒店数据库拖库事件**:2013年10月,慧达驿站软件漏洞导致2000万条开房记录泄露。 - **Java Struts2漏洞**:2013年7月,该漏洞导致某著名电商平台遭受拖库,超过5亿用户信息被盗。 - **韩国大规模网络攻击**...

    毕设&课程作业_智能旅馆开房系统.zip

    首先,从软件工程的角度来看,一个完整的智能旅馆开房系统需要遵循系统开发的生命周期,包括需求分析、系统设计、编码、测试和维护等阶段。在需求分析阶段,我们需要明确系统的目标用户,理解他们的需求,如预订、...

    自由行开房报告 旅游数据分析技术用户偏好预订行为

    报告基于蚂蜂窝旅行网大数据和问卷调查,分析自由行用户酒店预订偏好、行为和需求。覆盖境内外酒店资源和用户评论,揭示预订时间分布、高峰期、移动端预订趋势、住宿选择偏好及特殊住宿需求。适用于旅游行业分析师、...

    从LOL的成功推断竞技性“开房”游戏的成功思路.rar

    《从LOL的成功推断竞技性“开房”游戏的成功思路》 电子竞技,特别是以英雄联盟(League of Legends,简称LOL)为代表的多人在线竞技游戏,近年来在全球范围内取得了巨大的成功。这款游戏的成功并非偶然,其背后...

    【马蜂窝】自由行“开房”报告2016.pdf

    很抱歉,但根据您提供的信息,“【马蜂窝】自由行“开房”报告2016.pdf”似乎并不是一个关于IT专业知识的文件。它的标题和描述可能涉及到旅游行业的数据分析,特别是自由行旅客的住宿情况,这并不符合您要求的IT知识...

    软件工程作业-酒店管理系统

    **数据结构与组织**\n - 系统包含多个数据文件,如用户(员工)信息文件、客户信息文件、客房信息文件、客房类型文件、物品信息文件等,每个文件都有特定的数据组成和排序方式,便于数据的管理和检索。\n\n5. **...

    佳驰星级酒店管理系统方案书含自助开房模块.doc

    随着酒店市场的日益饱和,竞争愈发激烈,酒店业的发展趋势已经从最初的硬件设施比拼转向了以服务为核心的竞争,特别是那些能够提供人性化和智能化服务的酒店更能在市场上脱颖而出。 佳驰星级酒店管理系统方案书中的...

    皇家酒店管 理餐饮管理 点菜 酒店房间 开房

    6. **数据分析**:通过收集和分析入住数据,酒店可以了解入住率、平均消费等指标,以便优化定价策略和服务。 在"皇家酒店管理"系统中,这些功能的集成不仅提高了工作效率,也为客人提供了更便捷、舒适的体验。通过...

    酒店开房类图

    综上所述,这个“酒店开房类图”全面涵盖了酒店前台开台模块的需求,从系统架构到具体操作,为开发人员提供了清晰的蓝图。通过深入理解类图、用例图、流程图和数据库设计,可以更有效地实现功能强大的酒店管理系统。

    酒店管理系统(VB.net SQL)

    另一方面,SQL(Structured Query Language)是关系型数据库的标准语言,用于存储、管理和检索数据。在酒店管理系统中,SQL数据库如SQL Server或SQLite,用于存储房间信息、客人信息以及各种交易记录。通过精心设计...

    红包开房扫雷源码整站打包

    微信公众号搭建的微信抢红包源码开房模式的亲测可用包内有数据库有教程 本源码分享仅供学习交流,如作他用所承受的法律责任一概与本人无关 (下载使用即代表你同意上述观点)

    阿紫修改的ET最新开房聊天室(51专用)

    【阿紫修改的ET最新开房聊天室(51专用)】是一款专为51社区设计的聊天室软件,由用户阿紫进行了一定程度的修改和优化,以提供更个性化的聊天体验。这款聊天室类应用可能包含了针对51社区用户需求的特色功能,比如更加...

    JS全景开房代码,包含场景切换

    在这个“JS全景开房代码”项目中,我们主要探讨的是如何使用JavaScript来实现全景视觉效果,并实现场景的平滑切换。 全景技术通常用于创建360度全方位的图像或视频,给用户带来沉浸式的浏览体验。在网页上实现全景...

    我的计分板微信小程序,用于简单的开房、计分

    该小程序主要用于计分,提供基础的开房、邀请、计分、房内聊天室、比赛记录等。

    飞鸟系统源码带飞单系统无限开房【无需公众号】.zip

    完整可用,绝对没问题,有架设文档

Global site tag (gtag.js) - Google Analytics