第一部分:数据库相关概念
狭义:
- 存情数据的仓库
广义:
- 可以对数据进行存储和管理的软件以及数据本身统称为数据库
数据库是由表、 关系、 操作组成
为什么需要数据库
- 几乎所有的应用软件的后台都需要数据库
- 数据库存储数据占用空间小容易持久保存
- 存储比较安全
- 容易维护和升级
- 数据库移植比较容易
- 简化对数据的操作
- 为将来学习0racle做准备
B/s架构里面包含数据库
数据库的安装和卸载sq12000
- 解决挂起的问题
预备知识
- 学习SqlServer2005必须的先学一门编程语言么
- 不需要,但是懂一门编程语言的话会有助于学习sqlserver2005 的TL SQ
数据结构和数据库的区别
- 数据库是在应用软件级别研究数据的存储和操作数据结构是在系统软件级别研究数据的存储和操作
什么是连接 【重点】
- 有了编程语言为什么还需要数据库
- 对内存数据操作是编程语言的强项, 但是对硬盘数据操作却是编程语言的弱项对硬盘数据操作是数据库的强项, 是数据库研究的核心同题
建议初学者从三个方面学习数据库数据库是如何存储数据的
- 字段记录表约束(主键外键唯一键非空 check default触发器)
数据库是如何操作数据的
insert update delete T-SQL
存储过程函数触发器数据库是如何显示数据的
select
(重点的重点)
必各的一些操作
- 如何建数据库
- 如何删除数据库
- 如何附加和分高数据库
- 设置登录用户名和密码
- 如何创建用户
数据库是如何解决数据存储问题的 【最基础内容, 必须掌握】
1.表的相关数据
字段
- 一个事物的某一个特征
记录
- 字段的组合表示的是一个具体的事物
表
- 记录的组合表示的是同一类型事物的集合
表和字段、记录的关系
- 字段是事物的属性
- 记录是事物本身
表是事物的集合
列
- 字段的另一种称谓
属性
- 字段的另一种称谓
元组
- 记录的另一种称谓
2. create table命令
- 通过图形化界面建表
create table最后一个字段的后面建议不要写逗号说明:简単掌握后面我们会再详细的介绍
3. 什么是约束
定义
- 对一个表中属性操作的限制叫做约束
分类
- 主键约束
不允许重复元素選免了数据的冗余
- 主键约束
外键约束
- 通过外键约束从语法上保证了本事物所
- 关联的其他事物一定是存在的
事物和事物之间的关系是通过外键来体现的
check约束
- 保证事物属性的取值在合法的范围之内
default约束
- 保证事物的属性一定会有一个值
唯一约束
- 保证了事物属性的取值不允许重复,,但允许其中有一列且只能有一列为空
间题:
ul,i que键是否允许多列为空?
答:
- SqlServer2005只允许一个uni que列为空
- Oracle1 IG允许多个uni que列为空
not null
- 要求用户必须的为该属性赋一个值,否则语法出错!
- 如果一个字段不写n,11也不行not n,11
- 则默认是rm11即默认允许为空,用户可以不给该字段赋值
- 如果用户没有为该字段赋值,则该字段的值默认是nd1
要注意nu11和 default的区别
- 相同点:
- 都允许用户不赋值
- 不同点:
- nu11修饰的字段如果用户不赋值则默认是nu1 1
- default修饰的字段如果用户不赋値则默认是default指定的那个值
4. 表和约束的异同
- 数据库是通过表来解决事物的存備同题的
- 数据库是通过约束来解决事物取值的有效性和合法性的问题
建表的过程就是指定事物属性及其事物属性各种约束的过程
什么是关系
- 定义:
表和表之间的联系
- 定义:
实现方式
- 通过设置不同形式的外键来体现表和表的不同关系
分类(假设是A表和B表)
一对一
既可以把表A 的主键充当表B的外键
也可以把表B的主键充当表A的外键一对多【重点】
把表A 的主键充当表B的外键
或者讲: 把A表的主键添加到B表来充当B表的外键
在多的一方添加外键
- 多对多
多对多必须的通过単独的一张表来表示
例子
- 班级和教师
- 班级是一张表
- 教师是一张表
- 班级和教师的关系也是一张表
6. 主键
定义
- 能够唯一标示一个事物的一个字段或者多个字段的组合, 被称为主键
主键的特点【重点】:
- 含有主键的表叫做主键表
- 主键通常都是整数不建议使用字符串当主體(如果主體是用于集群式服务,才可以考虑用字符串当主體)
- 主键的值通常都不允许修改, 除非本记录被删除
- 主键不要定义成i d, 而要定义成表名 Id或者表名_i d
- 要用代理主键,不要用业务主键
- 任何一张表, 强烈建议不要使用有业务含义的字段充当主键
- 我们通常都是在表中単独添加一个整型的编号充当主键字段
- 主键是否连续增长不是十分重要
7. 外键
- 定义:
- 如果一个表中的若干个字段是来自另外若干个表的主键或唯一键
则这若干个字段就是外键
- 如果一个表中的若干个字段是来自另外若干个表的主键或唯一键
注意:
- 外键通常是来自另外表的主键而不是唯一键, 因为唯一键可能为M11
- 外键不一定是来自另外的表, 也可能来自本表的主键
- 含有外键的表叫外建表, 外键字段来自的那一张表叫做主键表
问题:
- 先删主键表还是外建表?
答集: 先删外建表
如果先删主键表,会报错,因为这会导致外建表中的数据引用失败
第二部分:查询
査询【最重要难度最大,考试必考内容,强烈建议所有的学生都要熟练掌握査询的内容】
1.计算列
1 |
|
1 |
|
–ok
-一输出的行数是emp表的行数 每行只有一个字段,
select5;
–ok
-一不推荐
注意:
- 在0racle中字段的别名不允许用单引号括起来
- 但是sqlserver2005却允许,,因此为了兼容性 -最好字段别名用双引号括起来, 不要用单引号
2. distinct【不允许重复的】
1 | ```--distince deptno会过滤掉重复的deptno |
1 | --distinct也可以过滤掉重复的nu11 或者说如果有多个nu11只输出一个 |
等价于1
where sa1 between1500 and3000
- -一査找工资小于3ooo或大于1 5oo的所有的员工的信息
from emp where sa1<1500 or="" sa1="">3000```1500> 1
2等价于
```select* from emp where sa1 not between1500 and3000
4. in【属于若干个弧立的值】
select*from emp where sa1 in(1500, 3000, 5000)
1
2
3等价于
```select* from emp
where sa1=1500 or sa1=3000 or sa1=5000
1 |
|
- -一数据库中不等于有两种表示:
!= <>
推荐使用第二种 - -一对或取反是并且对并且取反是或
5. top【最前面的若干个记录专属于sqlserver的语法,不可移植到其他数据库】
1 | ``select top15 percent* from emp; ``` -一输出的是3个,不是2个 |
- -一本程序证明了: r,u11不能参与任何数据运算否则结果永远为空
一正确的写法是:
ename, sa1*12+isnu11(comm, 0)″年薪″ from emp;``` 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33--is null(comm, 0)如果comm是nu11就返回零否则返回comm的值
**7. order by 【以某个字段排序】**
- `order by a, b` --a和b都是升序
- `order by a, b desc` --a升序 b降序
- `order by a desc, b` -a降序 b升序
- `order by a desc, b desc` --a和b都是降序
- 文字描述:
- 如果不指定排序的标准,则默认是升序升序用asc表示默认可以不写
- 为一个字段指定的排序标准并不会对另一个字段产生影响强烈建议为每一个字段都指定排序的标准
**例子:**
- asc是升序的意思默认可以不写 desc是降序
`select* from emp order by sa1;` 一默认是按照升序排序
select*from emp order by deptno, sa1;
- -一先按照deptno升序排序,如果deptno相同,再按照sa1升序排序
select* from emp order by deptno desc, sa1;
- -一先按deptno降序排序如果deptno相同再按照sal升序排序
- -一记住sa1是升序不是降序
`--orderby a desc, b, c, d` desc只对a产生影响不会对后面的b c d产生影响
```select*from emp order by deptno, sa1 desc-一问题: desc是否会对deptno产生影响?
- -一答案:不会
- -一先按deptno升序,如果deptno相同,再按sa1降序
8.模糊査询 【搜索时经常使用】
- 格式:
select字段的集合 from表名 where某个字段的名字1ike匹配的条件
匹配的条件通常含有通配符
通配符:
%
表示任意o个或多个字符emp where enamelike'%A%' ``` 1
2
3
4
5
6
- --ename只要含有字母A就输出
```select*from emp where enamelike'A%' ```
- -ename只要首字母是A的就输出
```select* from emp where enamelike'%A'-ename只要尾字母是A的就输出
[这是下划线不是減号]
表示任意单个字符
from emp where enamelike'_A%'``` 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
- -ename只要第二个字母是A的就输出
**[a-f]**
- a到f中的任意单个字符只能是a b c d e f中的任意一个字符
`select* from emp where`
- `enamelike'_[A-F]%'''`-一把ename中第二个字符是A或B或c或D或E或F的记录输出
**[a, f]**
- a或f
**[a-c]**
- 不是a也不是b也不是c的任意单个字符
`select* from emp where enamelike'_[A-F]%'''`-一把ename中第二个字符不是A也不是B也不是c也不是D也不是E也不是F的记录输出
**注意:**
- 匹配的条件必须的用单引号括起来 不能省略也不能改用双引号
通配符作为不同字符使用的同题
```select* from student where namelike'%\%%' escape'\' ``` -一把name中包含有%的输出```select* from student where namelike'%\_%' escape'\'``` 一把name中包含有_的输出
**9.聚合函数【多行记录返回至一个值通常用于统计分组的信息】函数的分类**
- 単行函数
- 每一行返回一个值
- 多行函数
- 多行返回一个值
- 聚合函数是多行函数
**例子:**
```selectlower(ename) from emp;``` 一最终返回的是行1ower0是单行函数
`select max(sa1) from emp;` 一返回行max0是多行函数
**聚合函数的分类**
- max()
-min()
-avg() 平均值
-count()求个数
-count(*)
返回表中所有的记录的个数
`select count(*) from emp;` -一返回emp表所有记录的个数
count(字段名)
- 返回字段值非空的记录的个数, 重复的记录也会被当做有效的记录
```select courlt(deptno) from emp;-一返回值是这说明deptno重复的记录也被当做有效的记录
coul,it(l1omm) from emp;`` 1
2
3
4
5
6
7
- -一返回値是这说明 c omm为ru」1 1的记录不会被当做有效的记录
- count(distinct字段名)
- 返回字段不重复并且非空的记录的个数
```select count(distinct deptno) from emp;
-一返回值是 统计deptno不重复的记录的个数
注意的问题
- 判断如下sq1语句是否正确
1 | select max(sa1) -最高工资″, min(sa1)″最低工资″, count(*)″员工人数″ from emp; --ok |
as″部门平均工资⊠ from emp group by deptno
注意:
- 理解: gro·up by a, b, c的用法
- 先按a分组,如果a相同,再按b分组,如果b相同,再按c分组
- 最终统计的是最小分组的信息
- 一定要明自下列语句为什么是错误的
select deptno, avg(sa1) as″部门平均工资⊠, ename
from emp
解oup by deptno
select deptno, ename
from emp
解oup by deptno
select deptno, job, sa1
from emp
解oup by deptno, job
记住:使用了gro1」p by之后select 不能出现组内的详细信息中只能出现分组后的整体信息,
11. having【对分组之后的信息进行过滤难点】
having子句是用来对分组之后的数据进行过滤
因此使用having时通常都会先使用group by如果没使用gro·L!p by但使用了having
则意味着having把所有的记录当做一组来进行过滤
极少用count(*) 1
2from emp
having avg(sa1) > 1000having子句出现的字段必须的是分组之后的组的整体信息having子句不允许出现组内的详细信息
尽管select字段中可以出现别名
- 但是having子句中不能出现字段的别名,
只能使用字段最原始的名字原因不得而知
having和where的异同
相同的:
都是对数据过滤,只保留有效的数据
where和having一样,都不允许出现字段的别名,,只允许出现最原始的字段的名字,本结论在S‘11Server2005和Olracle11G都成立
- 不同:
- where是对原始的记录过滤 having是对分组之后的记录过滤
- where必须的写在having的前面,顺序不可颠倒否则运行出错
例子:
一把工资大于,
-一统计输出部门平均工资大于的部门的部门编号部门的平均工资select deptno, avg(sa1)″平均工资″, count(*)″部门人数″,,max(sa1) ″部门的最高工资″
from emp
where sa1 >2000 –where是对原始的记录过滤
group by deptno
having avg(sa1) > 3000 -一对分组之后的记录过滤
一判断入选语句是否正确
select deptno, avg(sal)″平均工资″, count(*)″部门人数″,,max(sa1) ″部门的最高工资″ from
emp group by deptno having avg(sa1) >3000 -一对分组之后的记录过滤 where sa1 >
2000 一一where写在了having的后面 error
12.连接査询
定义
- 将两个表或者两个以上的表以一定的连接条件连接起来
- 从中检索出满足条件的数据
分类
内连接【重点的重点也是难点的难点】
select... fromA, B
的用法
产生的结果:
- 行数是A和B的乘积
列数是A和B之和
或者说
油表的每一条记录都和B表的每一条记录组合在一起形成的是个笛卡尔积或者说:
- 把B表的每一条记录都和A表的每一条记录组合在一起形成的是个笛卡尔积
注意:
1 | 输出结果和 |
是一模一样的
例子
-一输出70行11列1
2
3
4
5
6
7
8
9
10
11
12
13
14
**2. select... from A, Bwhere... 的用法**
```select... from A, B ``` --A和B可以互换
产生的簡卡尔积, 用where中的条件进行过滤
**例子:**
-一输出5行11列
select*
from emp, dept --dept和emp互换输出结果不变
where empno= 7369
- select... from A join B on... select... from A join B on
- SQL92标准和 SQL99标准的区别
```select... from A, B where.
1 | 输出结果是一样 |
1 |
|
注意:
- 若干个select子句要联合成功的话,必须的满足两个条件
- 这若干个select子句输出的列数必须是相等的
- 这若干个se1 ect子句输出列的数据类型至少是兼容的
identity
【主键自动增长,用户不需要为identity修饰的主键赋值】
用户如何手动给被i dent i ty修饰的主键赋值不重要
表中删除数据后又插入数据会导致主键不连续递增 怎么办?
主键是否连续增长不十分重要
视图
- 为什么需要视图
示例
求出平均工资最高的部门的编号和部门的平均工资
总结:
- 简化査询
- 避免了代码的冗余
- 避免了书写大量重复的sq1语句
- 什么是视图
- 视图从代码上看是一个select语句
- 视图从逻辑上看被当做一个虚拟表看待
- 如何创建视图
create view
视图的名字
as
-se1 ect的前面不能添加begin
select语句
-se1 ect的后面不能添加end
注意的问题
- 创建视图的 se1 ec t语句必须的为所有的计算列指定别名
-error
create view v$_a
as
select avg(sa1) from emp;
-ok
create view v$_a
as
select avg(sa1) as ⊠avg_sa1″ from emp;
- 视图不是物理表,是虚拟表
- 不建议通过视图更新视图所依附的原始表的数据或结构
视图的优点
- 简化査询
- 增加数据的保密性
视图的缺点
- 增加了数据库维护的成本
- 视图只是简化了査询,但是并不能加快査询的速度这也是视图使用不足的地方
事务【重要】
- 初学者必须要理解的三个概念
事务是用来研究什么的
- 避免数据处于不合理的中间状态
- 转账
怎样保证多用户同时访间同一个数据时呈现给用户的数据是合理的
很复杂,现在人类仍然投有设计出很好的解决办法!事务和线程的关系
- 事务是通过锁来解决并发访问的
- 线程同步也是通过锁来解决并发访同的 synchronized
所谓并发访同是指: 多用户同时访同同一个数据
事务和第三方插件的关系
- 直接使用事务库技术难度很大 很多人是借助第三放插件来实现
- 因此我们一般人不需要细细的研究数据库中事务的语法细节
第三方插件要想完成预期的功能, 一般必须的借助数据库中的事物机制来实现
- 索引
- 存储过程游标
- TL_SQL 触发器
分页査询
- 总结
假设每页显示n条记录, 当前要显示的是第m页
表名是A 主键是A_id
select top n
from A
where A_id not in(select top (m-1)n A_id from emp)