数据库:三级模式
- 外模式:数据库用户可以看到并允许使用的那部分局部数据的逻辑结构和特征的描述
- 模式:数据库中全体数据的逻辑结构和特征的描述
- 内模式,数据库存储结构的描述
DB:数据库
DBMS:数据库管理系统,管理控制数据库的建立、运行、维护
DBS:数据库系统 = 数据库 + DBMS +开发工具 +DBA +应用软件系统
概念模型–>结构模型–>物理模型
E-R三要素:实体,联系、属性
数据模型三要素:数据结构,数据操作,完整性约束
数据模型:
- 层次结构,树
- 网状结构,图
- 关系结构,表
- 面向对象
SQL语言(Structured Query Language)
数据定义:DDL:create、alter、drop
数据操作:DML:select、insert、update、delete
数据控制:DCL:grant、revoke、commit、rollback
SQL常用命令:
建表:
create table stu
(sno int not null primary key,
sname varchar(20) not null);
修改表名
alter table stu rename to student;
更新表,插入列:
alter table stu
add column sage int not null
drop column sname
删除表:
drop table stu
插入数据行:
insert into stu values(123,"张三");
insert into stu(sno,sname) values(123,"张三");
删除数据行:
delete from stu where sno=123;
更新数据:
update stu
set snmae="李四"
where sno=123;
查询:
select * from stu
授权:
grant select,update(sno) on stu to u1,u2 [with grant option]
撤销:
revoke update(sno) on stu from u1 [with revoke option]
创建视图:
create view abc as select * from stu;
删除视图:
drop view abc;
范式
**定义:**符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度。即一张数据表的表结构所符合某种设计标准的级别。
函数依赖:若在一张表中,在属性X的值确定的情况下,必定可以确定属性Y的值,则说Y函数依赖于X,写作X–>Y。
学号–>姓名,学号对唯一的姓名。
完全函数依赖:若X–>Y,且对于X的任何一个真子集X’,X’–>Y不成立,则称Y对于X完全函数依赖。
部分函数依赖:Y函数依赖X,但Y并不完全函数依赖于X,则称Y部分函数依赖于X,Xp–>Y
传递函数依赖:X–>Y(Y不属于X,X不函数依赖于Y),Y–>Z成立,则称Z传递依赖于X,记Xt–>Z
Armstrong公理
自反律:如果B ∈ A,则A–>B
增广律:如果A–>B,则AC–>BC
传递律:如果A–>B,且B–>C,则A–>C
Armstrong公理—推论
自合规则:A–>A
分解规则:A–>BC,则A–>B且A–>C
合并规则:A–>B且A–>C,则A–>BC
复合规则:A–>B且C–>D成立,则AC–>BD
闭包:由一个属性直接或间接推导出的所有属性的集合
例如:F={ a->b,b->c,a->d,e->f };由a可直接得b,d,间接得c,
所以a的闭包是{a,b,c,d};
候选码求解:U对X完全函数依赖
对于给定关系R(A,B,C)和函数依赖集F,可将其属性分成4类:
- L类,仅出现在函数依赖左部的属性
- R类,仅出现在函数依赖右边的属性
- N类,在函数依赖左右两边均未出现的属性
- LR类,在函数依赖左右两边均出现的属性
定理一:若X(X ∈ R)是L类属性,则X必为R的任一候选码的成员
推论:若X(X ∈ R)是L类属性,且X+包含了R的全部属性;则X必为R的唯一候选码
定理二:若X(X ∈ R)是R类属性,则X不在任何候选码中
定理三:若X(X ∈ R)是N类属性,则X必包含在R的任一候选码中
推论:若X(X ∈ R)是L类和N类组成的属性集,且X+包含了R的全部属性,则X是R的唯一候选码
多属性函数依赖集候选码选键的求解算法
(1)根据函数依赖集F,将R的所有属性分为L类、R类、N类和LR类等四类,并令X代表L类和N类属性,Y代表LR类属性;
(2)求X的闭包,若包含了R的全部属性,则X即为R的唯一候选键,转到步骤(5);
(3)从Y中取一个属性A,求(XA)的闭包,若它包含了R的全部属性,则XA是R的一个候选键,再换另一个属性反复进行这一过程,直到试完Y中所有的属性;
(4)这次每轮从Y中取两个、三个、多个属性并到属性集X中,每轮仿照步骤(3)的动作,耐心地求出关系R的全部候选键;
(5)停止,输出结果。
闭包链接:https://blog.csdn.net/Shishishi888/article/details/90269755
第一范式:符合1NF的关系中的每个属性都不可再分。
存在问题:
- 数据冗余
- 插入异常
- 删除异常
- 修改异常
第二范式:2NF在1NF的基础上,消除非主属性对码的部分函数依赖。
存在问题:
- 删除异常
- 插入异常
- 数据冗余
因为存在非主属性对主码的传递函数依赖。
第三范式:3NF在2NF的基础上,消除非主属性对码的传递函数依赖。
BC范式:BCNF在3NF的基础上,消除主属性对码的部分函数依赖与传递函数依赖。
事务
**概念:**事务是由一系列操作序列构成的程序执行单元,这些操作要么都做,要么都不做,是不可分割的工作单位。
事务的特性:
- 原子性:一个事务的所有操作要不全部完成,要不全部不完成
- 一致性:数据库的完整性没有被破坏,比如转账前后两个账户金额之和保持不变
- 隔离性:事务不受其他并发执行事务的影响
- 持久性:事务对数据库的修改是永久的
事务控制语句:begin transaction、commit、rollback
事务恢复:
前滚(重做REDO):对重做队列,正向扫描日志文件,重新执行登记的操作。
回滚(撤销UNDO):对撤销队列,反向扫描日志文件,对每个UNDO事务的更新操作执行反操作,回撤到事务开始前的状态。
并发操作导致不一致:
- 丢失更新,同时读入数据进行操作,A事务将B事务的结果覆盖
- 不可重读:A读取数据,B读取数据并更新数据,A核对时发现数值不同
- 读脏数据:A更新数据,B读取数据,A操作撤销,B得到的数据与当前数据不同。
并发操作的方法:封锁机制
排它锁(写锁,X锁):一个数据被某事物加了X锁,则不能再加任何其他锁
共享锁(读锁,S锁):一个数据被某事务加了S锁,其他事务不能加X锁,只能加S锁
事务的隔离级别
read-uncomitted:未提交读,读脏数据
read-commited:提交读,在读前加S锁,读后释放,不可重复读。
repeatable-read:可重复读,事务保持S锁到事务结束。
serialiable:可序列化,当事务处于repeatable-read时,只能锁定查询的那一行,而无法锁定其他行,当另一个事务插入一个记录数据满足查询条件时,两个查询结果就会不一样,称为幻读,serialiable可以避免幻读。
数据库故障与恢复
- 事务故障:系统自动完成
- 系统故障:重启系统,系统自动完成
- 介质故障:由DBA重装数据库
数据库恢复:
- 建立冗余数据:数据转储和登记日志文件
- 利用冗余数据实施数据库恢复
数据库锁机制
锁 | 概念 |
---|---|
乐观锁 | 用户自己实现,只在数据提交更新时候才会对数据的冲突进行检测 |
悲观锁 | 依靠数据库提供的锁机制 |
排它锁 | 一个数据被某事物加了X锁,则不能再加任何其他锁 |
共享锁 | 一个数据被某事务加了S锁,其他事务不能加X锁,只能加S锁 |
行锁 | 作用于数据行 |
表锁 | 作用于表 |
触发器的作用
触发器是一种特殊的存储过程,主要通过事件来触发而被执行,比如对一个表进行操作(insert,delete,update)。他可以强化约束,来维护数据的完整性和一致性,可以追踪数据库的操作而不允许未经许可的更新和变化。可以联级运算,如:某表的触发器包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。
//创建触发器
//new:新增对象;old:删除对象
create trigger 触发器名 before|after 触发事件
on 表名 for each row
begin
执行语句列表
end
create trigger teig_book after delete
on t_book for each row
begin
update t_booktype set bookNum = bookNum-1 where old.bookId = t_booktype.id;
insert into t_log values(null,NOW(),'在book表中删除数据');
end
什么是存储过程?
存储过程是由一些SQL语句组成代码块,这些语句像一个方法一样去实现一些功能(对单表或多表的增删改查),然后给这个代码块取一个名字,进行调用。
好处:
- 由于数据库执行动作时,是先编译后执行的。然而存储过程是一个编译过的代码块,所以执行效率高。
- 减少网络通信,用一条语句调用存储过程们就可以完成大量语句的任务,减少客户端与服务器的通信。
- 提供安全性机制,用户可以被赋予执行存储过程的权限,而不必在存储过程中引用的所有对象上都有权限。
create proc ABC [with recomplie] as select * from sudent 创建
execute ABC [with recomplie] 执行 [with recomplie]重新编译存储过程
alter proc ABC as select * from course 修改
drop procedure ABC 删除
输入参数执行存储过程
create proc ABC @ID int ,@date datetime
as select orderID,orderdate from order
where orderID = @ID ans orderdate < @date
execute ABC @ID=1,@date='1996-11-8'
输出参数执行存储过程
create proc ABC @A int, @ B int,@C int output
as set @C = @A*@B
declare @ans int
execute ABC 4,7,@ans output
select @ans as answer
什么是视图?
视图是从一个或几个基本表(视图)导出的表,是一张虚表。数据可只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。基本表的数据发生变化,从视图中查询的数据也会变化。
作用:
-
视图可以简化用户操作
-
安全性,用户只能查询与修改能看到的数据
-
逻辑上的独立性,屏蔽了真实表的结构带来的影响。
数据完整性
- 实体完整性:规定表的每一行在表中是唯一的实体
- 域完整性:表中的列必须满足某种特定的数据类型约束,如:取值范围、精度等规定
- 参照完整性:表之间的主关键字和外关键字数据一致
- 用户定义完整性:特殊的约束条件
如:主键约束,外键约束,唯一约束等
primary key(主键约束):
create table stu
(sno char(5),
cno char(1),
constraint PK_stu primary key(sno,cno)
)
add constraint PK_stu primary key(sno,cno);
drop constraint PK_stu;
foreign key(外键约束):
create table sc
(constraint FK_sc foreign key(sno) references stu(sno)
)
add constraint FK_sc foreign key(sno) references stu(sno);
drop constraint FK_sc;
unique:不受主键约束的列上的数据唯一性
create table test
(id int not null,
name varchar(20),
constraint UC_test unique(id)
)
add constraint UC_test unique(id);
drop constraint US_test;
default 默认值
create table test
(city varchar(5) not null,
constraint DF_test default 'A' for city)
check 约束用于限制列中的值的范围
create table stu
(id int not null,
birthdate datetime not null,
schooldate datetime noe null,
constraint chk_stu1 check (id>100),
constraint chk_stu2 check (birthday<schooldate)
)
InnoDB和MyISAM对比
事务 | 并发 | 外键 | 备份 | 崩溃恢复 | 索引 | |
---|---|---|---|---|---|---|
InnoDB | 事务型 | 行级锁 | 支持 | 在线热备 | 概率低 | 聚集索引 |
MyISAM | 非事务型 | 表级锁 | 不支持 | 不支持 | 慢,易丢失 | 非聚集索引 |
索引
索引类型:
索引类型 | 特点 |
---|---|
主键索引 | 添加主键,特殊的唯一索引,不允许有空值 |
唯一索引 | 索引列的值必须唯一,可以有多个,允许有空值 |
普通索引 | 快速定位 |
联合索引 | 由多列组成的索引,遵循最左前缀规则(从左往右匹配) |
全文索引 | 只能用于MyISAM类型数据表,用于varchar、char、text类型 |
聚集索引 | 聚集索引顺序与数据的物理存储顺序一致 |
辅助索引 | 一个表可以有多个辅助索引,叶子节点存放表的键值和指向聚集索引的指针 |
覆盖索引 | 从辅助索引中就能获取需要的记录,不需要查找聚集索引中的记录,减少I/O操作 |
索引失效:
- 查询数据比较多
- 有or必须全有索引
- 查询条件使用函数在索引列中:select * from test whee round(id)=10;
- 隐式转换导致索引失效,cno是varchar类型,查询时cno=123;
- 对索引项进行运算
- like"%_",百分号在前
- 使用复合索引的非第一位置的索引列
索引的优点:提高查询速度,加快表与表之间的连接速度
索引的缺点:更新数据时效率低,因为要同时更新索引,占用存储空间
对数据进行频繁查询建立索引,如果频繁更改数据不建议使用索引,不宜对重复值很多的列建立索引。
索引底层实现(B+树,B树,红黑树,hash表)
数据结构 | 区别 |
---|---|
hash表 | 精确查询效率高,但不可以范围查询、联合查询、排序 |
红黑树 | 增加,删除,红黑树会进行频繁的调整,来保证红黑树的性质,浪费时间 |
B树 | 查询性能不稳定,查询高度不一致,每个节点保存指向真实数据的指针,高度比B+树更高 |
B+树 | 显得更矮更宽,查询层次更浅,I/O次数更少,更利于范围查找 |
聚集索引与非聚集索引的区别?
在mysql中,有两大常用的存储引擎MyISAM和InnoDB。MYISAM使用的是非聚集索引,InnoDB
使用的是聚集索引,聚集索引就是以主键创建的索引,非聚集索引就是除了主键以外的索引。
- 表记录的排列顺序和索引顺序顺序一致。
- 聚集索引一个表只有一个,非聚集索引一个表可以存在多个。
- 聚集索引存储记录在物理上连续存在,非聚集索引是逻辑上连续。
- 聚集索引的叶节点就是数据节点,而非聚集索引的叶节点仍是索引节点,指向对应数据块。
聚集索引的优点:
- 查询速度快
- 聚集索引是排序的数据,所以方便取出一定范围内的数据。
聚集索引使用的场合:
- 查询结果返回一个区间的值
- 返回某值相同的大量结果集
聚集索引的缺点:更新聚集索引的代价高,因为在插入的时候需要按序插入,面临页分裂。
非聚集索引的优点:
- 非聚集索引的层次多
- 添加数据不会引起数据顺序的重组
非聚集索引使用场合:
- 此列包含大量数目不同的值
- 查询结果返回少量的结果集
SQL的优化:
- 尽量使用索引
- 子查询变成left join
- 避免嵌套查询
- 对多个字段等值查询时可以使用联合索引
varchar与char的区别
- char定长,varchar长度可变。如果char(10)存5个字符,后面补空格;而varchar(10)少于10个字符就存几个字符。
- 对于varchar来说,需要使用一个(字符串长度小于255)或两个(字符串长度大于255)来存储字符串的长度。
- char最多存放255个字符,和编码无关;varchar最多存放65532个字符,与编码有关。
- char对英文字符占用一个字节,对一个汉字占用两个字节,varchar对英文字符和汉字都占两个字节。
关系型数据库和非关系型数据库区别?
关系型数据库最典型数据结构是表,由二维表及之间的联系所组成的一个数据组织。
SQL Server,MySQL,ORACLE
优点:
- 易于维护:都是使用表结构,格式一致
- 使用方便:SQL语言通用,可用于复杂查询
- 复杂操作:可以多表连接查询
缺点:
- 读写性能差,尤其是海量数据的高效率读写
- 固定表结构,灵活度稍欠
- 高并发读写需求,硬盘I/O比较费时
非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方式和集合,可以使文档或者键值对。
mongoDB,redis
优点:
- 格式灵活:存储数据的格式可以使键值对,文档形式,图片形式等
- 速度快
- 高扩展性
缺点:
- 不支持sql,学习和使用成本较高
- 无事务处理
- 数据结构复杂,查询较复杂
/*MySQL、SQL Server、Oracle等数据库支持CONCAT方法,
而本题所用的SQLite数据库只支持用连接符号"||"来连接字符串*/
-名字拼接
-SQL select last_name||" "||first_name as name from employees;
-MySQL select concat(last_name," ",first_name) as name from employees
-获取执行计划,从而知道mysql是如何处理sql语句,分析查询语句或者表结构的性能瓶颈。
explain select * from stu
插入数据,如果已存在忽略
insert or ignore into stu values(1,'name');
创建索引
create unique index uni_idx_id on stu(id);
alter table stu add unique index uni_idx_id(id);
强制使用索引
-SQL select * from stu indexed by uni_idx_id where id=5;
-MySQL select * from stu force index uni_idx_id where id=5;