MySQL基础复习

在复习MySQL时的一些笔记,记录的细节多一点,基础少一点。

MySQL基础

语法规范

  1. 不区分大小写,建议关键字大写,表名、列名小写
  2. 建议分号结尾
  3. 根据需要进行缩进、换行
  4. 注释
    单行注释:#注释文字 – 注释文字 //注意–后面有空格
    多行注释:/* 注释文字 */

常用基础命令

    show databases;
    
    use databaseName;
    
    show tables;
    
    show tables from databaseName; # 不改变数据库
    
    select database(); # 当前所在数据库
    
    create table tableName(
    	id int,
    	name varchar(20));
    
    desc tableName; # 显示表的结构
    select version(); # 登录到mysql服务端,查看服务器版本
    #mysql --version; || mysql -V  没有登录

一、DQL数据查询

    #DQL 数据查询
    select * from tableName;
    	#为字段起别名  as xxxxx    as可以省略
    	#去重  
    		select distinct fieldName from tableName;
    	#连接成一个字段 
    		select concat(fieldName1,fieldName2[,...]) from tableName;
    		# mysql中‘+’号的作用:运算符 如果一方为null 结果为null
    	#判断是否为null 
    		select ifnull(expr, return); #如果expr为null返回return
    	#模糊查询like   占位符 %(任意数量占位符) _(一个占位符)
    	#escape '$' 指定$为转移字符
    	#安全等于 <=>
    	#order by fieldName (desc | asc) 除了limit外一般都放在order by前面
    	#length(fieldName) 计算长度

1.1 常见函数

#分类:
#单行函数:如concat、length、ifnull
	#字符函数
    	length(str)#获取参数值的字节个数,汉字为3(UTF-8)
    	concat(str...)#拼接字符串
    	upper(str)、lower(str)#转换为大小写
    	substr(str, pos[, len])、substring()#注意SQL的索引是从1开始!!!
    	instr(str, substr)#返回substr在str中的第一个起始索引,找不到返回0
    	trim(str)#取出前后的空格 trim('a' from 'aaaaaaaaaa123aaaaaa')去掉a
    	lpad(str, len, padstr)、rpad()#用padstr实现左填充指定长度 最终长度为len 长度超过len会从右边截断
    	replace(str, from_str, to_str)#将str中的from_str变为to_str
	#数学函数
    	round(x[, D])#四舍五入, 为保留的位数
    	ceil(x)、floor(x)#向上取整、向下取整
    	truncate(x, D)#将x小数点后保留D位
    	mod(x,y)#返回x%y
	#日期函数
		now()#返回当前系统日期+时间
		curdate()#返回当前系统日期
		curtime()#返回xxxxxxx时间
		year(date)month(date)、monthname(date)#返回date的年、月、日、时、分、秒,date可以是字符类型
		str_to_date(str, format)#将str按format格式解析为日期类型
		date_format(date, format)#将日期转成字符类型
		datediff(date1, date2)#返回date1-date2的天数
	#其他函数
		version()#版本号
		database()#查看当前数据库
		user()#查看当前用户
	#流程控制函数
		if(expr1,expr2,expr3)#实现if else的效果,如果条件expr1成立,返回true执行expr2,返回false执行expr3
		case()#实现switch case的效果
			select salary 原始工资, department_id,
			case department_id
			when 30 then salary*1.1
			when 40 then salary*1.2
			when 50 then salary*1.3
			else salary
			end as 新工资
			from employees;
			#实现if else if else的效果
			case
			when 条件1 then 语句1
			when 条件2 then 语句2
			when 条件3 then 语句3
			else 语句n
			end
