author:QYX
数据定义语言(DDL): 提供定义关系模式, 删除关系, 修改关系模式的命令
数据操纵语言(DML):SQL DML 提供从数据库中查询信息, 插入元组, 删除元组, 修改元组的能力
完整性: DDL 包括定义完整性约束的能力, 保存在数据库的数据必须满足所定义的完整性约束. 破坏完整性约束的更新是不允许存在的
视图: DDL 包括定义视图的命令
事务控制: SQL 包括定义事务开始和结束的命令
嵌入式 SQL 和动态 SQL: 嵌入式 SQL 和动态 SQL 定义 SQL 语句如何嵌入到通用编程语言中
授权: DDL 包括定义对关系和视图访问权限的命令
DDL 能定义每个关系的信息:
1 每个关系的模式
2 每个属性的取值类型
3 完整性约束
4 每个关系维护的索引集合
5 每个关系的安全性和权限信息
6 每个关系在磁盘上的物理存储结构
基本类型
SQL 定义了多种固有的数据类型
char 固定长度的字符串
varchar 可变长度的字符串
int 整数类型
smallint 小整数类型
numeric(p,d) 定点数 这个数有 p 位数字(加上一个符号位), 其中 d 位数字在小数点右边
real,double precision 浮点数与双精度浮点数, 精度与机器相关
float(n) 精度至少为 n 位的浮点数
空值: 缺失的值, 该值可能存在但并不为人知, 或者根本可能不存在, 我们应该避免空值的使用
char 存放固定长度的字符串, 例: 属性 A 的类型是 char(10), 如果我们为该属性存入一个 "AAA", 那么该字符串会在后面追加 7 个空格来使其达到 10 个字符的长度
varchar 相反, 他不会追加
SQL 也提供 nvarchar 类型来存放 Unicode 表示的多语言数据, 很多数据库也允许 varchar 类型存放 Unicode(采用 UTF-8 表示)
基本模式定义
create table 建表定义
primary key 主键, 主码必须非空且唯一
foreign key 外键, 外键声明表示关系中任意元组在属性 (A1,A2,..) 上的取值必须对应于关系 s 中某元组在主码上的取值 foreign key (xxx) references xxx(xxx)
not null 非空约束
unique 唯一约束
SQL 禁止破坏完整性约束的任何数据库的更新
常用命令
delete from xxx
从表中删除数据
drop table xxx
删除表
alter table add A D alter table r drop A
更改表结构
A 为属性名, D 为属性的域
SQL 查询的基本结构
select from where 查询输入是在 from 子句中列出的关系
distinct 去除重复
select distinct dept_name from dept
all 可以使用 all 来显式指定不去除重复(sql 默认不去除重复)
select all dept_name from dept
where 子句允许我们只选出那些在 from 子句的结果关系中满足特定谓词的元组
SQL 允许在 where 子句中使用 and or not,<= >=> <>
多关系查询
例
- select name,dept.dept_name.age
- from dept,department
- where dept.ID=department.ID
为何我没在 name 和 age 中加入前缀呢
因为 name 和 age 都是只出现在一个关系中, 因此不需要区分
select 子句 where 子句 from 子句的作用如下
select 子句用于列出查询结果中所需要的属性
from 子句是一个查询求值中需要访问的关系列表
where 子句是一个作用在 from 子句中关系的属性上的谓词
执行顺序 from where select
笛卡尔积连接
- select name,course_id
- from dept,course
这种笛卡尔积会包含来自 from 子句中所有关系的所有属性, 两个表的所有元组都要进行组合, 这种笛卡尔积没有任何意义
一般我们使用 where 子句来限制笛卡尔积所建立的集合
- select name,course_id
- from dept,course
- where deot,ID=course.ID
通常来说, 一个 SQL 查询的含义可以理解为
1 为 from 子句中列出的关系产生笛卡尔积
2 在 1 的结果上应用 where 子句中指定的谓词
3 对于 2 结果中的每个元组, 输出 select 子句中指定的属性
上述只是让各位明白一个 SQL 查询的结果应该是什么样的, 而不是这个结果是这样被执行的, 在 SQL 的实际实现中不会执行这种形式的查询, 它会通过 (尽可能) 只产生满足 where 字符谓词的笛卡尔积元素来进行优化执行
自然连接
自然连接运算作用于两个关系, 并产生一个关系为结果
自然连接只考虑属性相同且取值相同的元组对
- select name,.course_id
- from dept,course
- where dept.ID=course.ID
可以使用自然连接改变为
- select name,.course_id
- from deptnatural join course using (ID)
在实际中如果去掉 using 那么将考虑 dept,course 中所有属性相同且取值相同的元组对
而 using 指定了只需要匹配那些属性的取值即可
附加运算
更名运算
select name as new_name from dept
或
- select name,.course_id
- from dept as D,course as C
- where D.ID=C.ID
字符串运算
SQL 使用一对单引号来标示字符串, 如果单引号是字符串的一部分, 那么就用两个单引号来标示, 如字符串 "it' s right"可表示为"it ''s right" (注意不是双引号是两个单引号)
SQL 标准中, 字符串严格区分大小写 (比如 oracle), 如 oracle,'my'='MY'的结果是假的(false), 但在一些数据库中(MySQL 或者 sqlserver) 则对于大小写的区分没有这么严格
SQL 允许多种字符串函数, 如 || 串联, upper(s) 转换大写 lower(s) 转换小写
like 匹配字符串
% 匹配任意字符串
_ 匹配任意一个字符
- select name,.age
- from dept
- where dept_name like 'A%'
匹配 dept_name 以 A 开头的名字和年龄
如果 % 或者_也要运用要匹配中, 则可以使用 escape 关键字来定义转义字符
- select name,.age
- from dept
- where dept_name like 'A\%C%' escapes '\'
匹配 dept_name 以 A%C 开头的名字和年龄, 使用 escape 定义 \ 为转义字符
排列元组显示次序
- order by asc(升序, 默认) desc(降序)
- select name
- from dept
- where dept_name='ADC'
- order by name desc
between 关键字
- select name
- from dept
- where age between 20 and 30
等价于
- select name
- from dept
- where age <=20 and age>= 30
类似可以使用 not between
集合运算
并运算
union intersect except, 并 交 差(三者都是自动去重)
- (select name
- from dept
- where dept_name='AAA')
- union
- (select name
- from dept
- where dept_name='BBB')
输出结果就是保护 AAA 和 BBB 的信息, union 自动去重, 如果想要保留就是要 union all
- (select name
- from dept
- where dept_name='AAA')
- union all
- (select name
- from dept
- where dept_name='BBB')
交运算
比如我们要找出 2009 和 2010 年同时开设的所有课程
- (select course_id
- from course
- where course_year=2009)
- intersect
- (select course_id
- from course
- where course_year=2010)
结果就是 2009 2010 年都开设的课程
intersect 也是自动去重, 如果要保留重复数据, 可以使用 intersect all
- (select course_id
- from course
- where course_year=2009)
- intersect all
- (select course_id
- from course
- where course_year=2010)
差运算
找出 2009 开课但 2010 没开的课程
- (select course_id
- from course
- where course_year=2009)
- except
- (select course_id
- from course
- where course_year=2010)
except 也是自动去重, 如果要保留重复数据, 可以使用 except all
- (select course_id
- from course
- where course_year=2009)
- except all
- (select course_id
- from course
- where course_year=2010)
空值
涉及空值的任何比较运算的结果视为 unknown
null 的运算
and
true and unknown 结果是 unknown false and unknown 结果是 false unknown and unknown 结果是 unknown
or
true or unknown 结果是 true false or unknown 结果是 unknown unknown or unknown 结果是 unknown
not
not unknowen 结果为 unknown
所以例如 1<null not(1<A)的结果都是 unknown
判断是否为空值
is null is not null
select distinct 时两个元组的属性都是空或者非空且值相同例如 (1,null) 和(1,null)则两个元组是相同的
注意这里的区分和上述的谓词中对待空值的处理不同, 在谓词中 null=null 是 unknown, 而不是 true
数据库概念与实现(四)
来源: http://www.bubuko.com/infodetail-3395549.html