组成数据库的对像!
A:表(table)具体组织和存储数据的对像,由列和行组成.
1:行和列顺序可以是任意的.在同一个表中列名必须是唯一的.
2:在同一个数据库里面表名也必须要是唯一.
B:主键(primary key)
1:表中一列或多列的组合,其值唯一确定表的一行.
2:主键不能重复
3:作为主键各列都不能为空.
C:外键(foreign key)
表中一列或多列的组合,它本身不是本表的主键,而是另外一个表的主键.[一对多关系]
外键是两个表发生关系一个纽带.
D:视图(view)从一个或几个基本表中根据用户需要而做成一个虚表.
1:视图是虚表,它在存储时只存储视图的定义,而没有存储对应的数据
2:视图只在刚刚打开的一瞬间,通过定义从表中搜集数据,并展现给用户
E:约束(constraint)
对表中各列的取值范围进行限制,以确保表中数据的合理有效.
F:默认值(default)
在向表中插入数据时,为没有指定数据的列提供一个默认的数据
G:事务(constran)
1:在关系型数据库里面一般使用“事务“来处理用户提交的修改表和数据的操作
2:事务就是一次性完成的一组数据的操作.
3:事务的持征:位于事务中的操作要么全部都做,要么全部取消,从而维护了数据库中数据的合理性.
4:关系数据库中一般按照先写日志的方法进行事务操作.即:在实施事务之前先将要进行操作的记录写入日志,再进行实际的数据修改.
5:是记录关系数据修改的情况的笔记.
6:在用户对数据库实施之前,sql会把两种形式的情况写入日志.
1:实施事务之间的数据状态.
2:实施事务之后的数据状态.
当事务由于中途被破坏时,sqlserver会利用日志记录把数据恢复成实施事务之前的数据状态,即撤消事务(回滚);
如果事务顺利的执行则把数据恢复成实施事务之后的状态,即执行事务(前滚).
H:规则(rule)同约束一样,对特定的列进行限制:单价*数量=总额
I:索引(index)提供一种无需扫描整张表就能实现对数据快速访问的途径.可以使用索引来优化查询.[用索引可以实现排序]
J:存储过程(store procedure)
一组经过编译好的可以重复使用的sql代码.存储过程是在服务器中执行,用户可以调用存储过程并接收存储过程返回的结果.
1:由于存储过程是存储在服务器,所有可以让每一个客户重复使用,减少sql代码书写量.
2:由于存储过程是事先编译好的sql代码,所以在执行时,并不做语法检验,可以大大提高sql语句的执行效率.
K:触发器(trigger)
一种特殊的存储过程.
1:触发器与表相关.
2:当用户对指定的表进行某种操作时,触发器会自动执行,去做它里面sql代码
L:数据类型(data type)
两种类型:系统数据类型,用户自定义数据类型.
系统数据类型:int,float,char,varchar,text[备注,工作简历],image[存储图像]
M:日志(log)
sql server使用日志记载用户对数据库进行的一系列的操作.日志是维护数据库完整性的重要工具.sql server遵守先写日志再对数据库进行操作.所以某一天,如果数据库损坏,但可以通过日志进行恢复.
SQL系统组成
1:sql server系统数据库.
A:master:最重要的一个数据库.保存了:
服务器的用户名密码.
服务器的配置信息
使用的数据类型
错误信息
系统或者用户建立的所有对像
说明:由于master数据库比较重要所以不要在里面建表,不要修改里面的任何内容.
B:tempdb:临时数据库
1:记录所有的临时表格或者数据.
2:tempdb是一个全局资源,任何连接到sql server都可以使用.
3:该数据库所放有的数据全部是临时,这就是说当sql server服务停止之后,所有数据将会消失
C:model数据库:模板数据库.
1:是建立新的数据库一个样式.
2:当用户建立一个数据库的时候,首先要从model数据库里面复制所有的表.
D:msdb数据库:
主要被sql server agent服务用于操作作业调度以及管理报警.
组成数据库的对像!
A:表(table)具体组织和存储数据的对像,由列和行组成.
1:行和列顺序可以是任意的.在同一个表中列名必须是唯一的.
2:在同一个数据库里面表名也必须要是唯一.
B:主键(primary key)
1:表中一列或多列的组合,其值唯一确定表的一行.
2:主键不能重复
3:作为主键各列都不能为空.
C:外键(foreign key)
表中一列或多列的组合,它本身不是本表的主键,而是另外一个表的主键.[一对多关系]
外键是两个表发生关系一个纽带.
D:视图(view)从一个或几个基本表中根据用户需要而做成一个虚表.
1:视图是虚表,它在存储时只存储视图的定义,而没有存储对应的数据
2:视图只在刚刚打开的一瞬间,通过定义从表中搜集数据,并展现给用户
E:约束(constraint)
对表中各列的取值范围进行限制,以确保表中数据的合理有效.
F:默认值(default)
在向表中插入数据时,为没有指定数据的列提供一个默认的数据
G:事务(constran)
1:在关系型数据库里面一般使用“事务“来处理用户提交的修改表和数据的操作
2:事务就是一次性完成的一组数据的操作.
3:事务的持征:位于事务中的操作要么全部都做,要么全部取消,从而维护了数据库中数据的合理性.
4:关系数据库中一般按照先写日志的方法进行事务操作.即:在实施事务之前先将要进行操作的记录写入日志,再进行实际的数据修改.
5:是记录关系数据修改的情况的笔记.
6:在用户对数据库实施之前,sql会把两种形式的情况写入日志.
1:实施事务之间的数据状态.
2:实施事务之后的数据状态.
当事务由于中途被破坏时,sqlserver会利用日志记录把数据恢复成实施事务之前的数据状态,即撤消事务(回滚);
如果事务顺利的执行则把数据恢复成实施事务之后的状态,即执行事务(前滚).
H:规则(rule)同约束一样,对特定的列进行限制:单价*数量=总额
I:索引(index)提供一种无需扫描整张表就能实现对数据快速访问的途径.可以使用索引来优化查询.[用索引可以实现排序]
J:存储过程(store procedure)
一组经过编译好的可以重复使用的sql代码.存储过程是在服务器中执行,用户可以调用存储过程并接收存储过程返回的结果.
1:由于存储过程是存储在服务器,所有可以让每一个客户重复使用,减少sql代码书写量.
2:由于存储过程是事先编译好的sql代码,所以在执行时,并不做语法检验,可以大大提高sql语句的执行效率.
K:触发器(trigger)
一种特殊的存储过程.
1:触发器与表相关.
2:当用户对指定的表进行某种操作时,触发器会自动执行,去做它里面sql代码
L:数据类型(data type)
两种类型:系统数据类型,用户自定义数据类型.
系统数据类型:int,float,char,varchar,text[备注,工作简历],image[存储图像]
M:日志(log)
sql server使用日志记载用户对数据库进行的一系列的操作.日志是维护数据库完整性的重要工具.sql server遵守先写日志再对数据库进行操作.所以某一天,如果数据库损坏,但可以通过日志进行恢复.
SQL系统组成
1:sql server系统数据库.
A:master:最重要的一个数据库.保存了:
服务器的用户名密码.
服务器的配置信息
使用的数据类型
错误信息
系统或者用户建立的所有对像
说明:由于master数据库比较重要所以不要在里面建表,不要修改里面的任何内容.
B:tempdb:临时数据库
1:记录所有的临时表格或者数据.
2:tempdb是一个全局资源,任何连接到sql server都可以使用.
3:该数据库所放有的数据全部是临时,这就是说当sql server服务停止之后,所有数据将会消失
C:model数据库:模板数据库.
1:是建立新的数据库一个样式.
2:当用户建立一个数据库的时候,首先要从model数据库里面复制所有的表.
D:msdb数据库:
主要被sql server agent服务用于操作作业调度以及管理报警.
创建和维护数据库(上)
1:数据库的逻辑结构:
2:数据库的物理结构:
3:如何创建数据库:
4:如何删除数据库:
A:数据库的逻辑结构:
通常我们在企业管理器中看到的数据库和里面的对像都只是数据库的逻辑结构.也就是它们并不像在企业管理器中所看到的那样的结构去存储在计算机中.企业管理器只是为了方便用户查看数据和操作数据而在前台表象上作了一个“虚假”的显示结构即为数据库的逻辑结构.而数据库中真正的数据是存储在硬盘中.而且是以文件的形式来保存的.于是有了数据库的物理结构.
B:数据库的物理结构:
既然数据库里面的所有数据是以文件的形式存储在硬盘中,那么究竟一个数据库库由那样文件组成呢?组成一个数据库的文件由以下三种文件组成:
1:主要数据文件:
作用:主要数据文件包含数据库的初始信息.记录数据库还拥有那些文件,并且用来存储数据.如用户建的表等数据.
特点:每一个数据库有且只有一个主要数据文件.扩展名为 mdf
2:次要数据文件:
作用:次要文件也是用来存储数据库中的各类信息的,用户可以选择是否需要次要数据文件.也就是说它是可选的,它的扩展名为 ndf
为什么要引入次要数据文件:
1:或许你的主要文件的数据非常庞大,以至于超过所在的硬盘分区.如果没有次要数据文件帮助则用户添加的数据将不能加入到数据库里面去.
2:可以为一个数据库创建多个次要文件,并把这些文件放到不同的硬盘中,既可将一个数据库中的数据存储在多个不同的物理硬盘中.[可以提高查询效率:以下再作解释]
3:日志文件:我们知道由于关系型数据库遵循“先写日志再操作”的原则,所以必须有一个文件来存储用户对该数据库所作的一切操作的笔记的文件,这就是日志文件.扩展名为:ldf.说明:一个数据库必须至少有一个日志文件,也可以有多个日志文件.
所有数据库基本上由这个三类文件组成.另外补充一点:当你创建数据库并指定一个数据文件或日志文件时,系统会让你输入两种表示形式的文件名:一个是不带路径的文件名,一个是要带路径的文件.它们分别是:逻辑文件名,物理文件名
1:逻辑文件名:用于在sql语句命令中对该文件进行访问,即不需要指明路径.
2:物理文件名:是文件实际存储在磁盘上的文件名,必须包括路径,指明该文件在磁盘中的什么位置.
总结:逻辑文件名与物理文件名就像一个房主与房子地址一样,我们用房子的主人就可以代表房子本身即:房子的地址.
文件组
文件组:如果一个数据库有很多文件就不便于管理了,为了管理和分配的目的,sql server允许你将多个文件归纳为同一个组.这样文件组中的文件就和其它文件组中的文件没有直接关系.这就是文件组.
说明:
1:一个数据库里面必须有且仅有一个主文件组为:primary filegroup.用户可以根据需要来定义其它文件组.
2:一个文件只能属于一个文件组,它不能同时属于两个文件组.
3:文件组只能够管理数据文件,也就是日志文件不能放入文件组,因为日志文件是分开管理的
4:所有建的次要数据文件如果不特别指定组则自动被放入primary组.
sql server对文件组中的每个文件的填充策略:
如果用户有数据要写入文件组时(比如用户建一个表,并指定它属于的文件组时,之后用户对该表加入记录)sql server会采用“按比例填充”的原则:即以属于该组每个文件的可用空间比例来将数据分割并分别写入每一个文件中.而不是先写入第一个文件,第一个文件写满之后再写第二文件.但是sql server对日志文件的数据分配是采用“写满为止“的策略.
为什么要引入文件组:
理由:
1)用户可以在一个数据库里面建多个数据文件并指定它们的“物理名”为不同的磁盘,然后再把它们放入一个组中.这样当用户在这个组中创建一个表时这个表中的数据将按“比例填充”方式放入该组中所有的数据文件中,这样就可以实现把一个表中的数据放入多个磁盘,即可以实现数据库的“广域”存储.此时如果要对该表进行查询,则多个磁盘的读写磁头将能够同时并行的访问数据,从而加快数据库的操作.
2)通过为某些数据容量很大且经常需要使用的表直接存储在一个特定的高速的磁盘上,而把一些不经常使用且容量较小的表存储另一个磁盘上,就能提供工作效率.
怎样使用文件组:
1:大多数的数据库只需要一个主要数据文件和一个日志文件就中以非常好的运行.
2:如果在创建数据库之前估计某个对像(如表)以后会占用大量数据则在数据库创建时,在多个磁盘分别建立一个数据文件,然后把它们设为属于同一个组.然后把该对像放于该组,则因为多个磁盘能并行操作而加快操作速度.
3:如果某些表经常要执行“连接查询”且容量很大,则应该把这些表分别存储在不同的文件组中,如此一来因为能对被连接的数据实施并行磁盘搜索而提高效率.
C:如何创建数据库:
1:通过企业管理器:
2:sql语句:
格式:create database 数据库名
on
primary
(
name=/'数据文件1的逻辑文件名/',
filename=/'数据文件1的物理文件名/',
size=大小,
maxsize=大小,
filegrowth=大小
),
(
name=/'数据文件2的逻辑文件名/',
filename=/'数据文件2的物理文件名/',
size=大小,
maxsize=大小,
filegrowth=大小
),
............
filegroup 用户自定义文件组名
(
name=/'数据文件1的逻辑文件名/',
filename=/'数据文件1的物理文件名/',
size=大小,
maxsize=大小,
filegrowth=大小
),
(
name=/'数据文件2的逻辑文件名/',
filename=/'数据文件2的物理文件名/',
size=大小,
maxsize=大小,
filegrowth=大小
),
log on
(
name=/'日志文件1的逻辑文件名/',
filename=/'数据文件1的物理文件名/',
size=大小,
maxsize=大小,
filegrowth=大小
)
说明:
1:数据文件名之间不能同名,数据文件名与日志文件名也不能同名.
2:在给一个组加上文件时,每个文件之间用“逗号”隔开.
3:数据文件与日志文件的分界时不要加逗号.
4:由于日志文件不能放入任何组,所以不要为日志文件设定组.
5:如果不指明组则添加的数据文件都自动放入primary组.
6:必须有一个主数据文件.
7:如果数据文件还有较大的空间但是日志文件的空间已占满则对数据进行的所有更新操作将都因无法写入日志而终止.
注意:数据文件和文件组绝对不能与日志文件存储在相同的磁盘上.
D:如何删除数据库:
1:通过企业管理器:
2:sql语句:
格式:drop database 数据库名
说明:
1:数据库删除后,数据库里面的数据文件与日志文件就会被删除,系统数据库master关于该数据库的信息也被删除了.
2:建议在删除数据库之后立即备份master数据库.否则你在删除了一个数据库之后而后却因为某种原因还原了过去所备份的master数据库,则会出错.
3:master,model,msdb,tempdb这四个数据库不能删除.
4:如果数据库正在被使用则不能删除.
创建和维护数据库(下)
5:如何修改数据库:
6:快速查看数据库的内容:
7:附加和分离数据库:
8:生成数据库的sql脚本:
9:数据库复制向导:
E:如何修改数据库
1:更改数据库的名字:sp_renamedb 旧名,新名
说明:修改数据库的名字一定要小心,因为客户端应用程序都是以原先的名字来访问的.
必须确认没以任何人连接以数据库中才可以更名.
2:扩充分配给数据库的数据文件或日志文件的空间:
你在创建数据时,可以设置数据库文件的自动增长空间,事实上除了让sql server自动去扩充之外,还可以人工的方式来扩展数据库,还可以为已经创立的数据库增加新的文件.
方法:企业管理器:数据库,属性
说明:在给已经存在数据文件重新分配大小时,分配的大小不能比原来的小.
3:收缩分配给数据库的数据文件或日志文件.
当你觉得你的数据库的初始值设定过于大,或者增长方式设置不符合你的业务,以致使数据库产生多余空间时,就可以收缩数据库了.
方法:企业管理器 “收缩数据库”
说明:1:收缩后文件的最大可用空间:可以指定一个数值来决定收缩后文件的可用空间,数值越大,收缩越小,反之收缩越大.
2:在收缩前将移动页文件起始位置:在收缩之前会把位于页里面的数据集中到文件开头从而得到更多的可用空间,但由于要做移动数据等动作,则会花费较多的时间.
3:调度:可以让sql server定期来收缩数据库,从而实现自动化管理.
4:压缩页然后截断文件中的可用页:收缩数据页,然后将收缩页产生的可用空间删除.
5:从文件结尾处截断可用空间.
6:清空文件:清空数据文件或日志文件而该文件中的数据迁移到文件组中的其他文件中.
7:收缩文件至:将选定的文件收缩到特定的大小.
8:在一段时间之后收缩:到了某一时间之后再收缩.[预定义]
思考:能不能通过删除数据文件或日志文件的方法来收缩数据库.
4:添加或删除数据文件和事务日志:
你可以添加数据文件或事务日志文件来扩充数据库的大小,也可以通过删除数据文件和事务日志文件来收缩数据库.下面着重来讲解数据库文件的删除:
1:对于数据文件的写入方式是“按比例”写入,所以如果用户要建一个表则该表所属的文件组中的任何一个数据文件都将或多或小的写入数据.
2:而日志文件的写入方式是“写满为止”的策略来写入,即只有当第一个日志文件写满了之后才去写下一个日志,这就是说如果你为一个数据库建多个日志文件,有可能有些日志文件是空的.
3:要删除数据库文件必须保证数据库文件里面没有任何数据.
4:要得到删除数据库文件必须首先将它里面的数据迁移动同一个文件组中的其它文件里面去.
格式:dbcc shrinkfile (数据文件名,emptyfile)
5:方法:数据库====属性:
5:更改数据库的所有者:
1:什么是所有者:数据库的创建都就是数据库的所有者(dbo)
2:数据库所有者和sa对该数据库有任何操作权限.
3:数据库所有者与sa的区别在于sa是全局的,而数据库所有者是局部的.
4:格式:sp_changedbowner 登录用户名
说明:1:只能够更改当前数据库的dbo
2:如果指定的登录名已经是当前数据库的用户,则不能更改
6:更改数据库的配置:
A:仅仅供数据库拥有者或者sa能够使用:
用途:当你作为一名数据库管理员需要改变表的结构时,你不希望别的用户来使用该表,可以把此项设置,当你把表的结构改了之后再把它改回来.
sql语句:sp_dboption /'数据库名/',/'dbo use only/',/'true/'[false]
B:单用户:同一时间只能够有一位用户连接到数据库来访问它:
用途:更改数据库名称,还原数据库的时候.
sp-dboption /'数据库名/',/'single user/',/'true/'[false]
C:只读:使数据库只读.
sp-dboption /'数据库名/',/'read only/',/'true/'[false]
F:快速查看数据库的内容
1:企业管理器:任务板:
A:常规:给出关于数据库一些详细资料.
B:表:查看数据库中各个表的详细资料.
C:向导:很方便的打开向导和工具来完成操作.
2:sql语句:
A:sp_helpdb 数据库名[指定数据库的详细资料,包括各数据库文件]
B:sp_helpdb [当前服务器中所有数据库的详细资料,不包括数据库文件]
C:sp_databases[显示当前服务器所有可以使用的数据库]
D:sp_helpfile [查看当前数据库的所有文件的资料]
G:附加和分离数据库:
目的:就是移动数据库的位置.
注意:在sql里面没有复制,剪切,粘贴等命令.
用途:
1:将数据库移动到其它已经注册到你的企业管理器的其它的sql server 服务器中.
问题:要把服务器www中chen数据库移动到test服务器中.
比较:常规方法:
本方法:先让chen与www分离,然后再把chen的数据文件和日志全部移到test服务器对应的路径,接着再把www附加到test服务器.
2:改变数据库中数据文件或日志文件的磁盘的目录:
比如存储数据或日志文件的空间已不足了时你便要移动数据文件或日志文件的位置到其它有更大的空间的位置上.
A:数据库创建之后数据文件和日志文件的位置便不能更改.
B:只有把数据库分离之后才可以改变.
H:生成数据库的sql脚本.
通过生成数据库的sql脚本我们能够产生创建现有数据库各个数据库对像的sql语句.然后可以把此脚本再次运行.
例能够产生出一个和原数据库有相同结构(不是数据也相同)的新数据库.
用途:
1:重新创建一个与某个数据库结构完全相同的数据库.
比如:你在服务器A里面建了一个数据库test,你现在要把test的结构复制到B服务器里面去(注意:不是数据,仅仅是结构,也就是说对于表而言将不会有数据存在),那么你可以先在服务器A中生成一个关于test数据库的sql脚本,然后再在服务器B中去运行.
2:备份一个脚本,以便允许用户可以重建所有的用户,角色,登录与权限.
比如:你好不容易在某个服务器上创立了一些数据库用户或角色,或登录或权限.这个时候你可以生成一个你当前创建这些对像的脚本,如果以后有人恶意删除了这些对像,则可以通过把这些代码重新运行一次,重而免去重新创建这些对像的麻烦.
3:更新数据库开发代码.
比如:你可以在生成sql脚本的基础上,再对源代码进行修改,从而可以在源数据库的基础上扩展一些功能
方法:企业管理器:
说明:
1:为每个对像创建create命令:为用户在常规选项卡里面选择的各对像创建create语句.
2:生成全部相关脚本:生成在常规选卡中选中与之相关的对像. 比如:如果你在常规选项卡里只选择了视图,而没选择了表,当你运行这种sql代码就会出错.因为视图需要表支持.如果选中此项则sql会自动将支持视图的相关对像一起创建.
3:在脚本中包含说明性的标题:在生成代码的同时,加上一些说明性的文字
4:编写数据库脚本:要生成数据库的代码.
5:编写数据库的用户和角色脚本:要生成数据库的用户和角色的代码.
6:编写sql server登录脚本:要生成服务器登录的脚本.
7:编写对像级别权限的脚本:为你在“常规”页面中选取的各个数据库对像设置权限而编写的sql代码
I:数据库复制向导
利用数据库复制向导,我们可以很轻易地把一个服务器的数据库复制到另外一个服务器中.
1:选择是复制服务器的登录用户:
A:包括运行时检测到的所有登录:将要复制的数据库所在的服务器全部登录帐户复制到另外一个服务器中
B:仅包括数据库使用的登录:只复制“要复制的数据库”使用的登录的部分帐户.
2:选择master数据库里面的共享存储过程:
A:包括运行时检测到的所有的存储过程:将把要复制的数据库所有服务器中master数据库里面的存储过程都复制到目的服务器所在的master数据库中.
B:用户选定的存储过程:可以决定要复制的数据库所有服务器中master数据库里面的存储哪些要复制哪些不要复制.
创建和维护表(tables)
1:表的结构:
2:创建表:
3:自动编号字段:
4:活用用户定义数据类型:
5:创建计算字段:
6:快速查看、添加、修改与删除数据记录:
7:更改表的结构:
8:更改表的名称:
9:更改表的所有者:
10:删除表:
11:用户表与临时表与系统表:
A:表的结构:表的结构基本决定了表拥有哪些字段名、使用的数据类型.
1:字段名(field)
1)字段名最长可达128个字符
2)同一个表中字段名绝对不能重复
2:长度、精度和小数位数,NULL值.
1)长度:指字段所能容纳的最大数据量.对于不同类型的数据,长度对字段的意义可能有些不同
一:对于字符型数据类型而言:长度代表字段所能容纳的字符的数目,因此它会限制用户所能输入的的文本长度[长度可以修改]
二:对于数值型数据类型而言:长度代表字段使用多少个字节来存放数据,它决定了字段所能存放的最大数最小数[长度固定不能更改].比如: int 4字节=4*8=32位,则最大的数为: - 2^(32-1)-----2^(32-1)
2)精度:一般精度是相对于小数而言,表示数中数字的个数.
3)小数位数:小数点后数字的位数.
比如:1234.678 其精度是:7(不包括小数点),小数位数是:3
说明:有些数据类型精度,小数位数都不能改,有些可以改.decimal,numeric
3:数据类型(datatype)
特殊的类型:char,varchar的区别,精确数据类型:decimal,numeric [都可以指定小数数位数和精度]
image,money,datatime[固定保留四位小数],bigint,int,smallint,tinyint
4:NULL值:
1:NULL值并不等于数值0,空格,它是虚无值.
2:NULL值是说此字段中的数据是否可以是未知的或未定义的,如果允许为NULL则该字段的数据是允许未知,否则只能是已知的
3:快捷方式:ctrl+0
B:创建表:
1:通过企业管理器:
1:添加或插入字段:
2:删除字段:
3:表的属性窗口:所有者[该表所在的数据库里必须有用户],表名,表文件组,备注,是否为空
4:描述,默认值,精度,小数位数,标识,标识种子,标识递增量.[如果把某一个列定义成为标识列,则该列不能编辑]
说明:一个数据库包括表最多只能够有2^(32-1)个对像 每一个表最多可以拥有最多1024个字段
2:通过sql语句.
格式:create table 表名
(
列名1 数据类型(长度) not NULL [NULL],
列名2 数据类型(长度) not NULL [NULL],
................
)
[on] [放入指定的文件组]
说明:
1:对于字符型要指明长度,比如:职工号 char(20),姓名 vchar(20)
2:对于除decimal,numeric(6,2)以外的数值型类型,不需要指明指定长度.比如:基本工资 int,单价 float
3:可以对每个字段指定是否允许为空,如果省略则可以为空.[not null]
4:可以指定把创建的表放入一个文件组,如果省略则自动放入primary组.[该组必须存在]
C:自动编号字段
说明:
1:自动编号的字段类型只能是以下几种:int字样的数据
2:如果把某一个字段设置为自动编号,则用户不能去更改里面的内容
3:每一个表只能拥有一个自动编号字段
D:活用用户自定义类型
1:为什么要使用用户自定义类型:
理由:有时候为了建多个表,而这些表中都具有相同类型相同格式的某一种系统数据类型.如果每次建一个表都要去设置很不划算,可以引入用户自定义类型.
2:怎么定义或使用用户自定义类型:
3:删除用户自定义类型:
1:显示相关性:
2:如果该数据类型被其它对像使用,则不允许删除
说明:
1:在某一个数据库里创建的用户自定义数据类型只能够被该数据库的对像使用.不能被其它数据库使用.
2:问题:如何创建一个数据类型可以让新建的数据库都可以使用?(在模板数据库中创建)
E:创建计算字段:
计算字段:计算字段不是表中的字段,而是由表中其它字段通过计算而得来的.比如:单价*数量=销售量
1:为什么要创建计算字段:
2:怎么创建计算字段:创建表的时候才能够创建计算型字段
A:通过sql语句:
比如:create table ww
(
商品名 vchar(10),单价 float,销售量 int,总金额 as 单价*销售量
)
B:格式为:计算字段名 as 表中字段表达式.
C:通过企业管理器:公式列中进行
注意:计算字段也可以参与查询,但不能更新
F:快速查看、添加、修改、删除数据记录
1:查看:打开表.
2:添加:直接加.
3:删除数据:删除一行,删除多行
4:打开表,单右:菜单
G:更改表的结构 :
1:通过企业管理器:
2:使用sql语句
格式:
1:修改原有字段的数据类型
alter table 表名
alter column 列名 新的数据类型
说明:
1:一次只能修改一个字段的数据类型.
2:不能修改计算字段,或使用在计算字段中的列.
上述命令只能够修改数据类型不能修改字段名称.要修改字段名称可以用:sp_rename column 新的列名,
格式:sp_rename /'表名.旧列名/',/'新列名/',/'column/'
2:在原有表的基础上添加新的字段.
alter table 表名
add 数据的字段名 数据类型 [添加时,没有column关键字]
可以一次添加多个字段,字段与字段之间用逗号隔开
3:删除原有表的字段:
alter table 表名
drop column 列名 [删除时,需要column关键字]
1:可以一次删除多个字段,字段与字段之间用逗号隔开
2:可以删除计算字段,但不能删除使用在计算字段中的列.
H:更改表的名称
1:企业管理器:
2:sql语句:
格式:sp_rename 旧表名,新表名
说明:
1:如果一个表被某个或多个对像引用,则不要改名,否则会使这些对象不可用.
2:不要对系统表改名,这有可能会使系统损坏
I:更改表的所有者
1:通过企业管理器:
2:sql格式:sp_changeobjectsowner /'旧拥有者.表名/',/'新的数据库用户/'
J:删除表
1:通过企业管理器:
1:删除前的准备:查看有哪些对像在引用此表
2:删除:
2:sql语句:
格式:drop table 表名 可以一次性删除多个表,表名和表名之间用逗号隔开
K:用户表临时表系统表
sql server把整个表分成三种类型:用户表,系统表,临时表.用户表和系统表已经熟悉
临时表:
什么是临时表:就是临时存放数据的地方,一但不使用时会自动删除.
为什么要使用临时表:有时候在进行数据操作时,希望产生一些阶段性或者过滤性的数据,这些数据只是暂时使用,而当工作结束时,我们希望它们能自动删除,而不是人为去删除.这个时候我们就需要临时表.
临时表的分类:
1:本地临时表:
创建本地临时表:当你创建表时,在表名字前面加上“#”号,则这个表就成为本地临时表.
特点:本地临时表只有创建它的用户可以访问它,其它用户将不能访问,而且一旦这位用户断开与sql server的连接,本地临时表会自动删除.
2:全局临时表:
创建全局临时表:当你创建本时,在表名字前面加上“##”号,则这个表就成为全局临时表.
特点:当一个用户创建一个全局临时表时,其它连接到sql server服务器的用户都可以使用,当创建者与服务器断开后,sql server并不会立即删除该用户所创建的全局临时表,而是会去检查当前还没有别的用户的作业在访问该表,如果有,则暂时不删除全局临时表,但是不允许用户再去访问它,直到在sql server服务器再没有关于该表的作业时,才删除.
设计、创建和维护索引(index)(上)
1:索引的基本概念:
2:索引的设计准则:
3:索引的类型:
4:聚集索引和非聚集索引:
5:唯一索引和非唯一索引:
A:索引的基本概念
索引在关系型数据库中扮演着极其重要的角色,它最主要的作用是:
1:确保数据的唯一性:2:提高数据查询速度
提高数据的查询速度
为什么可以提高数据的访问速度:索引可以把表中的数据进行排序.
举例:创建一个work表最好有80万行.执行:select * from work where 年龄<50
1:[不建索引]观察所用时间
2:[创建一个索引]观察所用时间
1:表扫描:一行一行把表的数据全部扫描到.[tabscan]
2:使用索引:把表的数据进行排序,从而可以提高数据的查询效率
3:索引的结构:索引页,数据页
举列说明:
A:select * from work where 职工号=/'001/'.如果事先能够为职工号建立索引.则可以提高查询速度
B:select * from work where 基本工资>1200 and 基本工资<3000.如果事先能够为基本工资创建索引则可以提高查询效率
C:select * from work order by 基本工资.若能够事先为基本工资创建索引也能够提高查询效率
sql server在什么时候要使用索引:
不要以为只要为某个字段创建索引之后,sql server在查询的时候就一定要使用它.事实上sql server在执行查询之前会通过一个叫“查询优化器”的对像来判断是采用表扫描,还是使用索引,如果利用索引不能使查询得到优化,则不会使用索引,而改用表扫描.
确保数据的唯一性:
索引中有一类索引叫唯一索引(unique),利用它可以保证以该字段为索引的值不会出现重复但它可以为空.与主键有区别,当然如果你创建的索引不要求保持数据唯一性,只是为了提高查询效率你完全可以不建唯一索引,建一个一般的索引就行了.当然确保数据唯一性的方法有很多,比如可以创立主键等.索引只是确保数据唯一性的其中一种方法.
B:设计索引的准则
1:经常被用来查询数据记录的字段.
说明:经常被用来查询数据记录的字段最好是识别度较高的字段(也就是数据内容重复性低).
比如:使用员工编号或身份证号来作索引是非常恰当的.但如果使用家庭住址或使用基本工资来寻找员工就显然不恰当.家庭住址一般有很多字符,会使索引过于庞大,基本工资识别性太低.
2:主键所定义的字段一般应作索引,不过sql server自动帮我们作好了
3:在查询中用来连接表的字段:
4:经常用作排序的字段:
说明:不能为bit,text,image等数据类型的字段创建索引.
索引的负面影响:
那既然索引可以加快查询效率,那我们就把索引建多,越多越好,这一种说法完全错误.
理由:
1:索引显然会占用磁盘空间,创建不必要的索引只会浪费空间[任务面板中查看]
一个索引的大小绝对大于以该字段作为索引的大小乘以记录条数.
2:以某个字段创建一个索引之后,当以后修改或添加该字段时,为了让索引能够实时反映表的动态更新必须有相关的索引.[索引页]
所以得到一个结论:如果一个表是作为引用性的,也就是说它仅仅只作为查询,或者说它的改动非常少,多几个索引倒也无所谓,但是一个经常性修改的表则请谨慎的创建必须的索引[举列说明]
A:在work中执行update work set 年龄=年龄+1 where 年龄=20[观察使用时间]
B:在work中创建一个索引以年龄为索引,再执行同样的语句[观察使用的时间]
3:数据记录越多,索引提高数据访问效率越明显,反过来如果表内含有数据记录很少,建个索引是不会有任何作用的,所以不主张对一个记录很少的表创建索引
C:索引的类型
1:按存储结构区分:聚集索引(clustered index),非聚集索引(nonclustered index)
2:按数据唯一性分:唯一索引(unique index)和普通索引
3:以键列的个数分:单列索引与多列索引.
D:聚集索引和非聚集索引
聚集索引:数据页内容排列的次序与索引页的索引字段的值相同.即:聚集索引会改变表原先的排列顺序使之按照索引升序或降序排列.
正由于聚集索引会使得值相同的数据记录排列在一起,因此要搜索介于某范围的数据值时将会特别有效.因为一但使用聚集索引找到第一条符合条件的记录,则同范围之后的记录保证是相邻排列的,也就是说把这一范围找到之后就不会往下面找了.
怎么使用聚集索引
一般而言下列的数据访问操作非常适合使用聚集索引:
1:如果某个字段所包含的有差别的数据较少,则非常适合以该字段创建聚集索引.比如:员工表中部门字段用来存放员工所在的部门.但一个单位的部门不会超过十个,则以部门创建聚集索引最好.[为什么?]
2:使用betwwen,>,>=,<=,<等运算符查询[注意不是等于]
3:会返回大结果集的查询 至少10万以上
说明:
1:每一个表最多只能有一个聚集索引
2:聚集索引可以是一个唯一索引或普通索引
3:聚集索引的大小平均是表大小的5%,在创建聚集索引期间,它需要使用数据库的一些磁盘空间来存放编制索引过程中的一些临时数据,所需的临时空间大约是表大小的1.2倍,这些临时数据会在索引创建完成后释放出来.
4:如果某一个字段的内容经常变动则非常不适合给这个字段创建聚集索引.因为聚集索引要求表的记录按照索引列排序,所以如果一个字段的变动将会导致整个表的记录的要重新排列一次
非聚集索引:
与聚集索引不同的是,非聚集索引尽管可以按照升序或降序排列,但它丝毫不影响表中数据的实际的存放顺序[注意:索引的排序与表的实际数据的排序的区别]
所以非聚集索引并不会使表的记录排序[是不是就达不到提高数据搜索的效果呢?思考]
另外每一个表中可以拥有多个非聚集索引,正是由于一个表能拥有多个非聚集索引,所以如果你不需要用多种方式搜索数据记录时,非聚集索引便显得特别好用.比如你想先对年龄进行搜索而后又对基本工资进行搜索则我们可以分别为年龄和基本工资创建一个非聚集索引
怎么使用非聚集索引
一般而言下列情况非常适合使用非聚集索引:
1:如果某字段包含的有差别数据非常多,则非常适合为该字段创建非聚集索引.比如:一个客户表的姓名而言,虽然也有相同的姓名,但是大多数的客户的姓名都不一样,所以就要以姓名作为非聚集索引
2:所返回的结果量是不大的查询
3:使用where子句的字段,并要求该字段等于特殊的某个值.比如:where 职称=/'经理/'
4:每一个表最多能够拥有249个非聚集索引
5:非聚集索引可以是唯一索引和普通索引
E:唯一索引和非唯一索引
唯一索引
如果在创建索引的时候加上unique关键字就变成的唯一索引,唯一索引的特点:
1:唯一索引可以确保索引列不包含重复的值.在多列唯一索引的情况下,该索引可以确保索引列中每个值组合都是唯一的.
2:聚集索引和非聚集索引都可以是唯一的.因此,只要列中的数据是唯一的,就可以在同一个表上创建一个唯一的聚集索引和多个唯一的非聚集索引.
3:唯一索引不仅可以保证数据唯一性还可以提高查询效率[用执行计划的io成本来察看]
思考:如果你创建唯一索引的目的仅仅是为了保证数据唯一性,没有必要创建索引,但如果你创建唯一索引的目的是既要保持数据唯一性又要提高查询效率,想一想应该创建聚集的还是非聚集的.
4:当你为一个表创建一个主键时,sql server会自动帮你创建一个唯一索引
5:唯一索引与主键都能够确保数据唯一性,但是它与主键有区别[思考有什么区别]
思考:有work表有职工号,姓名,学历.假如本公司没有一个人同名,应该怎么做:
方法1:创建一个由列职工号和姓名组成的主键.
方法2:由创建一个主键职工号,再创建一个唯一索引,其索引列为:姓名
分析两种方法的结果.
怎么使用唯一索引
1:虽然唯一索引可以保证数据的唯一性,但是如果你只想保证数据唯一性话,则不是必须要设置唯一索引,你可以使用sql server其它方法 比如:主键,约束等.
2:只有你既希望保证数据唯一又想提高查询效率时,才使用唯一索引.
比如:work表中有职工号,姓名,性别,年龄,学历.假定本公司没有同名的人,为了在以后输入姓名的过程中避免出现复制错,而且你经常要用姓名列进行查询,则你可以在姓名列上创建一个唯一索引,这样既保证了数据的完整性又可以提高查询的效率
非唯一索引
如果你在创建索引时没有使用unique关键字,则你创建的索引为非唯一索引,这样该索引的作用仅仅是为了提高查询的效率
设计、创建和维护索引(index)(中)
6:单列索引和多列索引:
7:填充因子:
8:统计信息:
9:创建索引:
10:删除索引:
F:单列索引和多列索引
单列索引
可以为一个列创建一个索引也可以为多个列创建一个索引,为一个列创建的索引就为单列索引,为多个列创建的索引被称为多列索引.以上讨论的都是单列索引,在这里就不在讨论,下面讨论多列索引.
多列索引:由多个列组成的索引被称为多列索引
为什么要使用多列索引
1:当你需要为多个列确保数据唯一性时[不是主键],你可以设置一个多列的唯一索引.
比如:work:职工号,姓名,性别,年龄,学历,基本工资.假定本公司中规定姓名和性别都同时相同时,你可以作一个唯一的索引,这个索引以姓名和性别作为列.
2:如果你想对某些列按照不同的字段排序时,请使用多列的聚集索引.
比如:你想按年龄升序排列,而年龄相同的又按照基本工资降序排列,则你可以创建一个有年龄,基本工资的聚集索引
思考:在work表中有职工号,姓名,年龄,学历,基本工资,职称
要做如下查询:select * from work where 基本工资<1200 and 年龄<25
要提高效率有两种方法:
1:创建一个多列索引,索引列为年龄 升序,基本工资 降序
2:创建两个单列索引,一个索引的索引列为年龄,一个索引的索引列为基本工资.
分析哪一种方法可以更好的提高查询效率
结论:覆盖的查询可以提高性能.覆盖的查询是指查询中所有指定的列都包含在同一个索引中.例如,如果在一个表的a、b和c列上创建了组合索引,则从该表中检索a和b列的查询被视为覆盖的查询.
G:填充因子:
页拆分
在创建聚集索引时,表中的数据按照索引列中的值的顺序存储在数据库的数据页中.在表中插入新的数据行或更改索引列中的值时可能重新组织表中的数据存储,以便为新行腾出空间,保持数据的有序存储.向一个已满的索引页添加某个新行时,SQL Server会通过拆页以便为新行腾出空间.这种重组称为页拆分.页拆分会降低性能并使表中的数据存储产生碎片.
解决办法:
创建索引时,如果在每个数据页预留一些空间,这样以后修改和增加数据时就没有必要移动每个页中的数据以便为新的数据腾出空间了,则可以大加快修改和增加数据的效率.在前面我们已经知道数据被分了多个页每一个页的大小为8kb,那么为每一个页已经填充的空间与整个页的空间的比例就是填充因子.
特点:
1:很显然填充因子越大,则意味着预留空间越小,当为100%时,表示填满了.
2:填充因子值越小则数据页上的空闲空间越大,这样可以减少在索引增长过程中对数据页进行拆分[思考:是不是填充因子越小越好]
怎么设置填充因子:
1:对于一个经常要修改的表,由于要经常对数据进行修改,则拆分页的可能性越大,为了避免拆分页,可以把填充因子设置得小一点[预留空间越大],但是很浪费空间.这是以牺牲表的存储空间来提高数据的更新的效率的
2:对于一个只读的表,或者说很少修改的表,为了不浪费空间建议把填充因子设得大一点.
3:填充因子只在创建索引时执行,以后随着用户不断往表中添加或删除数据时,由于每一页的可用空间要减少或增加,所以填充因子会改变.所以如果对一个表作了大量的改动时,可以删除索引再重新分配数据
思考:如果在不考虑存储空间的情况下,把填充因子设得很小,这样是否可以避免分页
H:统计信息:
什么是统计信息
我们知道在用户创建索引之后,sql server在查询的时候并不一定要使用它.事实上sql server在执行查询之前会通过一个叫“查询优化器”的对像来估算按索引查询所需的成本和直接使用表扫描所需成本,如果发现使用索引所需要的成本大于使用表扫描使用的成本,则不会使用索引而改用表扫描,反之则使用索引.
那么查询优化器依赖什么来估算使用索引查询所需要的成本呢?它只能通过“每一个索引值在索引列中的分布情况的统计信息”估算.实现上在创建索引时,SQL Server会自动存储有关值在索引列中的分布情况的统计信息.SQL Server中的查询优化器使用这些统计信息估算使用该索引进行查询的成本.
但是随着用户对表的修改会导致列中数据的不断更新,则这种统计信息就会过时,从而导致查询优化器选择的查询处理方法不是最佳的,很显然使用过期的“统计信息”估算成本是不真实的,也就是说它不是最优的查询.
自动更新统计信息与手动更新统计信息
自动更新:
因此,随着表中的数据发生变化,SQL Server会自动定期更新这些统计信息.以保证“查询优化器”总是采用最优查询,但是如果用户每次对表进行一点点修改,如果sql server都要去更新统计信息这显然会加大sql server的负荷.所以并不是只要用户对一个表进行更改sql server就会马上去更新“统计信息”,而是更新的频率取决数据更改量.例如,对于一个包含10000行的表,当1000个索引值发生更改时,该表的统计信息便可能需要更新,因为1000个值可能在该表中占有很大的比例.而对于包含10000000个索引条目的表来说,有1000个索引值发生更改的意义要小得多,因此统计信息便可能不会自动更新.
你可以选择是否要让sql server自动更新还是手动更新:数据库->属性->自动更新统计信息
手动更新:
请注意:sql server在对“统计信息”进行更新时,它是不会分析表的所有数据的,而是会从表中随机抽样,这样可以极大地减少这种统计信息的自动更新所带来的成本.所以有可能在某些情况下,统计采样无法获得表中精确的“统计信息”,这个时候我们可以手动更新,比如:我们可以指定对表中所有数据进行抽样以取得精确的“统计信息”,或者指定对表的多少行进行采样.
如何手动更新:
update statistics 表名 索引名 [with fullscan或者sample 数值 percent或者rows]
说明:
1:如果省略索引名将对表的所有索引进行手动更新
2:如果使用fullscan关键字,则表示对表中所有行进行采样,这样会费很长时间,但会得到更优的查询
3:如果使用sample 数值 percent则表示对整个表行的百分之几进行采样
4:如果使用sample 数值 rows则表示对整个表的只取多少行进行采样.
比如: 在work表创立两个索引 年龄,基本工资
如果执行:
1:update statistics work with fullscan[表示什么意思]
2:update statistics work with sample 10 percent[表示什么意思]
3:update statistics work with sample 10 rows[表示什么意思]
什么时候需要手动更新:如果索引列中添加、更改或删除大量数据请使用update statistics手动更新
I:创建索引
1:通过企业管理器:
A:索引文件组:可以把索引也放在数据库的文件组中.你可以把关于一个表中创建的索引与表放在一个文件组中,也可以把基于一个表的索引放在不同的文件组中,这样可以在查询时由表所在的驱动器与该表索引所在的驱动器同时并行查询,从而提高查询效率.
B:但是一个聚集索引只能够放在primary组中.
C:不自动重新计算:如果选择该项则sql server不会自动更新“统计信息”,当用户在对表作了大量的修改之后再查询时因为“优化器”使用的是“过时的统计的信息”,所以可能得不到最优的查询,除非用户手动更新.
2:通过sql语句.
格式:create [unique][clustered] index 索引名 on 表名(列[asc|desc]) with fillfactor=整数
说明:
A:如果省略unique则是非唯一索引
B:如果省略clustered表示一个非聚集索引
C:在列后面可以指明是升序还是降序,如果省略则为asc(升序),否则必须指明desc(降序)
D:如果要创建多列索引可以写多个列,列与列之间用逗号隔开.
例如:
A:create unique clustered index 年龄 on work(年龄 desc)
B:create unique clustered index 年龄,基本工资 on work(年龄 desc,基本工资)
思考:
假定你要创建一个聚集索引和一个非聚集索引,你是先创建非聚集索引还是先创建聚集索引
结论:
sql server会在删除或创建任何聚集索引的时候重新创建非聚集索引,所以在创建任何非聚集索引之前创建聚集索引.
J:删除索引:
注意以下两点:
1:当一个索引不再需要,可以将其从数据库中删除,以回收它当前使用的存储空间.这些回收的空间可以由数据库中任何对象使用.
2:当你把一个聚集索引删除后,sql servr必须把以前的同一个表上的所有非聚集索引重新创建一次,所以删除一个聚集索引比删除一个非聚集索引要花费更多的时间.
3:只有表的所有者或sa可以删除其索引.
方法:
A:通过企业管理器:打开表的设计窗口,单右->索引->删除
B:通过sql语句:格式:drop index 表名.索引名
设计、创建和维护索引(index)(下)
11:索引的维护操作:
12:索引的评估和分析:
13:为计算字段创建索引:
14:为视图创建索引:
15:索引优化向导.
K:索引的维护
你创建了一个索引之后,用户可能要对表进行修改,而为了让索引能发挥它的最大用途,必须对它进行维护.
我们通常对索引有下面的维护:
1:重建索引
一个索引已经创建好了,为什么还要去重建索引呢?
A:为什么要重建索引:
在数据库中创建索引时,查询所使用的索引信息存储在索引页中,随着用户对表进行不断的修改,填充因子会不断的改变,这样就会生成很多碎片,这显然不利于查询.我们可以重建索引以重新组织索引数据来达到清除碎片的目的.
B:怎么重建索引:
思考:假设你已经为work表作了一个“年龄”聚集索引,随着用户不断更新该表,使它产生很多碎片,现在要重建你该怎么办:[首先删除原先建的年龄索引,再来创建一个年龄索引,行吗]
结论:这样做虽然可以,但会花费更多的成本,因为我们已经知道,每用户删除一个聚集索引,时sql server会把该表所有的非聚集索引全部删除之后再重新创建,显然不划算,那么可以在不删除原有索引的基础上来新建一个与原索引一样的索引吗?当然可以.
那么可以看到不删除原有的索引而重新创建一个索引的好处,有以下两点:
1:免了删除和重新创建非聚集索引这些不必要的工作
2:可以使用现有索引中的数据排序次序,从而避免了对数据重新排序.这对于聚集索引十分有用,可以显著减少重建索引的成本.
方法:只需要在创建索引的时候加上with drop_existing关键字就行了.
比如:create unique clustered index 年龄 on work(年龄 desc) with drop_existing
思考:是否执行了这个命令之后就意味着所有的非聚集索引不会删除之后再创建了呢?
结果:当建的新的聚集索引与原聚集索引的列相同时,才不会删除非聚集索引,否则还是会删除非聚集索引之后再创建.
2:查看索引:
在创建索引之后我们可能需要
A:查看某个索引类型
B:一个表的全部索引
C:某个索引使用的数据库空间总量.
方法:
1:查看表中的索引
格式:sp_helpindex 表名
2:查看数据库中的全部索引及使用的空间
通过:任务面板
3:碎片整理
我们已经知道,当用户对一个表创建一个索引之后,由于用户对表不断的改变,会导致产生很多碎片.你既可以重建索引,也可以选择不重建索引,而直接对索引进行碎片整理.
方法:dbcc indexdefrag(数据库名,表名,表中的索引名)
比如:dbcc indexdefrag(陈文杰,work,年龄)[对数据库陈文杰表work里面的年龄索引进行碎片整理]
显示的信息会给出:有多少页扫描了,有多少页被移动了,有多少页被删除了
注意:若索引的碎片相对较少,则整理该索引的速度比生成一个新索引要快,这是因为碎片整理所需的时间与碎片的数量有关.对碎片太多的索引进行整理可能要比重建花更多的时间.
4:更名
方法:sp_rename /'表名.原索引名/',/'新索引名/',/'index/'
例如:sp_rename /'work.年龄/',/'年/',/'index/'[把work表“年龄”索引名改为“年”]
5:索引管理器:可以方便对选择的数据库中相应的索引进行修改,删除,还可以方便进行索引的新建删除等.
操作方法:在企业管理器中选择某个表->单右->管理索引
L:索引的评估和分析:
实际上评估一个查询是不是最优查询,并不是由时间来决定的,因为相同的一个查询在计算机很忙的时候运行所花费的时间绝对要大于计算机很空闲的时候运行所花费的时间,因为当计算机很忙的时候cpu要把时间分给其它的程序,这显然会延长一个查询所花的时间,而当计算机很闲时,相当于把cpu的时间全部给这个查询,可以减少运行时间,所以仅凭运行时间来判定一个查询是否最优是不精确的,那么我们可以根据这个查询所花费的成本来决定一个查询的优劣.可以通过“执行计划”来察看
方法:显示执行计划,快捷方式:ctrl+k
A:查询分析器是采用表扫描还是采用索引来执行查询.
B:如果采用索引查询,是用的哪个索引
C:查询所花费的成本.
i/o成本:用于操作的所有I/O活动的预计成本(I/O成本).该值应尽可能低.
成本:查询优化器执行此操作的成本占查询总成本的百分比.由于查询引擎选择最高效的操作执行查询或执行语句,因此该值应尽可能低.
M:为计算字段创建索引
计算列虽然不是表的的字段,但是可以参与查询,所以为了加快查询效率,我们有时候希望在计算列上创建索引,在计算列上创建索引的方法与在非计算列中创建索引一样,但是需要注意二点:
在创建表的时候[不是在表创建好之后],既在执行create table的时候必须满足:
1:为计算列的表达式上使用的表的字段类型不能有float型,被称为不确定或不精确
2:ANSI_NULLS:必须设置为on 方法:SET ANSI_NULLS on[一般情况下]
说明:默认为off,表示可以在查询中使用=null或<>null条件,否则不允许使用
N:为视图创建索引
我们知道视图并没有存储数据,而是存储定义,所以当视图在刚刚打开的一瞬间会根据定义从相关的表中收集数据,相当于从相关表中做一个查询,然后再把数据导入到视图中,也就是要动态生成与视图定义相关的结果集.
于是用户要对一个视图进行查询时,将经过两步查询:
表----------->视图---------->用户
查询 查询
但是对一个很大的表来说,如果用户在查询之前都要从基本表是导入数据,将是很费时的事,如果我们把定义视图的数据直接存储在视图中这样当用户去查询时,就会直接从视图中搜索数据,这显然可提高效率.具备有这种特点的视图被称为索引视图.
视图(包括数据)-------->用户
查询
思考:怎么验证当创建索引视图之后,确实把数据存储到视图里面去了.[任务板]
说明:
1:在视图上创建的第一个索引必须是唯一聚集索引.
2:在创建唯一聚集索引后,可创建其它非聚集索引,也就是说在视图上不能创建单一的聚集索引.
方法:
A:通过企业管理器:
单右-->设计视图---->单右---->索引管理:创建索引
B:sql语句:
格式:create [unique][clustered] index 索引名 on 视图名 (列[asc|desc])
很显然:除去视图上的聚集索引将删除存储的结果集.[如何验证:删除索引视图的聚集索引]
索引优化向导
可以这样说,没有哪个人能够真正的设计一个非常优秀的索引,因为这需要深入了解SQL Server的数据库结构、工作负荷和内部原理.即使是微软高级工程师也不敢说自己创建的索引是最完美的,况且你只是一个一般的使用者呢?考虑到这些,微软为我们提供了一个能够让大多数用户操作,而又不需要去深入了解sql server内部结构、原理的操作平台,去做一个最好的索引,这就是“索引优化向导”.
说明:
要想让sql server建更好的索引,必须要指明:
A:指明一个服务器以及该服务器中一个数据库,以及该数据库中一个或多个表.[因为索引是对表而言的]
B:由于要创建索引,而我们知道创建什么样的索引是和所执行的sql语句有关的,所以必须要让sql server执行一个包括许多sql语句的一个sql脚本文件,我们把它叫工作负荷,为了让创建的索引能够真实的帮助你提高查询效率,要把与你工作相关的经常执行的sql语句放在一个脚本文件里面
C:假设你在使用“优化向导”之前已经创建一些索引,那么你可以选择让sql server是保留原有索引还是让sql server“优化向导”通过分析来决定是如何对现在索引进行更正,而增加新的索引.很显然如果你选择“要保留现有索引”,也就是说不管你以前的索引做得好还是坏,sql server都不会对你以前的索引提出真实的建议,这也许会使sql server“优化向导”没有办法提出新的建议,因为有可能某些确实可以提高查询效率的的建议是与你以前的索引情况相反的,而你要选择了“保留了现有索引”,所以不主张保留“现有索引”.
D:在sql server索引优化向导为你建议了新的索引之后会对以前的索引作一些操作比如:修改或删除,而创建新建议的索引
E:同时为了让用户能够对使用“优化向导”之前与使用“优化向导”之后的结果作一个对比会给出一个对比列表
方法:向导---------->优化向导
说明:
A:优化模式:优化模式决定了“优化向导”建议索引的准确性.
快速:建议的索引最优性不是最好的,但可以节约时间.
彻底:建议的索引比起“快速”与“适中”而言更准确.
建议:使用彻底
B:将要抽样的工作负荷查询的数目限制为指定要抽样的工作负荷查询的数目.默认值为200个查询.从指定的工作负荷文件中随机选取查询.如果设置值超过工作负荷文件中的查询数,则优化所有查询.
C:用于建议索引的最大空间(MB)
“优化向导”建议的所有索引的最大空间(以MB为单位),默认空间大小是当前数据大小的三倍.
D:每个索引的最大列数
指定索引优化向导建议的多列索引中的列的最大数.允许的最大值是16,这是默认值.
E:报表
A:索引使用报表:给出在使用“优化向导”之前与建议之后的每个表中每个索引的使用率和大小.
B:查询关系报表:给出在使用“优化向导”之前与建义之后每个查询使用的索引的情况.
C:优化摘要表:给出在使用“优化向导”之后,有多少个索引被优化,删除了多少个以前的索引,新建了多少建议的索引,优化了多少个查询,分析的时间.
试验:做一个work表:职工号,姓名,性别,年龄,学历,基本工资.有180万行.
在查询分析器中写上:
select * from work where 年龄<25
select * from work where 基本工资<1500
保存作为工作负荷
分析:不用优化向导,要对提高这个查询效率而设置索引
讨论方法:并按讨论的方法在work表创建索引.
并运行:记下成本.
通过“优化索引向导”来创建索引
说明:在运行“优化索引向导”的时候,先后选择“保留索引”和“不保留索引”,看优化索引向导所提出的建议是否一样,执行完“优化索引向导”以后,再运行:记下成本.比较两次的成本. 2004-3-11 08:11
冒顿
Moderator
积分 236
发贴 136
注册 2004-2-24
来自 湖北武汉
状态 离线 transact ---sql查询基础
1:select语句最简单的用法.
2:where子句的用法.
3:用in,not in和between关键字来缩小查询范围.
4:用like子句来实现模糊查询.
5:用order by子句来为结果排序.
A:select 语句最简单的用法
work表:职工号,姓名,性别,年龄,学历,职称,基本工资
A:简单的select查询格式:select 列名[1..n] from 表名 [从一个表中有选择性的查看某些列,而不是全部]
比如:select 职工号,姓名,学历,基本工资 from work [从work表中检索出职工号,姓名,学历,基本工资的信息]
B:select * from 表名 [从表中检索出全部的列]
C:可以使用select语句进行无数据源查询,就是查询的不是表,而是系统变量.
比如:select @@version[获得版本],select @@language [获得sql server使用的语言]
D:使用top关键字.
作用:用于只返回前面一定数量的数据.
用法:1):top n值:返回一个表中前n行的数据.
2):top n值 percent[返回一个表中百分之n的结果] 格式:必须紧跟在select的后面,所有列前面
比如:1:select top 10 职工号,姓名,学历 from work[从work表中返回前10行职工号,姓名,学历等信息]
[不要写成:select 职工号,姓名,学历 top 10 from work]
2:select top 10 percent * from work [从work表中返回前10%的记录]
3:使用计算列 [score表:姓名,语文,数学,化学]
比如:select 姓名,语文,数学,化学,语文+数学+化学 from score [会显示无列名]
或:select *,语文+数学+化学 from score
说明:可以在计算列上加上as指定列名,为计算列指定列名
可以计算列上使用:+,-,*,/,%[取余],或字符连接字符“+”
比如:select /'职工号: /'+职工号+/'姓名:/'+姓名+/'性别 /'+性别 from work
E:使用distinct[种类]
作用:返回无重复的行.
检索出work表中有多少种学历
select 学历 from work [将会得到重复的值]
改为:select distinct 学历 from work
说明:distinct只能用于列名前面,是对整个列进行检验.
比如:select 学历,distinct 职称 from work[分析会得到什么答案]
只能改成:select distinct 学历,职称 from work
[则会显示出学历,职称没有全部都相同的记录,意义:可以检索出各学历各个职称的分布情况]
F:操作查询的列名
可以根据实际需要对查询数据的列标题进行修改或者为没有标题的列增加标题.对列名进行操作有三种方式:
1):原列名 新列名
比如:select 职工号 /'职工编号/'(或职工编号),姓名,学历 from wrok[对已经存在的列名进行标题操作]
再如:select *,语文+数学+化学 总分 from score[对没有标题的列增加标题]
2):用“=”号 格式:新列名=旧列名
3):用as关键字 格式:旧列名 as 新列名
说明:
1:当使用中文列名时,可以不加引号.
2:当使用的英文列名中当中有空格时,必须加上引号或者中括号.
3:可以在一个表达式中同时使用上述的三种方法:
比如:select 职工号 as 职工编号,姓名 员工姓名,员工年龄=年龄 from work
B:where 子句的用法
使用select语句可以对表中的列进行取舍,而不能对表中的行进行取舍,而使用where子句可以对表的行进行筛选
比如:1:从work中检索出所有年龄大于25岁的职工.
select * from work where 年龄>25
2:从work中检索出所有年龄在20与40之间的职工.
select * from work where 年龄>25 and 年龄<40
3:从work中检索出学历是本科和大专的职工.
select * from work where 学历=/'本科/' or 学历=/'大专/'
说明:在where中可以运用关系运算符和逻辑运算符
关系运算符: >,>=,<,<=,=,<>等.
逻辑运算符:and or not
比如:检索出学历是本科,大专,中专的职工.
select * from work where not 学历=/'中专/'
C:使用in 或 not in,between and
in:表示位于集合里面.
not in:表示不位于集合里面.
between and:表示在两者之间 [格式:列 between 上界值 and 下界值]
举例:
1:检索出work表学历是大专,本科的职工.
select * from work where 学历 in(/'大专/',/'本科/') [注意引号不能少]
2:检索出职称经理,厂长,文员的职工. [假定职称只有:经理,厂长,文员,主管,秘书]
select * from work where 职称 not in(/'主管/',/'秘书/')
3:检索出年龄在20到40之间的职工.
select * from work where 年龄 between 20 and 40
D:使用like子句进行模糊查询.
说明:like子句中的查询条件通过与通配符一起使用.sql server为我们提供了以下四种作用的通配符.
A:%(百分号)表示0个或多个任意字符.
B:_(下划线):表示单个的任意字符.
C:[]表示方括号里面列出的任意一个字符.
D:[^]表示任意一个没有在方括号里面列出的字符.
举例:
1:检索出姓张或姓李的人.
select * from work where 姓名 like /'张%/' or 姓名 like /'王%/'
或者:select * from work where 姓名 like /'[张王]%/'
2:检索出姓名为两个字的职工.
select * from work where 姓名 like /'__/'
3:检索出姓名为三个字符且第二个字符为“小”的职工.
select * from work where 姓名 like /'_小_/'
4:检索姓名为二个字或三个字的职工.[假设没有姓名为四个字的职工]
select * from work where 姓名 like /'__/' or 姓名 like /'___/'
或者:select * from work where len(姓名 ) in (2,3)
5:检索出姓为“张、黄、刘”的职工.
select * from work where 姓名 like /'[张黄刘]%/'
6:检索出既不姓“刘”与不姓“张”的职工.
select * from work where 姓名 like /'[^张刘]%/'
7:假设work表中有基本工资等级字段取值可以从A--Z的任意字符.要检索出工资等级为A到G之间的职工.
1:select * from work where 基本工资等级=/'A/' or 基本工资等级=/'B/'...or 基本工资等级=/'G/'
2:select * from work where 基本工资等级 in (/'A/',/'B/',/'C/'.../'G/')
3:select * from work where 基本工资等级 like /'[A-G]/'
说明:可以用方括号和连字符“-”来指定一个范围.
再如:select * from work where 年龄 like /'2[1-5]/'
检索出年龄在21到25之间的职工.
E:转义字符的使用:
使用通配符可能会产生这样的问题,万一查询的字符中包括了通配符作为字符串的一部分,该如何处理,transact-sql为我们提供的转义字符可以解决这个问题: 用关键字escape.
用法:凡是遇到escape后第一个字符,表示通配符的字符仅作普通字符处理.
举列:1:检索出转义字符表b列中包括“%”字符的所有记录
select * from 转义字符 where b like %A%% escape /'A/'
2:检索出转义字符表b中以“c]/'”结尾的记录
select * from 转义字符 where b like /'%c]/'/'/'
说明:在sql中“/'/'”才算“/'”
F:用order by子句来排序.
说明:可以用order by子句来为查询之后的结果来排序.需要注意的是:执行该查询之后,虽然显示在用户面前是排好序的列,但它不会改变原表的排列情况
格式:order by 列名 asc|desc
说明:1:对一个列指定排序次序时,默认为升序(asc),如果要特别指明降序必须指明desc关键字.
比如:检索出所有职工,并按基本工资降序排序.
select * from work order by 基本工资 desc
2:一般情况都是对一个列进行排序,也可对多个列进行排序,此时只写一个order by就行了,列与列之间用逗号隔开
比如:检索出所有职工,先按年龄降序排序,年龄相同再按基本工资升序排序.
select * from work order by 年龄 desc,基本工资[asc]
注意:select * from work order by 基本工资 desc,年龄[asc] 完全不一样.
3:可以使用列的序号来进行排序列的指定.
比如:select 职工号,姓名,年龄,基本工资 order by 4 desc [4:表示“基本工资”的位置]
4:可以根据未曾出现在select列表中的值进行排列.
比如:select 职工号,姓名,职称 from work order by 基本工资 [基本工资并没有出现在select中]
5:如果有where子句则order by必须放在where的后面.
比如:按基本工资的降序检索性别是男的所有职工.
select * from work where 性别=/'男/' order by 基本工资 desc
select * from work order by 基本工资 desc where 性别=/'男/' [错错错错]
6:order by子句后面是排序的列,也可是计算列,支持别名.
比如:检索出score表中所有同学的总分并按总分升序排序
select 姓名,语文+数学+化学 as 总分 from score order by 总分
--------------------------------------------------------------------------------
-- 作者:hanzhufeng
-- 发布时间:2004-8-29 10:17:25
--
编辑维护表格数据
1:利用insert语句向表中插入新行.
2:利用update语句实现表中数据的修改.
3:利用delete语句实现表中数据的删除.
A:使用insert语句向表中添加数据
格式:insert 表名(列名1,列名2....列名n) values(表达式1,表达式2...表达式n)
比如:1:insert work(职工号,姓名,性别) values(/'0001/',/'陈小表/',/'男/')
说明:如果表中没有被指定的列,其列值为null,也就是如果没有被指定列中有不能为空的列,则插入失败
2:“值列表”必须和被指定的列有相同的个数.
3:可以省略insert里面的/'列说明/',条件是必须为表中每一个列提供值.
比如:insert work values(/'034/',/'陈立/',/'男/',23,/'文员/',/'经理/',1400) 不能少,否则会发生错误
4:注意类型必须能够相互转化.
比如:insert work(职工号,基本工资) values(/'001/',/'abc/') 因为/'abc/'无法与int型转换而出错
上述语句一次只能插入一行语句,下面的语句一次可以一次性插入多行数据.
格式:insert 目的表名(目的表列名1...目的表列名n)
select 源表列名1...源表列名n from 源表名 [where 条件]
比如:有一空的address表:职工号,姓名,婚否,住址,联系方式.现在要把work表中学历是大专或者本科的职工的职工号和姓名列的值全部都插入address表.
insert address(职工号,姓名)
select 职工号,姓名 from work where 学历 in(/'本科/',/'大专/')
B:利用update实现数据的修改
格式:update 表名 set 列名1=表达式,列名2=表达式....列名n=表达式 [where 条件]
比如:1:需要把work表学历是本科的基本工资提高1%
update work set 基本工资=基本工资*1.01 where 学历=/'本科/'
2:有一个录取表:姓名,性别,学历,所学专业,是否有工作经验,录取否
要求把符合:学历是大专或大专以上的,并且所学专业与计算机相关的,有工作经验的人录取.
update 录取 set 录取否=/'是/'
where 学历 not in(/'高中/',/'中专/') and 所学专业 like /'%计算机%/' and 有无工作经验=/'有/'
说明:1:如果不加条件会更新表中每一行,但只能更新一个表.
2:可以更新一个表中的多个字段,字段与字段之间用逗号隔开.
3:可以在update后面使用[from 表名]表示以其中一个表作为一个条件而去更新另一张表.
举例:A:把work销售部的员工的基本工资加上100.[work,部门表]
update work set 基本工资=基本工资+100 from 部门
where 部门.部门编号=work.部门编号 and 部门名称=/'销售部/'
B:更新work表前5条记录,把基本工资加上100
update work set 基本工资=基本工资+100 from (select top 5 * from work) as temp
where temp.职工号=work.职工号
C:使用delete删除表中的数据
格式:delete 表名 where 条件 [注意:不要from]
例如:删除work表职称是“经理”的职工
delete work where 职称=/'经理/'
说明:如果省略where条件则删除表中的所有记录
例如:delete work [删除work表的全部记录]
可以加上[from 表名 where 条件],这样是以后面一个表作条件来删除前面一个表相应的记录.
比如:delete work from 部门
where work.部门编号 not in(select 部门编号 from 部门)