#分组函数:
	#功能:做统计使用,又称为统计函数、聚合函数、组函数
	sum([distinct] x)avg()max()min()count()#求和、平均值、最大值、最小值、计算非空个数,这些函数都忽略null值
	#★★★★★★MYISAM存储引擎(内部有一个计数器)下,count(*)的效率最高
	#★★★★★★INNODB存储引擎下,count(*)和count(1)的效率差不多,比count(fieldName)高,因为后者有一个筛选过程。
	#和分组函数一同查询的字段有限制,如select avg(salary), employee_id from employees;
	#group by xxx,xxx   
		#如查询每个部门的平均工资,
			select avg(salary) from employees group by department_id;
	#添加分组前筛选条件 where(where筛选条件的字段都来自于原始表)
	#添加分组后筛选条件 having 
		#如查询哪个部门的员工个数大于2 
			select department_id from employees group by department_id having count(*)>2; 
		#查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资 
			select job_id, max(salary) where commission_pct is not null group by job_id having max(salary)>12000;
		#				数据源
		#分组前筛选		 原始表
		#分组后筛选	  分组后的结果集
		#★★★★★★★★分组函数做条件肯定是放在having子句中
		#★★★★★★★★能用分组前筛选的,就优先考虑使用分组前筛选

1.2 连接查询(多表查询)

   #分类:
   	#按年代分类:
   			  #sql92标准 mysql仅仅支持内连接
   ★★★★★★#sql99标准【推荐】:mysql支持内连接+外链接(左外和右外)+交叉连接
   	#按功能分类:
   		#内连接:
   			#等值连接:多表等值连接的结果为多表的交集部分,n表连接至少需要n-1个连接条件
   			#非等值连接
   			#自连接
   		#外连接:用于查询一个表有,另一个表没有的数据
   			#外链接的查询结果为主表中的所有记录
   				#如果从表中有匹配的,则显示匹配的值
   				#如果从表中没有和它匹配的,则显示null
   				#外链接查询结果=内连接结果+主表中有而从表中没有的记录
   			#左外连接,left左边的是主表
   			#右外连接,right右边的是主表
   			#全外连接:结果=内连接结果+表1有表2没有+表2有表1没有 mysql不支持
   		#交叉连接:笛卡尔积
   #sql92语法
   	select a.*,b.* from a,b where a.id = b.a_id; ...
   #sql99语法
   	select 查询列表 from1 别名 [连接类型]
   	join2 别名
   	on 连接条件
   	[where 筛选条件]
   	[group by 分组]
   	[having 筛选条件]
   	[order by 排序列表]
   #连接类型
   内连接:inner
   外连接:left [outer]   right [outer]  full [outer]
   交叉连接:cross

1.3 子查询

   #出现在其他语句中的select语句
   #分类:
   #按子查询出现的位置
   	#select后面:仅仅支持标量子查询
   		#查询每个部门的员工个数
		select d.*, (
            select count(*)
            from employees e 
            where e.department_id = d.department_id
        ) 
        from departments d;
   	#from后面:支持表子查询
   		#查询每个部门的平均工资的工资等级
   		select ag_dep.*, g.grade_level
   		from (
             select avg(salary) ag,department_id
             from employees 
             group by department_id
        ) ag_dep
        inner join job_grades g
        on ag_dep.ag between lowest_sal and highest_sal;
   ★★★#where或having后面:★★★标量子查询,★★★列子查询,行子查询
   		#标量子查询:如谁的工资比Abel高? 
		select name 
		from employees 
		where salary > (
            select salary 
            from employees 
            where name = 'Abel'
        );
   		#列子查询:返回location_id是1400或1700的部门中的所有员工的姓名 
   		select name 
   		from employees 
   		where department_id in (
               select distinct department_id 
               from departments 
               where location_id in (1400, 1700)
           );
   		#行子查询:查询员工编号最小并且工资最高的员工信息 
   		select * 
   		from employees 
   		where employee_id = (
            select MIN(employee_id) 
            from employees
        ) and salary = (
            select MAX(salary) 
            from employees
        );
   	#exists后面(相关子查询):表子查询,返回1或0
       	select bo.*
       	from boys bo
       	where not exists(
        	select boyfriend_id
            from beauty b
            where bo.id = b.boyfriend_id
        );
   #按结果集的行列数不同:
   	#标量子查询(结果集只有一行一列):一般搭配单行操作符使用 > < >= <= = <>
   	#列子查询(结果集只有一列多行) in any/some all
   	#行子查询(结果集有多行多列)
   	#表子查询(结果集一般为多行多列)

