关系型数据库学习笔记

本文分三部分,概念,mysql,sqlserver

part1 概念

第一章:绪论

四个概念:
数据:Data快递
数据库:DataBase物流仓库
数据库管理系统:DBMS整个仓库运作情况
数据库系统:DBS整个物流体系
概念模型:ER图
椭圆:属性
矩形:实体
菱形:联系
1:N:一对多
N:N:多对多
逻辑物理模型:
层次模型:树
网状模型:图
关系模型:二维表
关系:一张表
元组:一行
属性:一列
码:可以唯一确定一个元组的属性集且其真子集不是码(可多个属性作为码)
候选码:极小超码集,它的任意真子集都不是超码,而他本身是超码
主码:主码是被选中用来在一个关系中区分不同元组的候选码
域:属性取值范围
分量:单元格的值
关系模式:对关系的描述
完整性约束:
实体完整性:主码唯一且非空
参照完整性:外码要么空,要么是另一个表的主码
用户定义完整性:用户自行定义的
三级模式两级映像:
应用—n:1—外模式——外模式/模式映像n:1——模式(就是逻辑模式)
模式——内模式/模式映像1:1——内模式—1:1—数据库
数据独立性:
逻辑独立性:模式结构改变时,只需要修改外模式/模式映像即可保持逻辑独立性
物理独立性:内模式结构改变时,只需修改模式/内模式映像就可保持物理独立性

第二章:关系数据库

关系:一张表
关系描述:R(U,D,DOM,F)
R:关系名
U:所有属性名
D:属性来自哪些域
DOM:属性和域的映射
F:属性间的依赖关系
关系操作:增删改查
查询操作:选择,投影,连接,除法,并,差,交,笛卡尔积
关系数据语言:关系代数语言,关系演算语言,SQL语言
关系代数语言:
并:我有或你有
交:取相同的
差:取我有你没的
笛卡尔积:我每一个元组与你每一个元组组合
选择:就是分量在设定范围内的元组
投影:选择列
连接:
自然连接:把共同属性进行等值连接,被舍弃的元组叫悬浮元组
(全)外连接: 在自然连接基础上,加上左右表中的悬浮元组
左外连接:在自然连接基础上,加上左表中的元组(元组的右表属性为空)
右外连接:在自然连接基础上,加上右表中的元组(元组的左表属性为空)
除法:如图

第三章:SQL

存储文件——基本表——视图

查SELECT……选
定义CREATE,DROP,ALTER……创,删,改
视图VIEW,模式SCHEMA,表TABLE,索引INDEX,注意模式与视图不支持修改
操纵INSERT,UPDATE,DELETE……插,更,删
控制GRANT,REVOKE……权

第四章:安全性

用户身份鉴别:静态口令,动态口令,生物特征,智能卡
存取控制
自主存取控制方法
授权:授予grant与收回revoke

视图机制(用不上的就隐藏起来)
审计(所有操作记录,看有没有违法)
数据加密(明文与密文)

第五章:完整性

完整性:数据正确性与相容性
三大完整性:实体,参照,用户定义
用户定义完整性:非空NOT NULL,列值唯一UNIQUE,满足某一条件表达式CHECK
断言assertion:指定一般性约束,任何使断言不为真值得操作都会拒绝执行。
触发器trigger:用户定义在关系表上的一类由事件驱动的特殊过程,不能定义在视图上

第六章:关系数据库理论

