MySQL笔记整理

1.数据库库

存取数据的仓库

2.数据的分类

1.网络数据库

 	网络数据库是指把数据库技术引入到计算机网络系统中,借助于网络技术将存储于数据库中的大量信息及时发布出去,而计算机网络借助于成熟的数据库技术对网络中的各种数据进行有效的管理,并实现用户与网络中的数据库进行实时动态交互。

2.层级数据库

	层次结构模型实质上是一种有根结点的定向有序树(在数学中“树”被定义为一个无回的连通图)

3.关系数据库

	关系数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
	数据库的另一种区分方式:基于存储介质
		存储介质:磁盘,内存
				关系型数据库(存储在磁盘中)
				非关系型数据库(存储在内存中)

3.关系型数据库

1.关系模型由关系数据库、关系操作集合、关系完整约束三部分组成。
	关系数据结构:指的数据以什么方式来存储,本质是一种二维表
	关系操作组合: 如何来关联和管理对应的存储数据,SQL指令
	关系完整性约束:数据内部有对应的关联关系,以及数据与数据之间也有对应的关联关系
		表内约束:对应的具体列只能放对应的数据,不能乱放
		表间约束:自然界各实体都有着对应关系(典型的有外键)
2.典型关系型数据库
	小型数据库:Microsoft Access,SQLite
	中型数据库:SQLServer,Mysql
	大型数据库:Oracle,DB2

4.SQL

	SQL:结构化查询语言,专门为关系型数据库而设计出来的
	SQL的分类:
		1.数据查询语言(DQL)
			也称为数据检索语句,专门用于查询数据(代表指令:SELECT/SHOW)
		2.数据操作语言(DML)
			专门用于写数据(代表指令:INSERT/UPDATE/DELETE)
		3.事务处理语言(TPL)
			它的语句能确保被DML语句影响的表所有行及时得以更新,专门用于事务安全处理:transaction
		4.数据控制语言(DCL)
			通过GRANT或REVOKE获得许可,确定单个用户和用户组对数据库对象的访问,某些RDBMS可用GRANT或REVOKE控制对表单个列的访问
			专门用于权限管理:代表指令为grant和revoke
		5.数据定义语言(DDL)
			在数据库中创建表或删除表,加表索引等,也是动作查询的一部分。专门用于结构管理:代表指令CREATE和DROP(ALTER)

5.MySQL

1.MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前数据Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一。

	在WEB应用方面,MySQL是最好的RDBMS(关系数据库管理系统)应用软件。
	MySQL是一种开源免费的数据库产品
	MySQL对PHP的支持是最好的(wamp或者lamp)
	MySQL中用到的操作指令就是SQL指令

2.启动和停止MySQl服务

	MySQL是一种C/S结构:客户端和服务端
	服务端对应的软件:MySQLd.exe
		命令行:net stop mysql57  关闭
				net start mysql57  开启
				需要管理员权限运行命令提示符
		系统服务方式:
				前提:在安装mysql的时候将mysql添加到Windows的服务中去
				方式1:进入服务 我的电脑--管理--服务--找到mysql,启动和关闭操作
				方式2:进入服务	通过命令行services.msc

3.登录和退出mysql系统

	通过客户端(mysql.exe)与服务器进行连接认证,就可以直接操作
	通常:服务器与客户端不在同一台电脑上
	登录:
		1.找到mysql.exe(通过控制台:如果在安装的时候指定了mysql.exe所在的路径为环境变量,就可以直接访问,如果没有就必须进入到mysql.exe所在的路径(安装目录的bin目录))
		2.输入对应的服务器地址:-h:host -h[IP地址/域名]
		3.输入服务器中Mysql监听的端口:-P:host -P:3306
		4.输入用户名:-u:username -r:root
		5.输入密码:-p:password -p:root
			链接认证的基本语法:
				mysql.exe/mysql -h主机地址 -P端口号 -u用户名 -p密码
				mysql.exe -h127.0.0.1 -P3306 -uroot -proot   GRANT ALL ON databasename.tablename TO 'username'@'host' 
		注意事项:
			1.通常端口都可以默认:mysql监听的端口通常都是3306
			2.密码的输入可以先输入-p,直接换行,然后以密文的方式输入密码
		6.退出:
			断开与服务器的链接:通常Mysql提供的服务器数量有限,一旦客户端用完建议断开链接
			建议方式:使用SQL指令的方式
					Exit; 带分号
					\q; //quit缩写
					Quit;

4.mysql服务端的架构

	Mysql服务端的架构分为以下几层
		1.数据库管理系统(最外层):DBMS,专门管理服务端的所有内容
		2.数据库(第二层):DB,专门用于存储数据的仓库(可以有多个)
		3.二维数据库表(第三层):Table,专门用于存储具体实体的数据
		4.字段(第四层):field,具体存储某种类型的数据(实际存储单元)
	数据库中常用的几个关键字
		Row:行
		Column:列(field)

5.数据库基本操作

	数据库是数据存储的最大单元(最外层)
1.数据库操作
	1.创建数据库
		create database 数据库名称;
		create database 数据库名称 charset utf8;
	2.显示数据库
		每当用户通过sql指令创建一个数据库,那么系统就会产生一个对应的存储数据的文件夹(data)
		显示全部:
			show databases;
		显示部分:
			show databases like '匹配模式';
			_:匹配当前位置单个位置
			%:匹配指定位置多个位置
	3.选择数据库
		如果要操作数据库中的表,必须要先进入数据库。
		基本语法: use 数据集名字; 
	4.修改数据库
		修改数据库字符集(库选项)
		语法:alter database mydatabase charset gbk;
		mysql5.5之前可以修改数据库名字,5.5以后不能修改数据库名字(rename)
	5.删除数据库
		drop database mydatabase;
		删除虽然简单,但是要确保里面数据没有问题。(重要)
		2.表操作
			1.创建数据表
				普通创建表:
					基本语言:create table 表名(字段名 字段类型[字段属性],字段名 字段类型[字段属性],....)
					[]  :表选项

					表必须放到对应的数据库下,有两种方式可以将表挂到指定的数据库下:
						1.在数据库表名字前添加数据库名字,用.链接
						2.use 选择数据库
				复制已有表结构:
					create table t_user2 like center.t_user;
2.显示数据表
	每当一张数据表创建,那么就会在对应的数据库下创建一些文件(与存储引擎有关)
	1.显示所有表
		show tables like '%c';
	2.Describe tablename
		Desc tablename;
		show columns form tablename; 
	3.显示数据表创建时的语句
		不是自己输入的,已经被加工过
		show create table t_user2;
	3.修改表结构
		1.修改表名
			rename table tb_student to mytb_student;
		2.修改表选项
			alter table 表名 表选项[=]新值
			1.添加字段
				alter table mytb_student add column age int;
			2.修改字段名
				alter table mytb_student change age nj int;
			3.修改字段类型
				alter table mytb_student modify name varchar(20);
			4.删除字段
				alter table mytb_student drop nj;
	4.删除表
		drop table 表名[,....];
		drop table tb_1,tb_2;
