MySQL database basic operation-2#

Multi-table query

查询语法:
	Select 列名列表 From 表名列表 Where ...
笛卡尔积
    有两个集合A,B,取这两个集合的所有组成情况。
    要完成多表查询,需要消除无用的数据
多表查询的分类:
1.内连接查询
    1.隐式内连接;
    	使用Where条件消除无用的数据
    	语法:Select * From 表名列表 别名 Where 条件列表
    2.显示内连接;
    	语法:Select 字段列表 From 表名1 [Inner] Join 表名2 On 条件
    3.内连接查询注意事项:
        1.从哪些表中查询数据
        2.查询条件是什么
        3.查询哪些字段
2.外连接查询
	1.左外连接
        语法:Select 字段列表 From1 Left [Outer] join2 On 条件
        查询的是左表所有数据以及其交集部分
	2.右外连接
        语法:Select 字段列表 From1 Right [Outer] join2 On 条件
        查询的是右表所有数据以及其交集部分
3.子查询
子查询不同情况
    1.子查询结果是单行单列的;
    	子查询可以作为条件,使用运算符去判断
    2.子查询结果是多行单列的;
    	子查询可以作为条件,使用运算符in来判断
    3.子查询结果是多行多列的;
    	子查询的结果作为一张虚拟表
组合查询 union
	MySQL也允许执⾏多个查询(多条 SELECT 语句),并将结果作为单个查询结果集返回。
	这些组合查询通常称为并( union )或复合查询( compound query )。
	UNION规则
		UNION必须由两条或两条以上的 SELECT 语句组成,语句之间⽤关键字 UNION 分隔(因此,如果组合4SELECT 语句,将要使⽤3UNION 关键字)。
        UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)
        列数据类型必须兼容:类型不必完全相同,但必须是 DBMS 可以隐含地转换的类型(例如,不同的数值类型或不同的⽇期类型)。
	注意:
		UNION从查询结果集中⾃动去除了重复的⾏(换句话说,它的⾏为与单条 SELECT 语句中使⽤多个 WHERE⼦ 句条件⼀样)。
		这是UNION的默认⾏为,但是如果需要,可以改变它。如果想返回所有匹配⾏,可使⽤UNION ALL⽽不是 UNION
	对组合查询结果排序:
		SELECT语句的输出⽤ ORDER BY⼦句排序。在⽤ UNION 组合查询时,只能使⽤⼀条 ORDER BY⼦句,它必须出现在最后⼀条 SELECT 语句之后。

Affairs

1.事务的基本介绍
	1.概念:
		如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
	2.操作:
		1.开启事务:Start Transaction
		2.回滚:Rollback
		3.提交:Commit
		4.在mysql数据库中事务默认自动提交
			事务提交的两种方式
				自动提交
					MySQL就是自动提交的
					一条DML(增删改)语句会自动提交一次事务
					DDL( Data Define Language ):都是隐式提交。
				手动提交
					需要先开启事务,再提交 
			修改事务的默认提交方式:
				查看事务的默认提交方式:Select @@autocommit-- 1 代表自动提交,0 代表手动提交
				修改默认提交方式:set @@autocommit = 0
2.事务的四大特征:ACID(重点)
	1.原子性(Atomicity):是不可分割的最小操作单位,要么同时成功,要么同时失败。
	2.一致性(Consistency):事务操作前后数据总量不变
	3.隔离性(Isolation):多个事务之间。相互独立
	4.持久性(Duration):当事务提交或回滚后,数据库会持久化的保存数据
3.事务的并发问题
	脏读:读取到了没有提交的数据, 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。
	不可重复读:同⼀条命令返回不同的结果集(更新).事务 A 多次读取同⼀数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同⼀数据时,结果 不⼀致。
	幻读:重复查询的过程中,数据就发⽣了量的变化( insertdelete )。