存在问题:数据冗余,插入/删除/更新异常(多个表有共同属性)
函数依赖:
X可推出Y,且Y属于X,则称X->Y是平凡函数依赖(X班级,Y学生)
X可推出Y,且Y不属于X,则称X->Y是非平凡函数依赖(X班级,Y老师)
X可推出Y,但Y不完全依赖于X,则Y对X部分函数依赖(X学号,姓别,Y姓名)
X可推出Y,但对X任一真子集,都推不出Y,则Y对X完全函数依赖(X学号,Y姓名)
候选码:一个属性集合,可推出所有属性,但任一真子集无法推出所有属性
如F(A->B,B->C,D->E,E->D),则AD,AE是候选码,注意候选码不一定是唯一的
解求候选码题思路:只出现在左边一定是,只出现右边一定不是,左右不出现一定是
然后把可能是的逐个假设为候选码去试
超码:能表示所以属性的属性集
候选码:最小的超码,候选码的真子集不能推出所有属性
主码:从候选码中任意挑出一个为主码
主属性:包含在任意一个候选码中的属性
非主属性:不包含在任一候选码中的属性
码:我们把主码,候选码都叫做码
全码:所有属性都是码,就是全码
规范化范式
1NF:所有关系模式都是1NF,表中无表即可
2NF:在1NF基础上,不存在非主属性对码的部分函数依赖,简单来说就是要完全依赖
3NF:在2NF基础上,不存在非主属性对码的传递函数依赖,简单来说就是要直接依赖
BCNF:在ENF基础上,不存在主属性对码的部分和传递函数依赖,简单来说就是主属性间完全直接依赖
数据依赖公理系统
自反律:Y属于X,则X可推出Y
增广律:X可推出Y,则XZ可推出YZ
传递律:X可推出Y,Y可推出Z,则X可推出Z
合并规则:由X推出Y,X推出Z,有X推出YZ
伪传递规则:由X推出Y,WY推出Z,有XW推出Z
分解规则:由X推出Y及Z属于Y,则X可推出Z
考题:求最小函数依赖集:F中每个依赖,都不可以被其他依赖推出,且右边一定是单元素
解法:逐个依赖删去看是否多余,注意答案可以不唯一
模式分解
准则:无损连接性,保持函数依赖
考题:如何把数据库分解成3NF,并保持无损分解和函数依赖

第七章:设计

需求分析
概念结构设计:ER图、数据字典
逻辑结构设计:把ER图转换成逻辑模型:1对1转换主码,1对N转换外码,N对N建表
物理结构设计:逻辑模型转换成物理模型
数据库实施:写SQL代码
数据库运行与维护:性能检测、转储、恢复

第八章:编程

嵌入式SQL:把SQL写入其他编程语言(预编程变函数,主函数再编译)
主变量:SQL使用的主语言传入的变量,比如:name(注意有:)
游标:一个缓冲区,存放SQL执行结果
动态SQL:执行时才确定SQL子句,使用动态SQL
过程SQL:块基本结构
定义部分:DECLARE变量、常量、游标、异常
执行部分:BEGIN:SQL语句,过程化SQL流程
控制语句:EXCEPTION异常处理部分END
存储过程及函数差不多,只不过前者无返回值,后者必须有
ODBC编程

第九章:关系查询及优化

代数优化:先做选择和投影,最后再做连接

第十章:恢复技术

事务:一级SQL语句
A原子性actom:要么全做,要么全不做
C一致性consistent:数据之间的关系保持不变
I隔离性isolate:一个事务执行不被其他事务干扰
D持久性duration:永久改变,写入磁盘
事务故障:
事物内部:采REDO和UNDO技术
系统:重启,未执行完UNDO,丢失的事务REDO
介质:修复硬件,重装数据库,REDO已完成事务
病毒:杀毒
恢复技术:
数据转储:重新执行失败的事务
日志文件:记录事务对数据的更新操作文件
有检查点的恢复

第十一章:并发控制

带来问题:
丢失修改:我读了,他读了,我改了,他改了,我的修改丢失了
读脏数据:他改了,我读了,他回滚了,我读了脏数据(相当于之后再读时值不同)
不可重复读:我读了,他改了,我又读了,我读的两次值不同
解决方法:
排它锁=写锁=X锁
共享锁=读锁=S锁
一级封锁协议解决丢失修改:修改时加X锁直到结束
二级封锁协议解决读脏数据:读取时加S锁,用完就放
三级封锁协议解决不可重复读:读取时加S锁直到结束
活锁:该锁永远等待,得不到机会上锁(优先级低饿死)
死锁:多锁互相等待,互相谦让无人上锁
可串行化调度:并发调度中某一次结果与串行调度一致
封锁粒度大,并发度小,开销小