1.4 分页查询

    select 查询列表
    from[join type join2
    on 连接条件
    where 筛选条件
    group by 分组字段
    having 分组后的筛选
    order by 排序字段]
    limit offset, size;
    #offset要显示条目的起始索引(从0开始)
    #size要显示的条目个数

1.5 联合查询union

    #union 合并:将多条查询的结果合并成一个结果
    	#要求多条查询的列数是一致的
    	#要求多条查询的每一列的类型和顺序最好一致
    	#union关键字默认去重,如果使用union all 可以包含重复项
    	#查询部门编号>90或邮箱包含a的员工
    	select * from employees where department_id>90
    	union
    	select * from employees where email like '%a%';

二、DML数据操作

    #插入:insert
    #修改:update
    #删除:delete

2.1 插入语句

    insert into 表名(列名,...) values(1,...);
    	#支持多行插入和子查询
    insert into 表名 set 列名=, 列名=, ...;
    	#不支持多行插入,不支持子查询

2.2 修改语句

    #修改单表
    	update 表名 set 列名=,.... where 筛选条件
    #修改多表
    	#sql92语法
    		update1 别名,2 别名
    		set=,...
    		where 连接条件 and 筛选条件;
    	#sql99语法
    		update1 别名
    		连接类型 join2 别名
    		on 连接条件
    		set=,...
    		where 筛选条件;

2.3 删除语句

    #删除单表
    	delete from 表名 where 筛选条件
    #删除多表
    	#sql92语法
    		delete1的别名,2的别名
    		from1 别名,2 别名
    		where 连接条件 and 筛选条件;
    	#sql99语法
    		delete1的别名,2的别名
    		from1 别名
    		连接类型 join2 别名
    		on 连接条件
    		where 筛选条件;
    #清空表
    	truncate table 表名; #不能使用where
    #加入删除的表中有自增长列,如果用delete删除后,在插入数据,自增长列的值从断点开始,
    #truncate删除后,再插入数据,自增长列的值从1开始
    #truncate删除没有返回值,delete删除后有返回值
    #truncate删除不能回滚,delete删除可以回滚

三、DDL数据定义

3.1 库的管理

    #库的创建
    	create database [if not exists] 库名;
    #库的修改
    	rename database 旧库名 to 新库名;#版本升级后,废弃了,因为不安全,数据有可能丢失
    #更改库的字符集
    	alter database 库名 character set 编码方式;
    #库的删除
    	drop database [if exists] 库名;

3.2 表的管理

    #表的创建
    	create table [if not exists] 表名(
        	列名 列的类型[(长度) 约束],
            ....
            列名 列的类型[(长度) 约束]
        );
    #表的修改
    	#alter table 表名 add|drop|modify|change|rename column 列名 列类型 约束;
    	#列名
    		alter table 表名 change column 旧列名 新列名 新列类型;
    	#列的类型或约束
    		alter table 表名 modify column 旧列名 新列类型;
    	#添加列
    		alter table 表名 add column 新列名 新类型;
    	#删除列
    		alter table 表名 drop column [if exists] 列名;
    	#表名
    		alter table 表名 rename to 新表名;
    #表的删除
    	drop table [if exists] 表名;
    #表的复制
    	#仅仅复制的是表的结构
    		create table 新表 like 需要复制的表;
    	#复制表的结构+数据(可以只复制部分列或数据)
    		create table 新表
    		select * from 需要复制的表;
    	#仅仅复制某些字段
    		create table 新表
    		select 字段1,字段2...
    		from 需要复制的表
    		where 0; 