3.事务的隔离级别(了解)
	查看隔离级别
		select @@tx_isolation;
	设置隔离级别
		SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别;
	1.读未提交(READ_UNCOMMITTED)
	2.读已提交(READ_COMMITTED)
	3.可重复读(REPEATABLE_READ)
	4.顺序读(SERIALIZABLE4.不同的隔离级别的锁的情况(了解)
	1. 读未提交(RU): 有⾏级的锁,没有间隙锁。它与RC的区别是能够查询到未提交的数据。
	2. 读已提交(RC):有⾏级的锁,没有间隙锁,读不到没有提交的数据。
	3. 可重复读(RR):有⾏级的锁,也有间隙锁,每次读取的数据都是⼀样的,并且没有幻读的情况。
	4. 序列化(S):有⾏级锁,也有间隙锁,读表的时候,就已经上锁了

Database Design

1.多表之间的关系
	1.分类:
		1.一对一(了解):
			*如:人和身份证
			*分析:一个人只有一个身份证,一个身份证只能对应一个人
		2.一对多(多对一):
			*如:部门和员工
			*分析:一个部门有多个员工,一个员工只能对应一个部门
		3.多对多:
			*如:学生和课程
			*分析:一个学生可以选择很多门课程,一个课程可以被很多学生选择
	2.实现关系:
		1.一对多(多对一):
			*如:部门和员工
			*实现方式:在多的一方建立外键,指向一的一方的主键。
		2.多对多:
			*如:学生和课程
			*实现方式:多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
		3.一对一(了解):
			*如:人和身份证
			*实现方式:一对一关系实现,可以在任意一方添加外键指向另一方的主键
2.数据库设计的范式
	*概念:
		设计数据库时,需要遵循的一些规范,要遵循后边的范式要求,必须先遵循前边的所有范式要求
	设计数据库时,遵循不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
	目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF,又称完美范式)。
	*分类:
		1.第一范式(1NF):每一列都是不可分割的原子数据项
			*存在的问题:
				1.存在非常严重的数据冗余(重复):姓名、系名、系主任
				2.数据添加存在问题:添加新开设的系和系主任时,数据不合法
				3.数据删除存在问题:张无忌同学毕业了,删除数据,会将系的数据一起删除。
		2.第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除了非主属性对主码的部分函数依赖)
			*几个概念:
				1.函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
					例如:学号-->姓名,(学号,课程名称)-->分数
				2.完全函数依赖:A-->B,如果A是一个属性组,则B属性值的确定需要依赖于A属性组中所有的属性值
					例如:(学号,课程名称)-->分数
				3.部分函数依赖:A-->B,如果A是一个属性组,则B属性值的确定只需要依赖于A属性组中某一些值即可。
					例如:(学号,课程名称)-->姓名
				4.传递函数依赖:A-->B,B-->C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,再通过B属性(属性组)的值,可以确定唯一C属性的值,则称C传递函数依赖于A。
					例如:学号-->系名,系名-->系主任
				5.码:如果在一张表中一个属性或属性组被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
					例如:该表中码为:(学号,课程名称)
					*主属性:码属性组中的所有属性
					*非码属性:除过码属性组的属性
			*存在的问题:
				1.数据添加存在问题:添加新开设的系和系主任时,数据不合法
				2.数据删除存在问题:张无忌同学毕业了,删除数据,会将系的数据一起删除。
		3.第三范式(3NF):在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)

constraint

概念:对表中数据进行限定,保证数据的正确性、有效性和完整性
分类:
	1.主键约束: primary key
    2.非空约束: not null
    3.唯一约束: unique
    4.外键约束: foreign key

非空约束: not null ,值不能为 null
	1.在创建表时添加非空约束
		列名 数据类型 非空约束
	2.创建表完之后,添加非空约束
    	Alter Table 表名 Modify 列名 数据类型 非空约束
    3.删除非空约束
		Alter Table 表名 Modify 列名 数据类型
唯一约束: unique,值不能重复
	1.在创建表时添加唯一约束
		列名 数据类型 唯一约束
	2.创建表完之后,添加唯一约束
		Alter Table 表名 Modify 列名 数据类型 唯一约束
	3.删除唯一约束
		Alter Table 表名 Drop Index 列名
主键约束: primary key,
	注意:
		1.非空且唯一
		2.一张表只能有一个字段为主键
		3.主键就是表中记录的唯一标识
	1.在创建表时添加主键约束
		列名 数据类型 主键约束
	2.创建表完之后,添加主键约束
		Alter Table 表名 Modify 列名 数据类型 主键约束
	3.删除主键约束
		Alter Table 表名 Drop Primary key
	4.自动增长:
		概念:如果某一列是数值类型的,使用auto_increment可以来完成值的自动增长
		1.在创建表时添加主键约束,并且完成主键自增长
			列名 数据类型 主键约束 auto_increment
		2.创建表完之后,添加自动增长
			Alter Table 表名 Modify 列名 数据类型 自动增长
		3.删除自动增长
			Alter Table 表名 Modify 列名 数据类型
外键约束: foreign key
	1.在创建列表时,可以添加外键
		Constraint 外键名称 foreign key (外键列名称) References 主表名称(主表列名称)
	2.创建表之后,添加外键
		Alter Table 表名 Add Constraint 外键名称 foreign key (外键字段) References 主表名称(主表列名称)
	3.删除外键
		Alter Table 表名 Drop Foreign key 外键名称
级联更新
	1.添加外键,设置级联更新
		Alter Table 表名 Add Constraint 外键名称 foreign key (外键字段) References 主表名称(主表列名称) On Update Cascade;
	2.设置级联删除
		Alter Table 表名 Add Constraint 外键名称 foreign key (外键字段) References 主表名称(主表列名称) On Delete Cascade;

Expand

Stored procedure

⽬前使⽤的⼤多数SQL语句都是针对⼀个或多个表的单条语句。并⾮所有操作都这么简单,经常会有⼀个完整的操作需要多条语句才能完成。
概念:
	存储过程简单来说,就是为以后的使⽤⽽保存 的⼀条或多条MySQL语句的集合。
	储存过程是⼀组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,在需要时直接调⽤。
	存储过程就像脚本语⾔中函数定义⼀样。