索引

唯一索引:不允许两行具有相同的索引值
主键索引:为表定义主键时自动创建,唯一索引的特殊类型,主键索引要求主键中每一个值都是唯一的
聚集索引:表中各行的物理顺序与键值的逻辑(索引)顺序相同,表中只能包含一个聚集索引
(可以理解为字典的拼音,按字典序排,实现方法有B/B+树,理论上也可以是二分搜索)
非聚集索引:数据和索引包含指向数据存储的相应位置表中的各行物理顺序与键值的逻辑顺序不匹配
(可以理解为map,把表中某些频繁访问到数据地址作为键值,生成一个键映射它,每次就搜它的键)
其中,聚集索引比非聚集索引速度更快,一个表中只能有一个聚集索引,但是可以有多个非聚集索引

首先:清概念,键,就是码,一个意思
然后:超键/超码,候选键/候选码,主键/主码
超键(super key):在关系中能唯一标识元组的属性集称为关系模式的超键
候选键(candidate key):不含有多余属性的超键称为候选键
主键(primary key):用户选作元组标识的一个候选键程序主键

比如以下四个属性(假设无重名):身份证 姓名 性别 年龄

身份证唯一,所以是一个超键
(身份证,姓名)唯一,所以是一个超键
(身份证,姓名,性别)唯一,所以是一个超键
(身份证,姓名,性别,年龄)唯一,所以是一个超键
姓名唯一,所以是一个超键
(姓名,性别)唯一,所以是一个超键
(姓名,性别,年龄)唯一,所以是一个超键

身份证唯一且无多余属性,所以是一个候选键
姓名唯一且无多余属性,所以是一个候选键

我作为用户,在两个候选键中选一个作为主键,例如身份证,那身份证就是主键

主属性:候选键中的属性

六大范式

第一范式:每一个关系r的属性都是原子项,不可分割。
例如:姓名 电话……那么电话可能有家庭电话与手机,不符合

第二范式:R是1NF,且每一个非主属性完全依赖于候选建。
例如:学生ID,课程ID,成绩……成绩依赖于候选键(学生ID,课程ID),符合
例如:学生ID,课程ID,成绩,学生姓名……学生姓名仅依赖于主属性学生ID,存在部分依赖,不符合

第三范式:R是2NF,非主属性对任何候选关键字都不存在传递依赖 。
例如:员工ID,主管ID,主管年龄……主管年龄依赖于主管ID,主管ID依赖于员工ID,不符合

BCNF:R是3NF,主属性间无传递依赖。
例如:仓库ID, 存储物品ID, 管理员ID, 数量……(仓库ID) → (管理员ID),(管理员ID) → (仓库ID),不符合

第四范式:R是BCNF,表内没有多对多关系。
例如:员工ID,员工电话,员工手机……电话与手机相互独立,可能有多个电话,多个手机,故须变成员工ID-号码-号码种类(否则,假如1个ID有3个电话3个手机,要用9行来存储)

第五范式:R是4NF,从最终结构重新建立原始结构。
例如:员工ID,员工电话,员工手机(假设电话与手机都唯一)……必须拆成员工ID-员工电话 和 员工ID-员工手机

事务特性

原子性(自我对比):一个事务中的语句不可分割
一致性(自我对比):事务必须使数据库从一个一致性状态变换到另外一个一致性状态(和原子性差不多)
隔离性(横向对比):多线程环境下,一个线程中的事务不能被其他线程中的事务打扰(可串行化)
持久性(纵向对比):事务一旦提交就被保存


part2 mysql

Mysql 查询

