首页 > 代码库 > 数据库之视图、索引

数据库之视图、索引


一、数据库视图

 

       视图是虚表,是从一个或几个基本表(或视图)中导出的表,在系统的数据字典中仅存放了视图的定义,不存放视图对应的数据。
       视图是原始数据库数据的一种变换,是查看表中数据的另外一种方式。可以将视图看成是一个移动的窗口,通过它可以看到感兴趣的数据。 视图是从一个或多个实际表中获得的,这些表的数据存放在数据库中。那些用于产生视图的表叫做该视图的基表。一个视图也可以从另一个视图中产生。


1、视图的作用

* 简单性。看到的就是需要的。视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。

* 安全性。通过视图用户只能查询和修改他们所能见到的数据。数据库中的其它数据则既看不见也取不到。数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对象上,但不能授权到数据库特定行和特定的列上。通过视图,用户可以被限制在数据的不同子集上:

使用权限可被限制在基表的行的子集上。

使用权限可被限制在基表的列的子集上。

使用权限可被限制在基表的行和列的子集上。

使用权限可被限制在多个基表的连接所限定的行上。

使用权限可被限制在基表中的数据的统计汇总上。

使用权限可被限制在另一视图的一个子集上,或是一些视图和基表合并后的子集上。

* 逻辑数据独立性。视图可帮助用户屏蔽真实表结构变化带来的影响。



2、视图的优点

(1)视图能简化用户的操作

(2)视图机制可以使用户以不同的方式查询同一数据

(3)视图对数据库重构提供了一定程度的逻辑独立性

(4)视图可以对机密的数据提供安全保护



3、视图的安全性

视图的安全性可以防止未授权用户查看特定的行或列,使用户只能看到表中特定行的方法如下:

(1)在表中增加一个标志用户名的列;

(2)建立视图,使用户只能看到标有自己用户名的行;

(3)把视图授权给其他用户。



4、逻辑数据独立性

       视图可以使应用程序和数据库表在一定程度上独立。如果没有视图,应用一定是建立在表上的。有了视图之后,程序可以建立在视图之上,从而程序与数据库表被视图分割开来。视图可以在以下几个方面使程序与数据独立:

(1)如果应用建立在数据库表上,当数据库表发生变化时,可以在表上建立视图,通过视图屏蔽表的变化,从而应用程序可以不动。

(2) 如果应用建立在数据库表上,当应用发生变化时,可以在表上建立视图,通过视图屏蔽应用的变化,从而使数据库表不动。

(3)如果应用建立在视图上,当数据库表发生变化时,可以在表上修改视图,通过视图屏蔽表的变化,从而应用程序可以不动。

(4)如果应用建立在视图上,当应用发生变化时,可以在表上修改视图,通过视图屏蔽应用的变化,从而数据库可以不动。



5、创建视图的语法:


CREATE VIEW <视图名>[(列名组)]

AS <子查询>


eg. order为订单表,product为产品表,他们之间是一种一对多的关系,现在可以创建一个视图,代码如下:


create   view   order_product (orderName, productId, productName )           ---创建一个视图,有三个字段

as  select   o.orderName, p.productId, p.productName  from order o, product p        ---获取order和product表的字段值

where  o.orderId=p.orderId                                                               ----建立order表和product表的联系


6、删除视图的语法:

DROP VIEW <索引名>


适当的利用视图可以更清晰地表达查询

eg. 需要执行这样的查询“对每个学生找出他获得最高成绩的课程号”。可以先定义一个视图,求出每个同学获得的最高成绩:

CREATE VIEW VMGRADE
AS
SELECT Sno,MAX(Grade) Mgrade
FROM SC
GROUP BY Sno;

然后用如下的查询语句完成查询:

SELECT SC.Sno,Cno FROM SC,VMGRADE WHERE SC.Sno = VMGRADE.Sno AND SC.Grade = VMGRADE.Mgrade;



二、数据库索引(Index)

 

      索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。


1、索引的技术原理:

       索引是对数据库表中一个或多个列(例如,employee 表的姓名 (name) 列)的值进行排序的结构。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。
例如这样一个查询:select * from table1 where id=10000。如果没有索引,必须遍历整个表,直到ID等于10000的这一行被找到为止;有了索引之后(必须是在ID这一列上建立的索引),即可在索引中查找。由于索引是经过某种算法优化过的,因而查找次数要少的多。可见,索引是用来定位的。

 

 

2、索引的主要种类


      根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。

唯一索引

        唯一索引是不允许其中任何两行具有相同索引值的索引。
当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。


主键索引
        数据库表经常有一列或多列组合,其值唯一标识表中的每一行。该列称为表的主键。
在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

聚集索引
        在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。


       聚集索引和非聚集索引的区别,如字典默认按字母顺序排序,读者如知道某个字的读音可根据字母顺序快速定位。因此聚集索引和表的内容是在一起的。如读者需查询某个生僻字,则需按字典前面的索引,举例按偏旁进行定位,找到该字对应的页数,再打开对应页数找到该字。这种通过两个地方而查询到某个字的方式就如非聚集索引。


3、基本特点


        建立索引的目的是加快对表中记录的查找或排序

 

为表设置索引要付出代价的:(缺点)

一是增加了数据库的存储空间,

二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。

 

数据库索引就是为了提高表的搜索效率而对某些字段中的值建立的目录 。


创建索引可以大大提高系统的性能:(优点)

 

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

 

4、什么时候需要创建索引?在哪个列上创建索引号?

 

一般来说,应该在这些列上创建索引:


(1)在经常需要搜索的列上,可以加快搜索的速度;


(2)在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;


(3)在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为

索引已经排序,其指定的范围是连续的;


(4)在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;


(5)在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度

 

 

 

5、哪些列不适合创建索引?

 

       第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。


       第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。


       第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少,不利于使用索引。


        第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改操作远远多于检索操作时,不应该创建索引。

 

6、索引案例展示:

创建一个表,

CREATE TABLE mytable(
idserial int primary key,
category_id int not null default 0,
user_id int not null default 0,
adddate int not null default 0
);

最普通的情况,是为出现在where子句的字段建一个索引。

 

如果在查询时常用类似以下的语句:
SELECT * FROM mytable WHERE category_id=1;


最直接的应对之道,是为category_id建立一个简单的索引:
CREATE INDEX mytable_categoryid ON mytable (category_id);


如果有不止一个选择条件呢?例如:
SELECT * FROM mytable WHERE category_id=1 AND user_id=2;


第一反应可能是,再给user_id建立一个索引。不好,这不是一个最佳的方法。可以建立多重的索引
CREATE INDEX mytable_categoryid_userid ON mytable(category_id,user_id);

 

索引总结:

       建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。对于一个经常需要更新和插入的表格,就没有必要为一个很少使用的where字句单独建立索引了,对于比较小的表,排序的开销不会很大,也没有必要建立另外的索引。


以上资料整理于网络。





数据库之视图、索引