数据库系统的特点:
- 数据结构化
- 数据共享性高,冗余度低且易扩充
- 数据独立性高
- 数据有数据库管理系统统一管理和控制
提供数据控制功能主要包括:数据安全性保护,完整性检查,并发控制,数据库恢复
数据模型:是数据库内部对现实世界的抽象,是描述数据,组织数据和对数据进行操作的。数据模型是数据库系统的核心和基础。
数据库中的两大数据模型:概念模型,逻辑模型和物理模型
概念模型是现实世界到信息世界的第一层抽象。
信息世界的基本概念:实体,属性,码,实体型,实体集,联系。
概念模型的表示方法:实体-联系表示法(E-R模型)
数据模型由数据结构,数据操作,数据完整性约束组成。
逻辑数据模型分类:层次模型,网状模型,关系模型,面向对象数据模型。
关系模型的完整性约束包含:实体完整性,用户定义完整性,参照完整性。
关系模型的数据操作是集合操作,操作对象和操作结果都是关系。
数据库的三级模式结构:外模式,模式,和内模式
模式是数据库中全体数据的的逻辑结构和特征的描述。是全体用户的公共数据视图。模式是相对稳定的,实体是相对变动的。
外模式:外模式也称子模式或者用户模式,他是数据库用户能够看见的逻辑结构和特征的描述。是数据库用户的数据视图,是与某一应用相关的数据逻辑表示。外模式是模式的子集。一个应用程序只是用一个模式。
内模式:数据在数据库内部数据物理结构和存储方式的描述,数据在数据库内部的组织方式。
数据库的二级映像功能和数据的独立性:
外模式和模式的映像:当模式改变时(例如新添加某一个数据类型,或者新的关系),数据库管理员对各个外模式/模式的映像作相应改变,可以使外模式保持不变。应用程序是依据外模式编写的,所以应用程序也不必修改,保证了数据和程序的逻辑独立性。
内模式和模式的映像:当数据的存储结构发生改变的时候,有数据库管理员对模式/内模式映像做相应改变,可以使模式保持不变,从而应用程序也不必改变;保证了数据和程序的物理独立性。
总的来说,外模式/模式映像保证了数据的逻辑独立性,模式/内模式映像保证了数据的物理独立性。
数据与程序的独立性使得数据的定义和描述可以从应用程序中分离出来。应为数据的存取管理由数据库管理系统管理,所以简化了应用程序的编制,大大减少了程序的维护和修改。
数据库系统的组成:硬件平台和数据库,软件,人员。
关系数据和形式化定义:
域是一组具有相同数据类型的值的集合。
关系可以有三种类型:基本表或基表,查询表,视图表。
关系和关系模式:关系模式是静态的,稳定的,关系是动态的,随时间变化的,关系操作在不断的操作数据库中的数据。
基本关系操作:选择,投影,并,差,笛卡尔积。
操作的对象和结果都是集合。
关系模型中的三类完整性约束:实体完整性,参照完整性,用户定义完整性。实体完整性和参照完整性是关系模型必须满足的完整性约束条件。称作关系的两个不变性。
实体完整性的规则:若属性A是节本关系R的主属性,则A不能取空值。
参照完整性:若属性F是基本关系R的外码,他与基本关系S的主码Ks相对应,则R中的每个元祖在F上的值必须满足:
- 不能为空值
- 或者等于S中某个元组的主码值。
- 用户定义的完整性:用户在操作表的过程中,要满足具体数据库中所定义的约束条件和语义。
非关系模型数据语言包括:模式数据定义语言(DDL)
外模式数据定义语言外模式DDL
数据存储有关的描述语言DSDL
数据操纵语言DML
三级模式中的基本对象:模式表,视图,索引,断言等
一个关系数据库管理系统中可以建立多个数据库,一个数据库中可以建立多个模式,一个模式通常包含多个表,视图和索引等数据库对象。
创建模式:
create schema <模式名>authorization<用户名>
删除模式:drop schema<模式名><cascade|restrict>
mysql中似乎不支持cascade级联关键字
建立一个课程表:
CREATE TABLE course(
cno int ,
sno int PRIMARY KEY,//定义主键
cname char(20) NOT NULL,
FOREIGN KEY(cno) REFERENCES course(cno) ;//设置cno为外键,参照表为course
) ;
外键:当一个表中的某一列数据必须由另一个表中的主键约束时,该列的数据为外键。
例如学生表中的选课id号,必须取自课程表中的课程主键值。这就是数据库中数据的参照完整性的体现。这里说的不是很准确!单就这个意思吧。一个表可以定义多个外键,只能定义一个主键。
索引:
可以利用索引快速访问数据库表中的特定信息。索引是对数据库表中一个或多个列(例如,employee 表的姓氏 (lname) 列)的值进行排序的结构。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。
索引提供指针以指向存储在表中指定列的数据值,然后根据指定的排序次序排列这些指针。数据库使用索引的方式与使用书的目录很相似:通过搜索索引找到特定的值,然后跟随指针到达包含该值的行。
在数据库关系图中,可以为选定的表创建、编辑或删除索引/键属性页中的每个索引类型。当保存附加在此索引上的表或包含此表的数据库关系图时,索引同时被保存。有关详细信息,请参见创建索引。
通常情况下,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引将占用磁盘空间,并且降低添加、删除和更新行的速度。不过在多数情况下,索引所带来的数据检索速度的优势大大超过它的不足之处。然而,如果应用程序非常频繁地更新数据,或磁盘空间有限,那么最好限制索引的数量。
创建索引:
好处:当数据库中数据量比较大时,查询操作比较缓慢,建立索引加速查询速度。创建方法:
UNIQUE表示唯一索引 CLUSTER聚簇索引
CREATE [UNIQUE][CLUSTER]INDEX<索引名>ON <表名>(<列名>[次序]);
//创建一个按学生学号升序排列的索引
CREATE UNIQUE INDEX stuSno on student(sno) ;
//创建一个按照课程号升序的索引
CREATE UNIQUE INDEX couCno on course(cno) ;
//创建一个按照学生号升序课程号降序的唯一索引
CREATE UNIQUE INDEX Scno ON SC(Sno ASC, Cno Desc) ;
修改索引
ALTER INDEX<旧索引>RENAME TO <新索引>
删除索引
DROP INDEX <索引名>
表中的数据查询:
使用select语句进行。之前博文里面有相关操作,可以参考!
模糊查询:LIKE或者NOT LIKE ‘xxx%’
NOT IN
BETWEEN …AND…
对查询结果进行操作:
制定DISTINCT取消重复的列
查询相关的聚集函数:
COUNT(*) COUNT(DISTINCT<列名>)
SUM(列名)
AVG(列名)
MAX(列名)
MIN(列名)
对查询结果的操作:
ORDER BY
GROUP BY
等值连接和非等值连接:
<表名.><列名><连接符号><表名.><列名>
列名称连接字段,连接条件中的各连接字段必须是可比的。但名字不比相同。
当多表进行连接的话,可以进行外连接,左外连接和右外连接
两个表中的数据项条目不相等的话,使用做外连接可以使左表中的所有数据项全部显示出来:
SELECT Student.sno sname sex, age , sdept, cno,grade FROM Student LEFT OUTER JOIN SC ON (Student.sno=SC.sno) ;
也可以使用USING 消除重复项。
将以上from语句修改FROM Student LEFT OUTER JOIN SC USING (sno) ;
集合查询:
UNION 查询并集
INTERSECT 查询交集
EXCEPT 查询差集
往数据库中插入信息
INSERT
删除数据库表中的信息
DELETE FROM …
删除表:
DROP
修改表中的信息:
UPDATE
视图:是从一个或多个基本表中导出的表,他是一个虚表,数据库中存放的是视图的定义,不存在视图对应的数据,这些数据存放在原来的基本表中。所以一旦基本表发生变化,视图也就随之变化。通过视图可以获取数据库中自己感兴趣的数据项。
创建视图:
CREATE VIEW 视图名称[列名 ,列名…]AS 子查询 ;
数据库的安全性:
在数据库中的相关操作在之前的博客总结过了;
数据的完整性是指数据的正确性和相容性。
关系型数据库使得完整性控制成为其核心支持的功能,从而能够为所有用户和应用程序提供一致的数据库完整性。有应用程序实现的完整性控制有漏洞,可能被破坏,数据库的完整性无法保障。
创建外键约束的两种方式:
//创建一个表test1
CREATE TABLE test1(cno int primary key, sno int, sex varchar(10)) ;
//创建一个表test2 外键cno参考test1的主键---------------创建外键的方式1
CREATE TABLE test2(
sno int ,
cno int,
sex varchar(10)
age int,
primary key(cno, sno),
FOREIGN KEY(cno) REFERENCES test1(cno)
) ;
//创建主键的方式2,使用CONSTRAINT 完整性约束关键字
CREATE TABLE test2{
sno int
CONSTRAINT PKEY PRIMARY KEY(sno) ;
cno int
CONSTRAINT FKEY FOREIGN KEY(cno) REFERENCE test1(cno),
sex varchar(20) CONNSTRAINT SEX CHECK(sex IN(‘男’,‘女’)),
sname varchar(20) NOT NULL
};
触发器:
关系表中由事件驱动的特殊过程。触发器又叫做事件-条件-动作规则。当特定的系统事件对一个表的增删改查操作发生时,对规则的条件进行检查,要是条件成立的话,就会执行该动作,否则就不执行。
创建触发器的规则:
CREATE TRIGGER <触发器名>{
BEFORE|AFTER} <触发事件>ON <表名>
REFERENCE NEW|OLD ROW AS
<变量>
FOR EACH {ROW|STATEMENT}
[WHEN <触发条件>]<条件动作>
例子:
创建一个触发器:当对表SC的Grade 属性进行修改时,若分数增加了10%,则此次操作记录到另一个表SC_U中,其中oldGrade是修改前的分数,newGrade 是修改后的分数
CREATE TRIGGER SC_T AFTER UPDATE OF Grade ON SC//After 是触发时机,当触发了事件后,就会执行下面的规则。
REFERENCING
OLDROW AS OldTuple
NEWROW AS NewTuple
FOR EACH ROW//行级触发器,当每次执行一次Grade 更新操作,下面的规则就被执行一次
WHEN(NewTuple.Grade>=1.1*OldTuple.Grade)//触发条件为真时执行下面的语句
INSERT INTO SC_U(Sno, Cno, OldGrade, NewGrade)
Values(OldTuple.Sno, OldTuple.Cno, OldTuple.Grade, NewTuple.Grade);
在本例中,REFERENCING指出引用的变量,如果触发事件是UPDATE 操作并且有FOR EACH ROW子句,若引用的变量有OLDROW和NEWROW,分别表示修改前的元组和修改元组,若没有FOR EACH ROW子句,则可以引用的变量是OLDTABLE 和NEWTABLE,OLDTABLE 表示表中原来的内容。
将每次对表Student 的插入操作增加的学生个数记录到表StudentLog中
CREATE TRIGGER Student_Count
REFERENCING
NEW TABLE AS DELTA
FOR EACH STATEMENT
INSERT INTO StudentInsertLog(Numbers)
SELECT COUNT(*)FROM DELTA ;
FOR EACH STATEMENT,表示触发事件INSERT的语句执行完成后才执行一次触发器中的动作,这种触发器是语句级触发器。
定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则"教授的工资不得低于4000元,如果低于4000,自动修改为4000"
CREATE TRIGGER insert_or_update
BEFORE INSERT OR UPDATE ON Teacher
REFERENCING NEW row As newTUPLE
FOR EACH ROW
BEGIN
IF(newTuple.Job=‘教授’) AND (newTuple.Sal<4000)
THEN newTuple.Sal:=4000 ;
END IF;
END;
DROP TRIGGER <触发器名>ON<表名>;
数据库规范化:
规范化的基本思想是逐步消除依赖中不合适的部分,使模式的各关系模式达到某种程度的“分离”,即“一事一地”的模式设计原则。规范化实际上是概念的单一化。
规范化过程:
参考文章:https://blog.csdn.net/qq_41681241/article/details/95334431
数据库事务
事务是用户自定义的数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的看工作单位。定义事务的语句一般有三条:
BEGIN TRANSATION ;//开始事务
COMMIT;//提交事务
ROLLBACK;//回滚,将事务中对数据库的已完成操作全部撤销,回到事务开始的状态。
事务的ACID特性:
原子性,一致性,持续性,隔离性
事务故障的种类:事务内部故障,介质故障,系统故障,计算机病毒。
数据库恢复技术:建立冗余数据,通过冗余数据对数据库进行恢复。最常用的方式:登记日志文件,数据转储。
静态转储:在系统中无事务运行时的转储操作。
动态转储:转储和事务可以并发执行。
为保证数据库可恢复,登记日志文件必须保证两条规则:登记的次序严格按照并发的事件次序;
必须先写日志文件,再写数据库;
并发控制
事务是并发控制的基本单位。并发控制的主要技术:封锁,时间戳,乐观控制法,多版本控制等。
排它锁又称为写锁,若事务T对数据对象A加上x锁,则只允许T读取和修改A,其他任何事务不能对A加任何类型的锁,直到T释放A上的锁。
共享锁:又称读锁,事务T对数据对象A加S锁的话,则事务T可以读A但不能对A进行修改操作,其他事物只能对A加S锁,不能加写锁,直到事务T完成为止。
封锁协议
一级封锁协议:事务T在对A在修改数据之前必须对数据加X锁,直到事务结束才释放,事务结束包括正常结束和异常结束。
在一级封锁协议中,如果仅仅是读数据而不是对数据进行修改,是不需要加锁的,所以他不能保证可重复读和不读脏数据。
二级封锁协议:在以及封锁协议的基础上增加了事务T在读取数据R之前必须先对其加S锁,读完后即可释放S锁。在二级封锁协议中,由于读完数据就释放S锁,所以不能保证可重复读。
三级封锁协议:在一级封锁协议的基础上添加事务T在读取数据R之前先对其加S锁,直到事务结束才释放。三级封锁协议防止丢失修改,该可进一步防止读脏数据,并且可重复读。
活锁:
多个事务请求对同一数据进行封锁的操作。
当事务T1封锁了数据R,这时候请求封锁数据的事务T2只能等待,T3也对数据请求封锁,当T1对所释放后,正好T3拿到了锁,这是正在等待的T2又只能等待。当T3释放了锁之后,T4拿到了锁…这种情况下,先来的T2可能会一直等待下去。这就是活锁。
避免活锁的方法就是先来先服务。将每个事物对数据的封锁申请排个队,先请求的事务先拿锁。
死锁:
事务T1对数据R1进行封锁,T2对数据R2进行封锁,然后,T1请求封锁R2,因为T2已经封锁了R2,于是T1等待T2释放R2上的锁,接着T2又申请封锁R1,因为T1已经封锁了R1,T2也就只能等待T1释放R1上的锁,这种情况,T1等待T2,T2等待T1,两个事务永远不能结束的情况,就是死锁。
死锁的预防:
一级封锁法
顺序封锁法
死锁的诊断和解除:超时法,等待图法。
可串行化调度:
多个事务并发执行是正确的,当且仅当其结果与按照每一次序串行执行这些事务时的结果相同,称这种调度策略为可串行化调度。
可串行性是并发事务正确调度的准则。
冲突操作是指不同的事务对同一个数据的读写操作和写写操作。
两段锁协议:
在对任何数据进行读写操作之前,首先申请并获得该数据的封锁。
在释放一个封锁之后,事务不再申请和获得任何其他封锁。
第一阶段是获得封锁,也称为扩展阶段。
第二阶段是释放封锁,也称为收缩阶段。
多粒度加锁:对一个节点加锁意味着对这个节点及其下的所有节点进行加锁。
意向锁:当对一个节点加意向锁,说明其下的所有节点正在被加锁。
还有关于意向锁的扩展IS锁,IX锁,SIX锁等。