3.数据操作
	1.插入记录
		insert into my_student(name,age) values('jack',30);
		insert into my_student value('Lilei',35);
	2.查询
		select * form 表名;
		select [字段列表] from 表名;
		select [字段列表/*] from where name = '张三';
	3.删除
		delete from 表名 [where 条件];
	4.修改(更新)
		update 表名 set 字段名 = 新值 where 条件;

6.字符集简介

		字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同。
		常见的字符集名称:ASCII字符集,GB2312字符集,BIG5字符集,GB18030字符集,Unicode字符集等..
	设置客户端所有字符集
		如果直接通过cmd下的mysql.exe进行中文数据插入可能出错。
		出错原因:
			用户是通过mysql.exe来操作mysqlId.exe
			真正的SQL执行是MysqlId.exe执行的
			mysql.exe将数据传入mysqlId.exe时没有告知对应的符号规则,而mysqlId.exe也没有能力自己判断,就会使用自己默认的字符集。
		解决方案:mysql.exe客户端在进行数据操作之前将自己所使用的字符集告诉mysqlId
			mysql.exe告知mysqlId.exe
			快捷方式:set names gbk;
	深层原理
		客户端、服务端,连接层(show variables like 'character_set%')

7.列类型

	1.整形
		1.整形类型分类
			1.Tinyint 迷你整形,系统采用一个字节来保存的整形,范围是-128~127
			2.Smallint 小整形,系统采用两个字节来保存的整形
			3.Mediumint 中整形,采用三个字节保存整形
			4.Int 标准整形,系统采用四个字节保存整形
			5.Bigint 大整形,系统采用八个字节保存整形
			注:如果超出范围会提示错误,mysql默认保存负数空间,在实际的应用中应该根据对应的数据范围来选定对应的整形类型
				通常使用较多的是TINYINT和INT
			2.无符号,表示存储的数据在当前字段中,没有负数(只有整数,区间为0~255)
				基本语法:在类型之后加上一个unsigned	
			3.显示长度
				注:Tinyint(3) 括号中的3表示显示的最长长度
				zerofill:从左侧开始填充0(左侧不会改变原数值的大小),如果使用负数,则不能使用zerofill,因为负数前面填充0会
					改变原数据大小。zerofill可以指定长度,但是不能超出能显示的最大范围
	2.小数类型
		1.浮点型
			浮点型有又称为精度类型,是一种有可能丢失精度的数据类型,数据有可能不那么准确,尤其是在超出范围的时候
			1.Float
				又称之为单精度类型,系统提供4个字节用来存储数据,但是能表示的数据范围比整形大得多,大概是10
				^38;只能保证7个左右的精度。
			2.Double
				又称之为双精度,系统使用8个字节来存储数据,表示的范围更大,10^308次方,但是精度也只有15位左右
			注:之所以会比整形保存更大的范围,是因为一部分用来存储数据,有部分用来存储指数
			3.基本语法
				Float:表示不指定小数位的浮点数
				Float(M,D):表示一共存储M个有效数字,其中小数部分占D位
			4.精度丢失
				如果发生精度丢失,那么mysql默认是进行四舍五入
				用户不能插入数据直接超过指定的整数部分长度,但是如果是系统自动进位导致的,系统可以承担
			5.浮点型可以采用科学计数法来存储数据
				eg:10e5 表示10的五次方
				浮点数的应用:通常用来保存一些数量特别大,大到可以不用那么精确的数据。
		2.定点型
			定点数就是能够保证数据精度的小数(不能保证的是小数部分不精确,因为超出小数部分会四舍五入,但是整数部分一定精确)
			1.Decimal
				Decimal定点数:系统自动根据存储的数据来分配存储空间,每大概9个数的时候就会分配4个字节来进行存储,
				同时整数部分和小数部分是分开的。
			2.基本语法
				Decimal(M,D):M表示总长度,最大值不能超过65,D表示小数位长度,最长不能超过30位
				(Decimal最大能表示35位的整数和30位的小数)
			4.定点数如果整数进位超出则会报错,没办法像浮点数一样由系统承担
			一般涉及到钱的地方都使用定点数来保证数据的精确性。
	3.时间类型
		Date
			日期类型,系统使用三个字节来存储数据,对应的格式为YYYY-mm-dd,能表示的范围是从1000-01-01到
			9999-12-12,初始值为0000-00-00
		Time
			时间类型:系统提供三个字节来存储,能够表示某个指定时间,对应的格式为HH:ii:ss,但是mysql中的time
			类型能够表示时间范围要大得多,能表示从-838:59:59~838:59:59,在mysql中是用来处理描述时间段。
			在进行时间类型录入的时候还可以使用一个简单的日期代替时间,在时间格式之前加上一个空格,然后指定一个数字,
			系统会自动将该数字(可以是负数)转换成天数*24小时,再加上后面的时间

		Datetime
			将前面的Date和Time合并起来,表示的时间使用8个字节,格式为YYYY-mm-dd HH:ii:ss,能表示的范围区间
			1000-01-01 00:00:00 - 9999-12-12 23:59:59
		Timestamp
			时间戳类型:mysql中的时间戳指标上从格林威治事件开始,但是其格式依然是YYYY-mm-dd HH:ii:ss
			当对应的数据被修改的时候,其值会被修改成当前的格林威治时间
		Year
			年类型:占用一个字节来保存,能表示1900-2155年,但是year有两种数据插入方式:0-99和四位的具体年
			进行两位数插入的时候有特殊性,当输入的是69及以下匹配的是2069,70以上匹配的是1970
	4.字符串类型
		Char
			指定长度后,系统一定会分配指定空间用于存储数据
			基本语法:char(L),L代表字符数(中文与英文字符一视同仁,都一样),长度范围为0~255
		VarChar
			变长字符:指定长度之后,系统会根据实际存储的数据来计算长度,分配合适的长度(数据没有超出长度)
			基本语法:varchar(L), L代表字符数,L的长度理论值0-65535
			因为varchar要记录数据长度(系统根据长度自动分配空间),所以每个varchar数据产生后,系统都会在数据后面增加1-2个字节
			的额外开销,是用来保存数据所占用的控件长度,如果数据本身小于127个字符,额外开销一个字节,如果数据大于127个,
			就开销两个。

			char和varchar的区别:
				1.char一定会占用指定的空间,varchar是根据数据来确定空间
				2.char的数据的查询效率比varchar高,varchar需要通过后面的记录数来计算

				如果确定数据一定是占用指定长度,那么使用char类型
				如果不确定数据到底占用多少,那么使用varchar类型
				如果数据长度超过255个字符,不论是否固定长度,都会使用text,不会再使用char和varchar
		Text
			文本类型:本质上mysql提供了两种文本类型
			Text:存储普通的字符文本
			Blob:存储二进制文本(图片,文件),一般都不会使用blob来存储文件本身,通常使用一个连接来指向对应的文件本身。

			Text:系统提供了四种text
			Tinytext:系统使用一个字节来保存,实际能够能够使用的数据存储为:2^8+1
			Text:系统使用两个字节来保存,实际能够能够使用的数据存储为:2^16+2
			Mediumtext:系统使用三个字节来保存,实际能够能够使用的数据存储为:2^24+3
			Longtext:系统使用四个字节来保存,实际能够能够使用的数据存储为:2^32+4

			注:
			1.在选择对应的存储文本的时候,不用刻意的去选择text类型,系统会自动根据存的数据长度来选择合适的文本类型。
			2.在选择字符存储的时候如果超过255则选择Text性能会更好,而且更省空间
		Enum
			枚举类型:在数据插入之前,先设定几个项,在这几个项就是可能最终会出现的数据结果。
			如果确定某个字段的数据只有那么几个值,如性别只有男和女,系统就可以在设定字段的时候规定当前字段只能存放固定的
			几个值:使用枚举
			基本语法:
				enum(数据1,数据2.....)
			枚举enum的存储原理:实际上字段上所存储的值并不是真正的字符串,而是字符串所对应的下标,当系统设定枚举的时候,
			会给枚举中的每个元素定义一个下标,这个下标规则从1开始
			Enum(1=>男,2=>女)
			特性:在mysql中系统是自动进行类型转换的,如果数据碰到“+-*/”,系统会自动将数据转换成数值,而普通字符串转换成
			值为0
			既然枚举类型使用的是数值,那么在插入的时候就可以使用对应的数值进行插入
			枚举的意义:
				1.规范数据本身,限定只能输入规定的输入项
				2.节省存储空间
		Set
			集合:是一种将多个数据选项可以同时保持的数据类型,本质是将指定的项按照对应的二进制位来进行控制,
				1表示选中,0表示未选中
			基本语法:set('值1','值2',....)
			系统会根据set提供了多个字节进行保存,但是系统会自动计算来选择具体的存储单元
				1个字节:set只能有8个选项
				2个字节:set只能有16个选项
				3个字节:set只能有24个选项
				8个字节:set只能有64个选项
				set中最多只能放64个选项
			Set和enum一样,最终存放的是数字,而不是字符串
			set集合会按照创建表的时候的顺序进行编排,与插入时的顺序无关
			数据在存储的时候,如果被选中则对应的位的值为1,未被选中则对应的位的值为0
			系统在进行存储的时候会自动将得到的最终的二进制颠倒过来,然后再转换成二进制进行存储
			Set的意义:
				规范数据
				节省空间

8.mysql记录长度

	在mysql中,有一种规定:mysql的记录长度(record==行 row)总长度不能超过65535个字节Varchar能够存储的理论值为65535个字节,字符在不同的字符集下可能占用多个字节

9.字段属性(列属性)

	列属性又称之为字段属性,在mysql中一共有6个属性,null,默认值,列描述,主键,唯一键和自动增长
	1.NULL属性
		代表字段是否可以为空
		如果为YES,则字段可以为空
		如果为NO,则字段不可以为空
		注意:
			在设计表的时候,尽量不要让数据为空
			Mysql的记录长度为65535个字节,如果一个表中有字段允许为NULL,那么系统就会设计一个字节来存储NULL,
			最终有效长度为65534个字节
	2.默认值(Default)
		当字段被设计的时候,如果允许默认情况下,用户不进行数据的插入,那么久可以使用事先准备好的数据来填充,通常填充的是NULL

10.列描述

	comment是专门用来给开发人员进行维护的一个注释说明
	基本语法:comment'字段描述';
	查看Comment:必须通过查看表创建语句

11.主键

	主要的键,primarykey,在一张表中,有且只有一个字段,里面的值具有唯一性
	创建主键
		随表创建
			方案1:直接在需要当做主键的字段之后,增加primarykey属性来确定主键   
				create table my_pri1(username varchar(10)primary key)charset utf8;
			方案2:在所有字段之后增加primarykey选项:primarykey(字段信息)	       
				create table my_pri2(username varchar(10),primary key(username))charset utf8;
		表后增加
			创建完表之后添加主键
				alter table my_pri3 add primary key(username);
		查看表结构
			desc tablename;
		删除主键
			alter table my_pri3 drop primary key;
		复合主键
			primary key(username,usernumber);
	主键约束
		1.当前字段对应的数据不能为空
		2.当前字段对应的数据不能存在重复

	主键的分类
		1.业务主键
			主键所在的字段,具有业务逻辑意义(学生ID,课程ID)	
		2.逻辑主键
			自然增长的整形(应用广泛)

12.自动增长

	auto_increment,当给定某个字段该属性后,该列的数据在没有提供确定数据的时候,系统会根据之前已经存在的数据进行自动增加后
	填充数据
	通常自动增长用于逻辑主键,
	原理:
		1.在系统中有维护一组数据,用来保存当前使用了自动增长属性的字段,记住当前对应的数据值,再给定一个指定的步长
		2.当用户进行数据插入的时候,如果没有给定值,系统在原始值上再加上步长编程新的数据
		3.自动增长的触发:给定属性的字段没有提供值
		4.自动增长只适用于数值
	语法:
		建表时在想要自动增长的字段后面加上 auto_increment 
	查看自增长
		自增长一旦触发使用后,会自动在表的选项中增加一个选项(一张表最多只能有一个自增长)
	修改自增长
		alter table my_auto auto_increment = 10;
	删除自增长
		就是在字段属性之后不再保留auto_increment
		alter table my_auto modify id int;
	初始设置
		在系统中,有一组变量用来维护自增长的初始值和步长

14.唯一键

	unique key,用来保证对应的字段中的数据唯一
	主键也可以保证数据的唯一,但是一张表只能有一个主键
		1.唯一键可以有多个
		2.唯一键允许数据为NULL,NULL可以有多个(NULL不参与比较)
	创建唯一键
		创建唯一键与创建主键非常类似
		1.直接在表字段之后增加唯一键标识符:unique[key]
		2.在所有字段之后使用   unique key(唯一键列表)
		3.创建完表之后也可以增加唯一键
	查看唯一键
		desc my_unique2
	删除唯一键
		alter table my_unique2 drop index username;
	符合唯一键
		唯一主键和主键一样,可以使用多个字段来共同保证唯一性

15.表关系

	表与表(实体)之间有什么样的关系,每种关系应该如何设计表结构。
	1.一对一
		一张表中的一条记录与另外一张表中最多有一条明确的关系,通常,此设计方案保证两种表中使用同样的主键即可
		在表的使用过程中,常用的信息会经常去查询,而不常用的信息会偶尔才会用到。
		解决方案:将两张表进行拆分,常见的用一张表,不常用的放另一张表
	2.一对多
		一对多通常也叫多对一关系,通常一对多的关系设计的方案,在“多”关系的表中去维护一个字段,这个字段是“一”关系的主键

	3.多对多
		一张表中的一条记录在另一张表中可以匹配到多条记录,反过来也一样
		多对多的关系如果按照多对一的关系维护,就会出现一个字段中有多个其他表的主键,在访问的时候带来不便。
		既然两张表自己增加字段解决不了,就通过第三张表来解决
		多对多解决方案:
			增加一个中间表,让中间表与对应的其他表形成两个多对一关系,多对一的解决方案是在“多”的一方增加“一”一方的主键
			字段作为外键

16.高级数据操作

	1.新增数据
		1.多数据操作
			只要写一次insert指令,但是可以直接插入多条记录
			基本语法:
				insert into tablename [字段列表] values((值列表),(值列表)....)
		2.主键冲突
			在有的表中,使用的是业务主键(字段有业务含义),但是往往在进行数据插入的时候,又不确定数据表中是否
			已经存在对应的主键。

			主键冲突的解决方案:
				主键冲突更新
					类似插入数据语言,如果插入的过程中主键冲突,那么采用更新方法
					insert into 表名 [字段列表] values (值列表) on duplicate key update 字段 = 新值;
				主键冲突替换
					当主键冲突后,干掉原来的数据,重新插入进去
					replace into[字段列表] values (值列表);
		3.蠕虫复制
			蠕虫复制:一分为二,成倍的增加。从已有的数据中获取数据,并且将获取的数据插入到数据表中。
			基本语法:
				insert into 表名[字段列表] select *[或者字段列表] from 表名;
			意义:可以在短期内快速增加表的数据量,从而测试表的压力,还可以通过大量数据来测试表的效率(索引)
	2.更新数据
		1.在更新数据的时候,特别要注意:通常一定是跟随条件更新
			update 表名 set 字段名 = 新值 where 条件;
		2.如果没有条件,是全表更新数据。但是可以使用limit来显示更新的数量
		update 表名 set 字段名 = 新值 [where 判断条件] limit 数量;
		改变4个a变成e
	3.高级删除操作
		1.删除数据的时候尽量不要全部删除,应使用条件来限制,可以使用limit限定删除的数量
			delete删除的时候无法重置auto_increment
		2.mysql有一个能够重置表选项中的自增长的语法
			Truncate 表名; 先删除,后重新创建。
	4.高级查询
		1.完整的查询指令
			select select选项 字段列表 from 数据源 where 条件 group by 分组 having 条件 order by 排序 limit 限制数量
		1.select选项:系统该如何对待查询得到的结果
			All:默认的,表示保存所有的记录
			Distinct:去重,出去重复字段,只保留一条记录。这里的重复指的是所有的字段全部一致
		2.字段列表
			有时候需要从多张表中获取数据,这时候可能存在不同的表中有同名的字段,这时候需要将同名字段命名成不同
			名的,别名
			基本语法
				字段名 [as] 别名
		3.from 数据源
			from是为前面的查询提供数据:数据源只要是一个符合二维表结构的数据即可
			1.从多张表获取数据
				基本语法
					from 表名列表
				结果:两张表的记录数相乘,字段数拼接
				本质:从第一张表中取出一条记录,去拼接第二张表中的所有记录,保留所有结果。
					得到的结果在数学上有一个专业的说法:笛卡尔积,这个结果除了给数据库造成压力没有其他
					任何意义。应该尽量避免笛卡尔积
			2.动态数据
				select * form (select * from 表名) as 别名;
		4.where字句
			where字句:用来从数据表获取数据的时候,然后进行条件筛选。
			数据获取原理:针对表去对应的磁盘处获取所有的记录(一条条),where的作用就是拿到一条结果就开始进行
			判断,判断是否符合条件,如果符合条件就保存下来,如果不符合直接舍弃(不放到内存中)
			where是通过运算符进行结果比较来判断数据。
		5.group by子句
			group by 表示分组的含义:根据指定的字段,将数据进行分组,分组的目的是为了统计。
			1.分组统计
				group by 字段名; 
			group by 是为了分组后进行数据统计的,如果只是想看数据显示,那么group by没什么含义
			group by 将数据按照指定的字段进行分组后,只会保留每组的第一条记录。
			
			我们需用使用一些统计函数:
				count():统计每组中的数量,如果统计目标是字段,那么不统计为空NULL字段
				avg() : 求平均值
				sum() :求和
				max() : 求最大值
				min() : 求最小值
				group_concat():为了将分组中指定的字段拼接起来(字符串拼接)
			2.多分组
				将数据按照某个字段进行分组后,对已经分组的数据进行再分组
				1.基本语法
					group by 字段1,字段2....;
			3.分组排序
				MYSQL中,分组默认有排序,按照分组进行升序排序
				基本语法:group by 字段[asc|desc],字段[asc|desc]
			4.回溯统计
				当分组进行多分组之后,往上统计的过程中,需要进行层层上报,将这种层层上报统计的过程
				称之为回溯统计,每一次分组向上统计的过程中都会产生一次新的统计数据,而且当前数据对应的分组
				字段为NULL
				基本语法:group by 字段 [asc|desc] with rollup;
	5.Having子句
		Having的本质和where一样,是用来进行数据条件筛选
		1.Having是在group by子句之后,可以针对分组数据进行筛选,having在group by分组之后,可以使用聚合函数或者字段别名,
		where是从表中取出数据,别名是在数据进入到内存之后才有的
	6.order by
		排序:根据校对规则进行排序
		基本语法:order by 字段[asc|desc]; asc升序  desc降序
		order by也可以进行多字段排序
		基本语法:
			order by 字段[asc|desc],字段[asc|desc]....;
			先按照字段1进行排序,再按照字段而进行排序
	7.limit子句
		限制子句:主要用来限制记录数的数量
		limit通常在查询的时候如果限定为一条记录的时候,使用的比较多:有时候如果获取多条记录并不能解决业务问题,但是
		会增加服务器的压力
		
		分页:
			利用limit限制获取指定区间的数据
			基本语法
				limit offset,length;//offset偏移量,从哪开始,length就是获取多少条记录
			mysql中记录的数量从0开始

17.运算符

	1.算术运算符
		+  -  *  /  %
		基本算术运算:通常不在条件中使用,而是用于结果运算(select 之后)
		mysql中的除法运算结果是用浮点数表示,除法中除数如果为0,系统会给NULL
		拿NULL进行任何的算术运算,结果都为NULL
	2.比较运算符
		>  >=  < <= =  <>不等于
		通常用来在条件中进行限定结果,在mysql中没有bool值,1代表真,0代表假
	3.between 闭区间
		基本语法
			between 条件1,条件2
		条件1必须小于条件2
	4.逻辑运算符
		and:逻辑与
		or:逻辑或
		not:逻辑非
	5.in运算符
		用来替代=,当结果不是一个值,而是一个结果集的时候
		基本语法:in(结果1,结果2,....)
	6.is运算符
		is是专门用来判断结果是否为空的运算符
		基本语法:is null    is not null
	7.like运算符
		进行模糊匹配的
		基本语法:like '匹配模式'
		_ : 匹配单个字符
		% : 匹配零到多个字符

18.联合查询

	1.基本概念
		联合查询是可合并多个相似的选择查询的结果,等同于将一张表追加到另一张表,从而实现将两个表的查询组合到一起,使用为此为
		union或者union all
		联合查询:将多个查询的结果合并到一起(纵向合并),字段数不变,多个查询的记录数合并
	2.应用场景
		1.将同一张表中不同的结果(需要对应多条查询语句来实现,合并到一起展示数据)
			男生身高升序排序,女生身高降序排序
		2.最常见:在数据量大的情况下,会对表进行分表操作,需要对每张表进行部分数据统计,使用联合查询将数据存放到一起显示
	3.基本语法
		select语句
		union [union选项]
		select语句;

		union选项:与select选项基本一致
		distinct:去重(默认)
		all:保存所有的语句
	
	4.在联合查询中要使用order by,则前面的select语句要使用括号
		order by在联合查询中必须使用limit,而limit后面必须跟对应的限制数量,这里通常使用一个较大的数,大于总数即可。

19.链接查询

	将多张表连到一起进行查询(会导致记录数行和字段数列发生改变)
	1.链接查询的意义
		在关系型数据库设计过程中,实体(表)与实体之间是存在很多联系的,在关系型数据库表的设计过程中,遵循着关系来设计
		:一对一,一对多,多对多,通常在实际操作的过程中,需要利用这层关系来保证数据的完整性

	2.链接查询分类
		1.链接查询一共有以下几类
			1.交叉链接
				将两张表的数据与另外一张表彼此交叉
				1.原理:
					1.从第一张表一次取出每一条记录
					2.取出每一条记录后,与另外一张表的全部记录挨个匹配
					3.没有任何匹配条件下,所有的结果都会进行保留
					4.记录数 = 第一张表记录数*第二张表的记录数  字段数 =  第一张表记录数+第二张表的记录数
					笛卡尔积
				2.基本语法:
					表1 cross join 表2;
				3.应用
					在实际使用中,交叉链接的结果是笛卡尔积,没有实际应用。
			2.内链接
				inner join 从一张表中取出所有的记录去第二张表中进行匹配,利用匹配条件进行匹配,成功了则保留,失败了放弃。
				1.原理
					1.从第一张表中取出所有的记录,然后去另一张表中进行匹配
					2.利用匹配条件进行匹配
						2.1:匹配到:保留,继续向下执行。
						2.2:匹配失败:向下继续,如果全表匹配失败,结束
				2.基本语法
					表1 [inner] join 表2 on 匹配条件;  

					如果内连接没有匹配条件,则其实的交叉链接,结果是笛卡尔积
				3.内连接必须保证匹配到才会有结果
				4.内连接因为不强制必须使用匹配条件(on)因此可以在数据匹配完成之后,使用where条件,效果与on一样。
				5.应用
					通常在对数据有精确要求的地方使用,必须保证两张表中都能进行数据匹配。
			3.外链接
				
				outer join,按照某一张表作为主表,(表中所有记录在最后都会保留),根据条件去连接另外一张表
				从而获取到数据。
				外链接分为两种
					1.左外连接(left join):左表是主表
					2.右外连接(rigth join):右表是主表
				1.原理
					1.确定连接主表,左连接就是left join左边的表为主表,rigth join就是右边为主表
					2.拿主表的每一条记录,去匹配另外一张表(从表)的每一条记录
					3.如果满足匹配条件:保留 不满足则不保留
					4.如果主表记录在从表中一条都没有匹配成功,那么也要保留该记录,从表对应的字段值都没NULL
				2.基本语法
					1.左连接
						主表 left join 从表 on 连接条件
					2.右连接
						主表 rigth join 从表 on 连接条件
				3.特点
					1.外链接中主表数据记录一定会保存,连接之后数据量一定不会少于主表
				4.应用
					非常常用的一种获取数据的方式,作为数据获取对应主表以及其他数据(关联)
			4.using关键字
				using 是在链接查询中用来代替对应的on关键字的,进行条件匹配。
				1.原理
					1.在链接查询时,使用on的地方用using代替
					2.使用using的前提是对应的两张表链接的字段同名(类似于自然链接,自动匹配)
					3.如果使用using关键字,那么对应的同名字段,最终会再结果中只保留一个
				2.语法
					表1 [left|rigth|...] join 表2 using(同名字段); 

20.子查询

	1.子查询概念
		sub query,子查询是一种常见的计算机select-sql语言中嵌套下层的程序模块,当一个查询是另一个查询的条件时,称之为子查询。
		指在一条select语句中,嵌套了另外一条select语句,那么被嵌入的select语句称之为子查询语句。
	2.主查询概念
		主要的查询对象,指第一条select语句,确定用户所有获取的数据目标(数据源),已经要具体到得到的字段信息
	3.子查询的分类
		1.按功能划分
			1.标量子查询:子查询返回的结果是一个数据(一行一列)
				基本语法:
					select * from 数据源 where 条件判断 =/<> (select 字段名 from 数据源 where 条件判断)
			2.列子查询:返回的是一列
				基本语法:
					select * from 数据源 where 条件 in(列子查询)
			3.行子查询:返回的是一行
				行元素:字段元素是指一个字段对应的值,行元素对应的就是多个字段,多个字段合起来作为一个元素参与
				运算,把这种情况称之为行元素。
				基本语法:
					主查询 where 条件[(构造一个行元素)] = (行子查询)
			4.表查询:返回的是多行多列,表子查询与行子查询非常相似,只是行子查询需要产生行元素,而表子查询没有。
				行子查询是用于where条件判断:where子查询
				表子查询是用于from数据源:from子查询
				基本语法:
					select 字段表 from (表子查询) where.....将
			5.Exists查询:返回的结果是0或者1
				基本语法:
					where exists(查询语句) ;//exists就是根据查询得到的结果进行判断,如果结果存在,那么返回1,否则返回03
		2.按位置划分
			1.where子查询:子查询出现的位置在where条件中 (作为条件)
			2.from子查询:子查询出现的位置在from数据源中(作为数据源)
	4.子查询中特定的关键字
		1.in
			主查询 where 条件 in (列子查询)
		2.any
			任意一个
			= any(列子查询):条件在查询结果中有任意一个匹配即可,等价于in
			<> any(列子查询):条件在查询结果中不等于任意一个

		3.some
			与any完全一样	
		4.all
			= all(列子查询):等于其中的所有
			<> all(列子查询):不等于其中的所有

			如果对应的匹配字段有NULL,那么NULL不参与匹配

21.整库数据备份与还原

	整库数据备份也叫SQL数据备份,备份的结果都是SQL指令
	在MySql中提供了一个专门用于备份SQL的客户端:mysqldump.exe
	1.应用场景
		SQL备份是一种mysql非常常见的备份与还原方式,SQL备份不只是备份数据,还备份对应的SQL指令(表结构),即便遭受到毁灭性
		的破坏,那么利用SQL备份依然可以实现数据还原。

		SQL备份因为需要备份结构,因此产生的备份文件特别大,因此不适合特大型数据备份,也不适合数据变换频繁型数据库备份。
	2.应用方案
		1.sql备份
			SQL备份用到的是专门的备份客户端,因此还没与数据库服务器进行连接。
			基本语法:mysqldump/mysqldump.exe -hPup 数据库名字[表1 [表2]] > 备份文件地址
			备份有三种形式:
				1.整库备份
					mysqldump.exe -hlocalhost -P3306 -uroot -p123456 world > E:/world.sql
				2.单表备份
					mysqldump.exe -hlocalhost -P3306 -uroot -p123456 world mytable1 > E:/world1.sql
				3.多表备份
					mysqldump.exe -hlocalhost -P3306 -uroot -p123456 world mytable1 mytable2 mytable3 > E:/world2.sql
		2.数据还原
			mysql提供了两种方式来实现数据还原
			Mysqldump备份的数据中没有关于数据库本身的操作,都是针对表级别的操作,当进行数据还原(SQL还原),必须指定数据库
				1.利用mysql.exe客户端:没有登录之前,可以直接用该客户端进行数据还原
					基本语法:
						mysql.exe -hPup 数据库 < 文件位置
				2.在SQL指令,提供了一种导入SQL指令的方式
					Source SQL文件位置;//必须先进入到对应的数据库

22.用户权限管理

	用户权限管理,在不同的项目中给不同的角色(开发者)不同的操作权限,为了保证数据库数据的安全。
	通常,一个用户的密码不会长期不变,所以需要经常性的变更数据库用户密码来确保用户本身安全(mysql客户端用户)
	1.用户管理
		mysql需要客户端进行连接认证才能进行服务器操作,需要用户信息。mysql中所有的用户信息都是保存在mysql数据库下的user表中。
		查看用户:
			select * from mysql.user\G
			默认的,在安装mysql的时候,如果不选择创建匿名用户,那么以为着所有的用户只有一个:root超级用户
			在mysql中:用户管理中的用户是由Host和User共同组成主键来区分的,User代表的是用户名,Host代表的可以访问的主机
			地址或者IP地址,如果host使用*代表所有的用户(客户端)都可以访问。
		创建用户:
			可以两种方式创建用户:
				1.直接使用root用户在mysql.user表中插入记录
				2.专门创建用户的SQL指令
					基本语法:
						create user 用户名 identified by '明文密码';
						用户:用户名@主机地址
						主机地址:''/'%'
		删除用户:
			基本语法:
				drop user 用户名@主机地址

		修改用户密码:
			两种方式:
				1.使用专门的修改密码的指令
					set password for 用户 = password('明文密码');
				2.使用更新语句update来修改表
					update mysql.user set password = password('新的明文密码') where user = '' and host = '';
	2.权限管理
		在mysql中将权限管理分为三类:
			1.数据权限:增删改查
			2.结构权限:结构操作
			3.管理权限:权限管理
		授予权限:grant
			将权限分配给指定的用户
			基本语法:grant 权限列表 on 数据库/*.表名/* to 用户;
			权限列表:使用逗号分隔,但是可以使用 all privileges代表所有权限
			数据库.表名:可以是单表(数据库名字.表名字),可以是具体某个数据库(数据库.*),也可以整库*(*.*)
				
		取消权限:revoke
			权限回收
			基本语法:
				revoke 权限列表/all privileges on 数据库/*.表名/* from 用户; 
			权限回收同样不需要刷新,用户马上就没有权限。
		刷新权限:flush
			将当前对用户的权限操作进行刷新,将操作的具体内容同步到对应的表中
			基本语法:
				flush privileges;
	3.密码丢失找回
		如果忘记了Root密码
			就需要找回或者重置root用户密码
			1.停止服务
			2.重新启动服务:mysqld.exe --skip-grant-tables//启动服务器但是跳过权限
			3.当前启动的服务器没有权限概念:非常危险,任何客户端,不需要任何用户信息都可以直接登录,而且是root权限
			,新开客户端,直接使用mysql.exe登录即可。
			4.登录服务器后修改root密码
			5.直接关闭mysqld进程,重新启动服务

23.外键

	1.外键的概念
		如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间
		的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表,外键又称作外关键字。
	
		外键:foreign key
			一张表(A)中有一个字段,保存的值指向另外一张表(B)的主键
				B 主表
				A 从表
	2.外键的操作
		1.增加外键
			1.在创建表的时候增加外键(类似主键)
				基本语法:在字段之后增加一条语句
					[constaraint `外键名`] foreign key (外键字段) references 主表(主键);    
			2.在创建表后增加外键
				基本语法
					alter table 从表 add [constaraint `外键名`] foreign key (外键字段) references 主表(主键);
			MUL:多索引,外键本身是一个索引,外键要求外键字段本身也是一种普通索引
		2.修改&删除外键
			外键不允许修改,只能先删除后增加
				删除基本语法:alter table 从表 drop foreign key 外键名字; .
				外键创建会自己增加一个索引,但是外键删除的时候不会删除这个产生的普通索引
				如果想要删除对应的索引:alter table 表名 drop index 索引名字
		3.外键基本要求
			1.外键字段需要保证与关联的主表字段类型完全一致	
			2.基本属性也要相同
			3.如果在表后增加外键,对数据还有一定的要求(从表数据与主表的关联关系)
			4.外键只能使用innodb存储引擎,myisam不支持
		4.外键约束
			外键约束:通过建立外键关系之后,对主表和从表都会有一定的数据约束效力
			1.约束的基本概念
				1.当一个外键产生时,外键所在的表(从表)会受制于主表数据的存在从而导致数据不能进行某些不符合规范的操作
				(不能插入主表不存在的数据)
				2.如果一张表被其他表外键引入,那么该表的数据操作就不能随意,也必须保证从表数据的有效性。
				(不能删除一个被从表引入的记录)
			2.外键约束的概念
				1.可以在创建外键的时候,对外键约束进行选择性的操作
				基本语法:
					add foreign key(外键字段) references 主表(主键) on 约束模式;
				约束模式有三种:
					1.district:严格模式,默认的,不允许操作
					2.cascade:级联模式,一起操作,主表变化,从表数据跟着变化
					3.set null:置空模式,主表删除,从表对应的记录设置为空,前提是从表中对应的外键字段允许为空
				外键约束主要约束的对象是主表操作:从表就是不能插入主表不存在的数据

				通常在进行约束的时候,需要指定操作:update和delete
				常用的约束模式:on update cascade on delete set null;  级联更新,删除置空

			3.约束作用
				保证数据的完整性,主表与从表的数据要一致
				正是因为外键有非常强大的数据约束作用,而且可能导致数据在后台变化变得不可控。导致程序在进行设计开发逻辑
				的时候,没有办法去很好的把握数据(业务),所以外键比较少用

24.视图的基本操作

	1.创建视图
		视图的本质是SQL指令(select语句)
		基本语法: create view 视图名字 as select 指令;可以是单表数据,也可以是链接查询
		查看视图结构,

	2.使用视图
		视图是一张虚拟表:可以直接把视图当做“表”操作,但是视图本身没有数据,是临时执行select语句得到对应的结果。
		视图主要用于查询操作
		基本语法:
			select 字段列表 from 视图名字 where 条件;
	3.修改视图
		alter view 视图名字 as select 指令;可以是单表数据,也可以是链接查询

	4.删除视图
		基本语法
			drop view 视图名;

25.事务安全

	1.事务的概念
		事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言
		或者编程语言书写的用户程序的执行所引起。事务由事务开始(begin Transaction)和事务结束(end Transaction)之间
		执行的全体操作组成。
	2.事务的基本原理
		基本原理:
			mysql允许将事务统一进行管理(存储引擎innodb)将用户所做的操作,暂时保存起来,不直接放到数据表(更新),
			等到用于确认结果之后再进行操作。

			事务在mysql中一般是自动提交,但是也可以设置成手动提交。
		查看自动事务开启情况:show variables like 'autocommit%'
		1.自动事务
			autocommit,当客户端发送一条SQL指令给服务器的时候,服务器在执行之后不用等待用户反馈结果,会自动将
			结果同步到数据表
			系统做了额外的步骤来帮助用户操作,系统是通过变量来控制。
			
			关闭自动事务:set autocommit = off;
			提交事务:commit;
			回滚事务:rollback;
			
		2.手动事务
			手动事务:不管是开始过程还是结束都需要程序员手动的发送事务操作指令来实现。
			手动事务对应的命令:
				1.start transaction;开启事务,从这句语句开始,后面的所有语句都不会直接写入到数据表中(保存到事务日志中)
				2.事务处理:多个写指令构成
				3.事务提交:commit/rollback;到这个时候事务才算结束
			回滚点:savepoint,当有一系列事务操作时,而其中的步骤如果成功了,没有必要重新来过,可以在某个点(成功),
			设置一个记号(回滚点),然后如果后面有失败,那么可以回到这个记号位置。

			增加回滚点:savepoint 回滚点名字;
			回到回滚点:rollback to 回滚点名字;
			如果在一个事务处理中,如果有很多和步骤,那么可以设置多个回滚点,但是如果回到前面的回滚点,后面的回滚点就失效。

		3.事务特点
			原子性:一个事务是一个不可分割的单位,事务中包括的诸多操作,要么都成功,要么都失败
			一致性:事务必须是使数据库从一个一致状态到另一个一致状态,一致性与原子性是密切相关的
			隔离性:一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的
				并发执行的各个事务之间不能互相干扰。
			持久性:持久性也称为永久性,事务一旦提交,它对数据库的修改是永久性的,接下来的其他操作或者故障不应该对其有
				任何影响。
		4.事务的隔离级别
			事务隔离级别 			脏读 		不可重复读 	幻读
			读未提交(read-uncommitted) 	是 		是 		是
			不可重复读(read-committed) 	否 		是 		是
			可重复读(repeatable-read) 	否 		否 		是  (mysql默认)
			串行化(serializable) 		否 		否 		否
			
			设置事务隔离级别基本语法
				set session transaction isolation level 隔离级别;

26.变量

	mysql本质是一种编程语言,需要很多变量来保存数据,Mysql中很多的属性控制都是通过mysql中固定的变量来实现的。
	1.系统变量
		系统内部定义的变量,系统变量针对所有用户(Mysql客户端)有效。
		查看全部系统变量:show variables [like 'pattern'];
		mysql支持使用select查询变量的值
		查询系统变量:
			select @@变量名
		修改系统变量:
			分为两种
				1.局部修改(针对当前本次会话有效)
					基本语法:set 变量名=新值
				2.全局修改(针对当前所有新连接有效,已经连接的无效)
					基本语法:set global 变量名 = 新值;

	2.会话变量
		会话变量也称为用户变量,会话变量跟mysql客户端是绑定的,设置的变量只针对当前使用的客户端生效。
		定义用户变量:
			set @变量名 = 值;
			set @变量名 := 值;

			专用赋值符号    :=
	3.局部变量
		作用范围在begin到end语句块之间,在该语句块里设置变量,declare语言专门用于定义局部变量
		1.局部变量是使用declare关键字声明
		2.局部变量declare语句出现的位置一定在begin和end之间(begin end是在大型语句块中使用:函数、存储过程、触发器)
		3.声明语法:declare 变量名 数据类型 [属性];

27.流程结构

	流程结构:代码的执行顺序
	1.if分支
		基本语法:
			if在Mysql中有两种基本用法
			1.用在select查询当中,当做一种条件来进行判断
			基本语法:if(条件,为真结果,为假结果)
			2.用在复杂的语句块中(函数/存储过程/触发器)
			基本语法:
				if 条件表达式 then
					满足条件要执行的语句;
				end if;
		复合语法:
			代码的判断具有两面性,两面都有对应的代码执行。
			if 条件表达式 then
				满足条件要执行的语句;
			else 
				不满足要执行的语句;
			end if;

	2.while循环
		基本语法:
			while 条件 do
				要循环的代码
			end while;
		
		结构标识符:
			结构标识符:为某些特定的结构进行命名,然后为的是在某些地方使用名字
			基本语法:
				标识名字:while 条件 do
					循环体;
				end while;

				标识符的存在主要是为了循环体中使用循环控制,在mysql中没有continue和break,有自己的关键字代替:
				iterate:迭代,就是一下代码不执行,重新开始循环,相当于continue
				leave:离开,终止循环体循环,相当于break
				语法: iterate/leave 标志名字;
				
	3.函数
		在mysql中,函数分为两类:系统函数和自定义函数,不管是内置函数还是用户自定义函数,都是使用select 函数名(参数列表);进行访问
		1.内置(系统)函数:
			字符串函数
				1.char_length()  判断字符串的字符数
				2.length()  判断字符串的字节数
				3.instr()   判断字符在字符串中是否存在,存在返回其位置,不存在则返回0
				4.lcase()    全部小写
				5.left()    从左侧开始截取到指定位置,如果超过长度就截取所有
				6.ltrim()    消除左边对应的空格
				7.mid()     从中间指定位置开始截取,如果不指定截取长度,直接到最后
			时间函数
				1.now()  返回当前时间,日期 时间
				2.curdate()  返回当前日期
				3.curtime()   返回当前时间
				4.datediff()   判断当前两个日期之间的天数差距
				5.date_add(日期,interval 时间数字 type)	进行时间增加
					type:day   hour   minute   second
			数学函数
				1.abs()    绝对值
				2.ceiling()    向上取整
				3.floor()    向下取整
				4.pow()	    求指数,谁的多少次方
				5.rand()     获取一个随机数(0-1之间)
				6.round()     四舍五入
			其他函数
				1.md5()	 md5加密
				2.version() 获取版本号
				3.databse() 显示当前所在数据库
				4.uuid() 生成一个唯一的标识符
			
		2.用户自定义函数:
			用户自己定义的函数,实现某种功能的语句块(由多条语句组成)
				函数内部的每条指令都是一个独立的个体,需要符合语句定义规范,需要语句结束符
				函数是一个整体,而且函数是在调用的时候才会被执行,那么当设计函数的时候,意味着整体不能被中断
				mysql一旦见到语句结束符分号,就会自动开始向下执行
				解决方案:
					在定义函数之前,尝试修改临时的语句结束符
					基本语法: delimiter 新符号[可以使用系统非内置的符号,如两个$   $$]
					中间为正常的SQL指令:使用分号结束(系统不会执行,不认识分号)
					使用新符号结束
					修改回语句结束符:delimiter ;
			1.创建函数
				自定义函数包含几个要素:function关键字,函数名,参数(形参和实参[可选]),确认函数返回值类型,
				函数体,返回值
				基本语法:
					delimiter $$
					create function(形参(int_1 int)) returns 返回值类型
					begin
						函数体;
						return 返回值数据;
					end
					语句结束符$$
					delimiter ;

				并不是所有的函数都需要begin和end,如果函数只有一条语句,那么只就可以省略begin和end
	
			2.查看函数
				查看所有函数:show function status [like 'xxxx']
				查看函数创建语句:show create function 函数名

			3.调用函数
				select 函数名1(),函数名2()...;

			4. 删除函数
				drop function 函数名;
			注意事项:
				自定义函数只属于用户级别,只有当前客户端对应的数据库中可以使用
				可以在不同的数据库下看到对应的函数,但是不可以调用
				函数的本质是代码的包裹,解决复用问题
				函数因为必须规定返回值,那么在函数内部不能使用select指令,select一旦执行就会得到一个结果,就会输出
				,输出就相当于返回,但是select 字段 into @变量  是唯一可用的。

28.变量的作用域

	变量作用域:变量能够使用的区域范围
	1.局部作用域
		使用declare关键字声明(在结构体内:函数/存储过程/触发器),而且只能在结构体内部使用
		1.declare关键字声明的变量没有任何符号修饰,就是皮套字符串,如果在外部访问该变量,系统会自动认为是字段

	2.会话作用域
		用户定义的,使用@符号定义的变量,使用set关键字
		会话作用域:在当前用户当次链接有效,只要在本链接之中,任何地方都可以使用(可以在结构体内部,也可以跨库)

		会话变量可以在函数内部使用,也可以垮库。
	3.全局作用域
		所有的客户端所有的链接都有效:需要使用全局符号来定义
		set global 变量名 = 值;
		set @@global.变量名 = 值;
		通常,在SQL编程的时候,不会使用自定义变量来控制全局。一般都是定义会话变量或者在结构中使用局部变量来解决问题。

29.存储过程

	1.存储过程的概念:
		存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,存储过程在数据库中,经过
		一次编译后再次调用不需要再次编译(效率比较高),用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)
		来执行它。存储过程是数据库中的一个重要对象(针对SQL编程)。
		存储过程简称:过程
	2.与函数的区别:
		相同点:存储过程和函数目的都是为了可重复地操作数据库sql语句集合。
			存过程函数都是一次编译,后续执行
		不同点:
			1.标识符不同。函数的标识符为function,过程为procedure
			2.函数中有返回值,且必须返回,而存储过程没有返回值。
			3.过程无返回值类型,不能将结果直接赋值给变量,函数有返回值,调用时除在select中,必须将返回赋值给变量。
			4.函数可以在select语句中直接使用,而存储过程不能。函数是在select中使用,而过程不是。
	3.存储过程的操作
		1.创建存储过程
			基本语法:
				create procedure 过程名称([参数列表])
				begin
					过程体
				end
				结束符

				如果过程体中只有一条指令,那么可以省略begin和end
				过程基本上可以完成函数对应的所有功能。
		2.查看存储过程
			查看存储过程和查看函数完全一样,除了关键字
			查看所有存储过程:show procedure status\G
			查看存储过程的创建语句:show create procedure my_procedure\G
		3.调用存储过程
			过程没有返回值,所有select不可能调用
			调用过程有专门的语法:call 过程名
			call my_procedure();
		4.删除存储过程
			基本语法:
				drop procedure my_procedure;

		5.存储过程的参数
			存储过程也允许提供参数(形参和实参):存储过程的参数也和函数一样,需要制定其类型。但是存储过程对参数
			还有额外的要求,自己的参数分类。
			in:
				表示参数从外部传入到存储过程中使用。可以是直接数据,也可以是存数据的变量

			out:
				表示参数是从存储过程里面把数据保存到变量中,交给外部使用,传入的必须是变量
				如果说传入的out变量本身在外部也有数据,但是一进入存储过程就会被干掉,设置为NULL

			inout:
				数据可以从外部传入到存储过程内部使用,同时内部操作之后,又会将参数返还给外部
			基本语法:
				i in int,j out int, p inout int

30.触发器

	1.基本概念
		触发器是一种特殊的存储过程,它不同于存储过程,触发器主要是通过事件进行触发而执行的,而存储过程可以通过名字直接
		被调用。
		触发器:trigger,是一种非常接近js中事件的东西,提前给某张表的所有记录(行)绑定一段代码,如果改行的操作满足
		触发条件,这段提前准备好的代码就会自动执行
	2.作用
		1.可在写入数据表前,强制检验或转换数据。
		2.触发器发生错误时,异动的结果会被撤销,事务安全
		3.部分数据库管理系统可以针对数据定义语言DDL使用触发器,称为DDL触发器
		4.可依照特定的情况,替换异动的指令(INSTEAD OF)(mysql不支持)
	3.优点
		1.触发器可通过数据库中的相关表实现级联更改(如果某张表的数据改变,可以利用触发器来实现其他表的无痕操作(对用户透明))
		2.安全校验,保证数据安全
	4.缺点
		1.对触发器过分的依赖,势必影响数据库的结构,同时增加了维护的复杂程度
		2.造成数据的程序层面不可控制
	5.触发器的基本操作
		1.创建触发器
			基本语法:
				create trigger 触发器名字 触发时机 触发事件 on 表 for each row
				begin
				操作
				end
			触发对象:on 表 for each row ,触发器绑定实质是表中的所有行,因此当每一行发生指定的改变的时候,就会触发触发器
		2.触发时机
			触发时机,每张表中的不同的行都会有不同的状态,当sql指令发生的时候,都会令行中数据发生改变,每一行总会有两种状态
			数据操作前的状态和数据操作后的状态
			Before   在表中数据发生改变之后的状态

		3.触发事件
			mysql中触发器针对的目标是数据发生变化,对应的操作只有写操作(增删改)

		注意事项:
			每一张表中,每一个触发时机绑定的触发事件对应的触发器类型只能有一个,所以一张表中最多只能有6个触发器
	
		delimiter $$
		create trigger after_inser_order_t after insert on my_orders for each row
		begin
			update my_goods set inv = inv - 1 where id = 1;
		end
		delimiter ;
	
	6.查看触发器
		查看全部触发器:
			show trigger\G
		查看指定触发器的创建语句
			show create trigger 触发器名字;
	7.删除触发器
		drop trigger 触发器名字;
	8.触发器的应用
		记录关键字new 和 old
		触发器针对的是数据库表中的每条记录(每行),每行在数据操作之前和操作之后都有一个对应的状态,触发器在执行之前
		就将对应的状态获取到了,将没有操作之前的状态(数据)都保存到old关键字中,而操作之后的状态都保存在new中
		在触发器中,可以通过old和new来获取绑定表中对应的记录数据。
		基本语法:
			关键字.字段名
		并不是所有触发器都有old和new关键字,删除没有new关键字,插入没有old关键字
	delimiter $$
			create trigger after_inser_order_t after insert on my_orders for each row
			begin
				update my_goods set inv = inv - new.goods_number where id = new.goods_id;
			end
			delimiter ;

		  	delimiter $$
			create trigger before_inser_order_t before insert on my_orders for each row
			begin
				select inv form my_goods where id = new.goods_id into @inv;   --查询库存
				if @inv < new.goods_num then		   --如果库存少于订单
					insert into xxx values('xxx');	--暴力退出
				end if
			end
			delimiter ;

你可能感兴趣的:(SQL,MySQL)