3.3 常见的数据类型

    #数值型:
    	#整型
    		#tinyint 占1字节 有符号-128~127 无符号0~255
    		#smallint 占2字节 有符号-32768~32767 无符号0~65535
    		#mediumint 占3字节 有符号。。。。
    		#int、integer 占4字节 
    		#Bigint 占8字节
    		#设置无符号 数据类型为 int unsigned
    		#超出范围会报out of range异常,并插入临界值
    		#如果不设置长度会有默认的长度,设置长度的时候 数据类型为 int(7) zerofill,如果不加zerofill长度无效,如果插入数据长度小于设置的长度,进行0填充。并且此时字段成为无符号。
    	#实数:
    		#定点数:
    			#dec(M,D)、decimal(M,D) 占M+2个字节,最大取值范围和double相同,保存精度更高。默认M=10,D=0
    		#浮点数:
    			#float(M,D) 占4个字节
    			#double(M,D) 占8个字节
    		#M:整数部位长度+小数部位   D:小数部位长度
    		#如果超过范围,插入临界值
    #字符型:
    	#较短的文本:char(M)、varchar(M) M是最多字符数,char默认为1可以省略,varchar不可省略。
    		#char    固定长度的字符 比较耗费空间 效率高 
    		#varchar 可变长度的字符 比较节省空间 效率低
    		#enum('a','b','c') 只可以选择一个插入
    		#set 可以选择多个插入 insert into 表名 values('a,b');
    		#binary varbinary 用于保存较短的二进制
    	#较长的文本:text、blob(较长的二进制数据
    #日期型:
    	#date 占4字节 最小值1000-01-01 最大值9999-12-31
    	#datetime 占8字节 最小值1000-01-01 00:00:00 最大值9999-12-31 23:59:59
    	#timestamp 占4字节 最小值19700101080001 最大值2038年的某个时刻
    		#受时区的影响
    	#time 占3字节 最小值-838:59:59 最大值838:59:59
    	#year 占1字节 最小值1901 最大值2155
    	#set time_zone='+09:00'修改时区

3.4 常见约束

    #为了保证数据的准确和可靠性
    #分类:六大约束
    	#not null:非空
    	#default:默认值
    	#primary key:主键
    	#unique:唯一
    	#check:检查约束[mysql中不支持]
    	#foreign key:外键
    create table 表名(
    	字段名 字段类型 列级约束,
    	字段名 字段类型,
        表级约束
    );
    #外键约束不能作为列级约束
    #非空和默认约束不能作为表级约束
    
    #添加删除约束
    	#创建表时
    		#表级约束
    			#[constraint 约束名] 约束类型(字段名)
    			constraint 主键名 primary key(主键字段[, 主键字段]);
    			constraint 唯一键名 unique(唯一字段);
    			constraint 检查约束 check(检查字段 = '字段值'[or ...]);
    			constraint 外键名 foreign key(外键字段) references 主表名(主表主键);
    		#通用写法
    	drop table if exists stuinfo;
    	create table stuinfo(
    		id int primary key,
    		stuname varchar(20) not null,
    		sex char(1),
    		age int default 18,
    		seat int unique,
    		majorid int,
    		constraint fk_stuinfo_major foreign key(majorid) references major(id)
    	);
    	#修改表时
    		#列级约束 
    		alter table 表名 modify column 字段名 字段类型 约束;
    		#表级约束 
    		alter table 表名 add [constraint 约束名] 约束类型(字段名); 
    		#删除约束 
    		alter table 表名 modify column 字段名 字段类型; alter table 表名 drop (primary key | index 索引名 | foreign key 外键名); 
    #外键
    	#要求在从表设置外键关系
    	#从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求
    	#主表中的关联列必须是一个键(主键、唯一)
    	#插入数据,先插入主表,再插入从表
    	#删除数据,先删除从表,在删除主表
    #标识列 auto_increment
    	#设置步长为3
    	set auto_increment_increment=3; 
    	#标识列只能是数值型
    	#一个表最多有一个
    	#要求和key共同作用一个字段 	