为什么要使⽤存储过程?
    优点:
        可以把⼀些复杂的sql进⾏封装,简化复杂操作
        保证了数据的完整性,防⽌错误
        简单的变动只需要更改存储过程的代码即可
        提⾼性能。因为使⽤存储过程⽐使⽤单独的SQL语句要快。(预先编译)
    缺点:
        存储过程的编写⽐SQL语句复杂
        ⼀般可能还没有创建存储过程的权限,只能调⽤
个⼈观点:
	业务逻辑不要封装在数据库⾥⾯,应该由应⽤程序(JAVA、Python、PHP)处理。
	让数据库只做它擅⻓和必须做的,减少数据库资源和性能的消耗。
	维护困难,⼤量业务逻辑封装在存储过程中,造成业务逻辑很难剥离出来。动A影响B。
	⼈员也难招聘,因为既懂存储过程,⼜懂业务的⼈少。使⽤困难。
创建存储过程:
	\d // 修改MySQL默认的语句结尾符 ; 改为 // 。
	create procedure 创建语句
	BEGINEND 语句⽤来限定存储过程体
		案例:
			-- 定义存储过程
            \d //
            create procedure p1()
            begin
            set @i=10;
            while @i<90 do
            insert into users values(null,concat('user:',@i),@i,0);
            set @i=@i+1;
            end while;
            end;
            //
执⾏储存
	call 存储过程别名()
查看存储过程
	show create procedure 存储过程别名\G
删除存储过程
	drop procedure 存储过程别名

trigger

触发器的定义:
	触发器是MySQL响应写操作(增、删、改)⽽⾃动执⾏的⼀条或⼀组定义在BEGINEND之间的MySQL语句
	或可理解为:提前定义好⼀个或⼀组操作,在指定的SQL操作前或后来触发指定的 SQL⾃动执⾏触发器就像是JavaScript中的事件⼀样
触发器语法:
	-- 创建语句
		CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt
    说明:
        # trigger_name:触发器名称
        # trigger_time:触发时间,可取值:BEFORE或AFTER
        # trigger_event:触发事件,可取值:INSERT、UPDATE或DELETE。
        # tb1_name:指定在哪个表上
        # trigger_stmt:触发处理SQL语句。
    -- 查看所有的 触发器
    	show triggers\G;
    -- 删除触发器
    	drop trigger trigger_name;
tips:
    在INSERT触发器代码内,可引⽤⼀个名为NEW的虚拟表,访问被 插⼊的⾏;DELETE触发器代码内,可以引⽤⼀个名为OLD的虚拟表,访问被删除的⾏;
        OLD中的值全都是只读的,不能更新。
        在AFTER DELETE的触发器中⽆法获取OLD虚拟表
    在UPDATE触发器代码中
        可以引⽤⼀个名为OLD的虚拟表访问更新以前的值
        可以引⽤⼀个名为NEW的虚拟表访问新 更新的值;

view

什么是视图?
	视图是虚拟的表。与包含数据的表不⼀样,视图只包含使⽤时动态检索数据的查询。
    视图仅仅是⽤来查看存储在别处的数据的⼀种设施或⽅法。
    视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的。
    在添加或更改这些表中的数据时,视图将返回改变过的数据。
    因为视图不包含数据,所以每次使⽤视图时,都必须处理查询执⾏时所需的任⼀个检索。
    如果你⽤多个联结和过滤创建了复杂的视图或者嵌套了视图,可能会发现性能下降得很厉害。
视图的作⽤
	1. 重⽤SQL语句。
    2. 简化复杂的SQL操作。在编写查询后,可以⽅便地重⽤它⽽不必知道它的基本查询细节。
    3. 使⽤表的组成部分⽽不是整个表。
    4. 保护数据。可以给⽤户授予表的特定部分的访问权限⽽不是整个表的访问权限。
    5. 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
    6. 注意:视图不能索引,也不能有关联的触发器或默认值。
视图的基础语法
	创建视图:
    	create view v_users as select id,name,age from users where age >= 25 and age <= 35;
    -- Query OK, 0 rows affected (0.00 sec)
    view视图的帮助信息:
        mysql> ? view
        ALTER VIEW
        CREATE VIEW
        DROP VIEW
    查看当前库中所有的视图
        show tables; --可以查看到所有的表和视图
        show table status where comment='view'; --只查看当前库中的所有视图
    删除视图v_t1:
    	mysql> drop view v_t1;

optimization:

1. 尽量避免使用 select *,返回无用的字段会降低查询效率,可以使用具体的字段代替*
2. 尽量避免使用 inornot in等,会导致数据库引擎放弃索引进行全表扫描
3. 尽量避免在字段开头模糊查询, null值的判断, where 1=1的条件等,会导致数据库引擎放弃索引进行全表扫描
4. 减少访问数据库的次数
5. 用索引提高效率,避免改变索引类型

Guess you like

Origin blog.csdn.net/BrightZhuz/article/details/108540796