select 
{ * | [ distinct ] [ table. ] col [ as name ] [ , [ table1. ] col1 [ as name1 ] , … ] }	
from table [ , table1 , … [ on search_condition ] ]
[ where search_condition ]
[ group by col [ , col1 , … ] ]	
[ having search_condition ]	
[ order by order_expression { asc | desc } [ , order_expression { asc | desc } ]
[ limit m,n ]
[ union [ all ] select … ]

补充:
col部分:可以进行+,-,*,/,%等运算,注意只可以数字相加
可以进行max(col),min(col),avg(col),sum(col),count(col)聚合运算
		char(10)=’yyyy-mm-dd’时,可以使用year(col),month(col),day(col)调用
		timestamp等价于int(14),等价于DATE_FORMAT(col,'%Y%m%d%H%i%s')
		可以使用isnull(col)建列,col为空是1,非空为0
		可以使用nullif(col,val) 建列,col列中值为val的取空,非val取原值
into部分:可以把查询到的内容建成新表
from部分:可以定义要查询的源表,也可以是select子句返回的表
			可以使用left join左外连接,第一个表全部行保留,第二个表只保留匹配行
			可以使用right join右外连接,第二个表全部行保留,第一个表只保留匹配行
			可以使用full join全外连接,两个表都全部行保留,未匹配行全是null
			可以把一个表定义为两个别名,使用自连接
			可以使用cross join交叉连接(笛卡尔乘积)
where部分:可以使用col <,<=,>,>=,=,!=,<>(同!=),可接select子句
				符号可以连接不同的表,若两表同属性名则col部分的列要注明表名
可以使用col [ not ] between … and …
			可以使用not(写在条件前),and,or(三个条件优先级下降)
			可以使用col [ not ] in ( val1 , val2 , val3, … ) 或 val in ( col1 , col2 , col3 , … )
			可以使用col [ not ] like ‘_[a][^b-z]%’( _单符含中文 %全符 []指定 [^]非 )
	可以进行max(col),min(col),avg(col),sum(col),count(col)聚合运算
			可以使用ltrim(col),rtim(col),trim(col),去掉空格
			可以使用clo is [ not ] null
			可以使用[ not ] exists ( select语句) 选择符合条件的行
			可以使用all操作符:<all是小于最小的,>all是大于最大的,=all返回空
			可以使用any操作符:<any是小于最大,>any是大于最小,=any同in
			可以使用some操作符:同any
Group by 部分:可以指定按哪些列分组(可以多列),在col部分可以用count(*)统计
			虽然null不等于null,但是分组中null会分成一组
having部分:类似where定义限制条件,但是其中的聚合函数如AVG只统计组内数据
order by部分:默认asc或1升序,降序设desc或-1,或者用RAND()随机数排序
limit部分:limit m,n可以写成limit n offset m
union部分:连接两个表(列属性名要相同),有all会保留重复值,没有则自动删重复值

执行顺序:from, where, group by, having, select, order by, limit, union, …



Mysql 数据库

创建数据库
create database database_name;
删除数据库
drop database database_name ;



Mysql数据表

创建数据表
create table table_name as select语句
create table table_name ( col1 type , col2 type , … [ condition ] )
	type可以使用int, float, varchar(x), text,其中text可视为无限长的varchar,即x无穷大
	condition可以使用default default_value,设置默认值
condition可以使用primary key,列值必须唯一且不允许有空值
condition可以使用unique,列值必须唯一但允许有空值
condition可以使用not null,不允许有空值
condition可以使用check ( check_condition ),condition例如col>10 and col<20
修改数据表
alter table table_name add col_name type [ condition ]
	增加列
alter table table_name alter column col_name type [ condition ]
	改变列的数据类型
alter table table_name add primary key ( col )
	添加主键(原来不能有主键)
删除数据表
drop table table_name



Mysql视图

创建视图
create view view_name [ ( column_name ) ] as select … [ with check option ] ;
	创建时有with check option字段,则之后通过视图进行数据操作时要也符合定义时的查询条件。
查询视图
select col from view_name;
删除视图
drop view view_name;

对数据表或视图插入数据
insert into { table_name | view_name } ( col1, col2, … ) values ( val1, val2, … ) [ ( val1, val2, … ) ] ;
	对于允许为空的列可以不赋值;有默认值的属性没有赋值时自动设为默认值,可同时插入多行。
对数据表或视图更新数据
update { table_name | view_name } set col = val [ , col1 = val1 , … ] where search_condition ;
	没where就是整列赋值,where子句可以使用其他select子句
对数据表或视图删除数据
delete from { table_name | view_name } where search_condition ;
	没where就是整列删除,注意删除的是行,不可删列。
truncate table table;
	这个不但删了整个表的元素,而所删数据在事务处理日志中还会做相应记录,还比delete效率高。



MySQL导入导出sql文件

window下
1.导出整个数据库
mysqldump -u 用户名 -p 数据库名 > 导出的文件名
mysqldump -u xxxxx -p yyyyyyyy > wwwwwww.sql
2.导出一个表
mysqldump -u 用户名 -p 数据库名 表名 > 导出的文件名
mysqldump -u xxxxx -p yyyyyyyy zzz > wwwwwwww.sql
3.导入数据库(注意sql文件有可能是数据库或表)
source d:/dbname.sql

linux下
一、导出数据库:
mysql的bin目录命令行	mysqldump	-u	用户名	-p	密码	数据库名	>	数据库名.sql
#/usr/local/mysql/bin/   	mysqldump	-u	admin	-p	pass		abcdefg		>	xyz.sql
二、导入数据库
1.当sql文件是一个数据库
mysql	-u	用户名	-p	密码	数据库名	<	数据库名.sql
mysql	-u	admin	-p	pass		abcdefg		<	xyz.sql
2.当sql文件是一个表
(1)选择数据库                    mysql>use abc;
	或者建空数据库				   mysql>create database abc;
(2)设置数据库编码                mysql>set names utf8;
(3)导入数据(注意sql文件的路径) mysql>source /home/abc/abc.sql;



MySQL 连接报错

出现 Authentication plugin 'caching_sha2_password' cannot be loaded
首先登陆,输入密码,然后执行下面四句
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;   #修改加密规则 
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; #更新用户密码 
FLUSH PRIVILEGES;   #刷新权限 
alter user 'root'@'localhost' identified by 'abccba';



Mysql索引

创建索引
CREATE [ UNIQUE ] INDEX indexName ON table_name (column_name)
ALTER table tableName ADD [ UNIQUE ] INDEX indexName(columnName)
删除索引
DROP INDEX [indexName] ON mytable;
ALTER TABLE mytable DROP INDEX indexName;



Mysql存储过程

创建存储过程
DELIMITER $$
USE `shop`$$
DROP PROCEDURE IF EXISTS `proc`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc`()
BEGIN
  SELECT COUNT(*) FROM goods_type;
END$$
DELIMITER ;
	定义时决定传入与传出参数,有in out inout三种,如上例`proc`( in xx integer)
执行存储过程
Call proc_name();
	传入参数a的话就括号里写@a
删除存储过程
Drop procedure proc_name;



Mysql事务

CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci;
USE shop;
CREATE TABLE `account`(
    `id` INT(3) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(30) NOT NULL,
    `money` DECIMAL(9,2) NOT NULL,
    PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO account(`name`,`money`) VALUES('A',2000.00),('B',10000.00);

SET autocommit = 0;
START TRANSACTION;
UPDATE account SET money=money-500 WHERE `name`='A';
UPDATE account SET money=money+500 WHERE `name`='B';
COMMIT;
ROLLBACK;
SET autocommit=1;



part3 sql server

SQL server存储过程

/*创建*/
CREATE PROCEDURE CRE_PRO AS SELECT * FROM brand WHERE cat_name='生鲜食品'
/*执行*/
EXEC CRE_PRO
/*系统存储过程*/
EXEC sp_helptext CRE_PRO
EXEC sp_depends CRE_PRO
EXEC sp_help CRE_PRO
/*修改*/
ALTER PROCEDURE CRE_PRO AS SELECT name,cat_name,cat_id FROM brand WHERE cat_name='运动户外'
/*删除*/
DROP PROCEDURE CRE_PRO



SQL server索引

创建索引
CREATE [UNIQUE] [CLUSTERED|NUNCLUSTERED] //是否唯一索引,是聚类还是非聚类存储
    INDEX 索引名                           //索引名
        ON 表名(属性列……)                  //要生成索列的属性列
            [WITH FILLFACTOR = x]           //生成的索引占总条目的百分比,一般小于30%
使用索引:自动使用
删除索引
DROP INDEX 表名.属性名

举例:
create unique clustered
	index xxx
		on yyy(zzz)
			with fillfactor=30
select * from yyy 
	where zzz 
		between 40 and 60
drop index yyy.xxx




SQL server游标

DECLARE add_cur CURSOR FOR SELECT * FROM user_address	/*声明游标*/
OPEN add_cur                         					/*打开游标*/
FETCH NEXT FROM add_cur            /*执行取数操作*/
WHILE @@fetch_status = 0         	/*判断是否可以继续取数,0成功,非0失败*/
BEGIN								/*while begin … end 是固定搭配*/
  FETCH NEXT FROM add_cur			/* 循环主体就是读取下一行 */
END
CLOSE add_cur                      	/*关闭游标*/
DEALLOCATE add_cur                	/*释放游标*/



SQL server事务

/*启动隐式事务模式*/
SET IMPLICIT_TRANSACTIONS ON
INSERT INTO goods_type VALUES(34,'雪地鞋')
INSERT INTO goods_type VALUES(35,'护手霜')
COMMIT TRANSACTION --提交事务
/*下面的INSERT语句将开始第二个事务*/
INSERT INTO goods_type VALUES(36,'薯片')
SELECT * FROM goods_type
COMMIT TRANSACTION --结束事务
/*关闭隐式事务模式*/
SET IMPLICIT_TRANSACTIONS OFF

BEGIN TRANSACTION UPDATE_DATA
  UPDATE goods SET store_count = 900 WHERE goods_id = 106
  DELETE goods WHERE goods_name = '索尼D7200单反相机'
COMMIT TRANSACTION UPDATE_DATA

BEGIN TRANSACTION
INSERT INTO bookpub (书号,书名) VALUES(9,'一基础学Mysql');
SAVE TRANSACTION SavePoint
INSERT INTO bookpub (书号,书名) VALUES(8,'零基础学Oracle');
SELECT 书号,书名,作者 FROM bookpub;

ROLLBACK TRANSACTION SavePoint
SELECT 书号,书名,作者 FROM bookpub;



SQL server触发器

定义:一种特殊类型的存储过程,是一个可回滚的事务
能够:只能应用在特定的表上,对表插入、更新、删除时自动触发
不能:不能直接调用,不能执行IF,WHILE,CASE等语句

操作	inserted表			deleted表
insert	存放新增记录	 
delete						存放被删记录
update	存放更新后的记录	存放更新前的记录

格式:
go
create trigger trigger_name		     	触发器名
	on table_name                   所属表名
		[with encryption]            	是否上锁
			for[delete,insert,update]    操作类型
	as
		do sth                       触发语句
go

例子:当向表Z插值是就会读出该表中z列的值并赋给X,Y变量,再插入到XY表的x,y列中
select * from z                
select * from xy
go
create trigger trig_insert                    
	on z
		for insert
	as
		declare @x varchar(8),@y varchar(8)
		select @x=z,@y=z from inserted
		insert into xy(x,y) values(@x,@y)
go
insert into z(z) values(4)
select * from z
select * from xy
s
开始时:z表的z属性有3,4两个值,xy表的x属性有3一个值,y属性有3一个值
结束时:z表的z属性有3,4,4三个值,xy表的x属性有3,4两个值,y属笥有3,4两个值



SQL SERVER变量(GO语句中的句子视为一个整体执行)

变量声明格式:declare @变量名 类型
变量赋值格式:set @变量名=值
然后就可以应用到where语句中
go
declare @n varchar(100)
set @n =191
select * from goods where cat_id=@n
go


另外可以从表中读数据赋给变量,如下例子
注意若有多个条目,则变量最终的值是最后一个条目中的值
go
declare @id1 varchar(8),@id2 varchar(10)
select @id1=goods_id,@id2=cat_id from goods
select @id1,@id2
go


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cj1064789374/article/details/115342173