四、TCL事务控制

	Transaction Control Language
	事务:一个或一组sql语句组成一个执行单元,要么全部执行,要么全部不执行。

事务的ACID特性:

  1. 原子性(Atomicity)
    指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  2. 一致性(Consistency)
    事务必须是数据库从一个一致性状态变换到另一个一致性状态。
  3. 隔离性(Isolation)
    一个事务的执行不能被其他事务干扰,一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性(Durability)
    指一个事务一旦被提交,它对数据库中数据的改变是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

事务的创建:

  1. 隐式事务
    事务没有明显的开启和结束的标记。比如insert、update、delete语句。
    show variables like ‘autocommit’;
  2. 显式事务
    事务具有明显的开启和结束的标记。前提:必须先设置自动提交功能为禁用。(set autocommit=0;)

步骤:

    set autocommit=0;
    start trasaction;#可选
    #编写sql语句
    commit;#提交事务
    rollback;#回滚事务
    
    savepoint name;#节点名,设置保存点
    rollback to a;#回滚到savepoint a

4.1 隔离级别

对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题。

脏读
对于两个事务T1、T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的。(在一个事务内,读取到假数据)

不可重复读
对于两个事务T1、T2,T1读取了一个字段,然后T2更新了该字段之后,T1再次读取同一字段,值就不同了。(在一个事务内,读取到的数据不一致)

幻读
对于两个事务T1、T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行之后,如果T1再次读取同一个表,就会多出几行。(一个事务内,结果集不同)

Oracle支持两种事务隔离级别:read committed(默认),serializable。
MySQL支持四中:read uncommitted、read committed、repeatable read(默认)、serializable

    select @@tx_isolation;#查看当前隔离级别
    set session transaction isolation level read uncommitted;#将隔离级别设置为read uncommitted
    set global transaction isolation level read committed;#设置数据库系统的全局隔离级别

4.2 delete和truncate在事务使用时的区别

delete支持回滚,truncate不支持回滚。

五、视图

虚拟表,和普通表一样使用
mysql5.1版本出现的新特性,是通过表动态生成的数据。

应用场景:

多个地方用到同样的查询结果。
该查询结果使用的sql语句较复杂。

扫描二维码关注公众号,回复: 5725763 查看本文章
    #视图创建
        create view 视图名
        as
    	查询语句;
    #视图修改
        create or replace view 视图名
        as
        查询语句;
    	alter view 视图名
    	as
    	查询语句;
    #视图删除
    	drop view 视图名, 视图名,...;
    #视图查看
    	desc 视图名;
    	show create view 视图名;
    #视图更新
    	insert into 视图名 values(1,2....);
    	update 视图名 set 字段1=1,... where 筛选条件;
    	delete from 视图名 where 筛选条件;
    	#不允许更新的视图
    		#包含以下关键字的sql语句:分组函数、distinct、group by、having、union或者union all
    		#常量视图
    		#select中包含子查询
    		#连接
    		#from一个不能更新的视图
    		#where子句的子查询引用了from子句中的表
    #视图占用了一点点物理空间,保存sql的逻辑

六、变量

    #系统变量:变量由系统提供,属于服务器层面,包含全局变量和会话变量
    	#查看所有的系统变量:
    		show [global|session] variables;
    	#查看满足条件的:
    		show [global|session] variables like '%%';
    	#查看指定的某个系统变量:
    		select @@[global|session].系统变量名;不写默认为会话
    	#为某个系统变量赋值:
    		set [global|session] 系统变量名=; 
    		set @@[global|session].系统变量名=;
    	#全局变量
    		#作用域:服务器每次启动将为所有的全局变量赋初始值,针对所有的会话(连接)有效,但不能跨重启。
    	#会话变量
    		#作用域:仅仅针对于当前会话(连接)有效。
    #自定义变量:用户自己定义
    	#使用步骤:声明,赋值,使用。
    	#用户变量:
    		#作用域:针对于当前会话(连接)有效。
    		#声明并初始化 
                set @用户变量名=; 
                set @用户变量名:=; 
                select @用户变量名:=;
    		#赋值(更新用户变量值)
                #同声明初始化 
                #或者 
                select 字段 into 变量名 from 表名;
    		#应用在任何地方,也就是begin end里面或外面
    	#局部变量:
    		#作用域:仅仅在定义它的begin end中有效
    		#声明:
    			declare 变量名 类型;
    			declare 变量名 类型 default;
    		#赋值:
    			set 局部变量名=; 
    			set 局部变量名:=; 
    			select @局部变量名:=;
    			select 字段 into 变量名 from 表名;
    		#使用
    			select 局部变量名;
    		#应用在begin end中的第一句话★★★★★★

七、存储过程和函数

7.1 存储过程

一组预先编译好的SQL语句的集合,理解成批处理语句。
减少了编译次数并且减少了和数据库服务器的链接次数,提高了效率。

    #创建
    	delimiter $
    	create procedure 存储过程名(参数列表)
    	begin
    		#存储过程体;
    	end $
    	#★★★★注意:
    		#参数列表包含三部分:参数模式 参数名 参数类型 如 in stuname varchar(20)
    			#参数模式
    				#in:该参数可以作为输入,该参数需要调用方传入值
    				#out:该参数可以作为输出,该参数可以作为返回值
    				#inout:该参数既可以作为输入,又可以作为输出
    		#如果存储过程体只有一句话,begin end可以省略
    		#存储过程体的每条SQL语句的结尾要求必须加分号。而存储过程的结尾可以使用delimiter重新设置 语法:delimiter 结束标记
    #调用
    	call 存储过程名(实参列表);
    	#空参列表 call myp1()$
    	#带in模式参数的存储过程 call myp2('参数')$
    	#带out模式参数的存储过程 call myp3('参数', @用户变量名)$
    	#带inout模式参数的存储过程 先设置用户变量然后call myp4(@用户变量名)$
    #删除
    	drop procedure 存储过程名, 存储过程名2;
    #查看
    	show create procedure 存储过程名; 	

7.2函数

和存储过程的区别:
存储过程可以有0个返回,也可以有多个返回。
函数有且仅有1个返回。

    #创建
        create function 函数名(参数名 参数类型) returns 返回类型
        begin
            函数体
        end
    #调用
    	select 函数名(参数列表)
    #查看
    	show create function 函数名;
    #删除
    	drop function 函数名;

7.3流程控制结构

    #顺序结构
    #分支结构
    	if(expr1, expr2, expr3); 如果expr1成立,返回expr2,否则返回expr3
    	#if实现多重if
    		if 条件1 then 语句1;
    		elseif 条件2 then语句2;
    		...
    		else 语句n;
    		end if;
    	#switch
    		case 变量|表达式|字段
    		when 要判断的值 then 返回的值1
    		...
    		else 要返回的值n
    		end
    	#多重if
    		case
    		when 要判断的值 then 返回的值1
    		...
    		else 要返回的值n
    		end
    #循环结构
    	#while
    		[标签:] while 循环条件 do
    			循环体;
    		end while [标签];
    	#loop
    		[标签:] loop
    			循环体;
    		end loop [标签];
    	#repeat
    		[标签:] repeat
    			循环体;
    		until 结束循环的条件
    		end repeat [标签];
    	#iterate:类似continue
    	#leave:类似break 

八、存储引擎

概念:在mysql中的数据用各种不同的技术存储在文件(或内存)中。
show engines; 进行查看存储引擎
在mysql中用的最多的存储引擎:
innodb、myisam、memory
innodb支持事务,而其他两个不支持。

猜你喜欢

转载自blog.csdn.net/qq_39513105/article/details/88426269
今日推荐