基础篇
SQL通用语法
SQL语句可以单行或多行书写,使用回车可换行继续书写最后以分号结尾 。
SQL语句可以使用空格/缩进来增加语句的可读性。
MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
注释:
单行注释:-- 注释内容 或 # 注释内容(MySQL特有)
多行注释:/*注释内容*/
SQL分类
1 2 3 4 DDL: 数据定义语言,用来定义数据库对象(数据库,表,字段) DML: 数据操作语言,用来对数据库表中的数据进行增删改 DQL: 数据查询语言,用来查询数据库中表的记录 DCL: 数据控制语言,用来创建数据库的用户、控制数据库的访问权限
SQL数据类型
见这篇blog->MySQL字段类型最全解析_kun_行者的博客-CSDN博客
SQL运算符
SQL学习之运算符_sql运算符有哪些_heart-szu的博客-CSDN博客
SQL七大约束
约束条件用法参考这篇blog 【MySQL基础】MySQL表的七大约束_mysql 表级约束_小杨MiManchi的博客-CSDN博客
DDL(数据库操作和表操作)
数据库操作
查询
查看所有数据库:
查询当前数据库:
创建
1 2 3 4 5 6 7 8 CREATE DATABASE| SCHEMA [IF NOT EXISTS ] 数据库名 [DEFAULT (CHARSET)| (CHARACTER SET ) 字符集] [COLLATE 排序规则];/ / DEFAULT 这个单词在写代码的时候可以加也可以不加,最好加上例: CREATE DATABASE IF NOT ETISTS teachingDEFAULT CHARACTER SET utf8mb4DEFAULT COLLATE utf8mb4_0900_ai_ci;
删除
1 DROP DATABASE [IF EXISTS ] 数据库名;
使用
查看
1 2 SHOW CREATE DATABASE 数据库名/ / 结果会显示出创建命令和各参数设置(字符集,校对规则)
修改
1 2 ALTER DATABASE| SCHEMA [IF NOT EXISTS ] 数据库名 [DEFAULT (CHARSET)| (CHARACTER SET ) 字符集] [COLLATE 排序规则];/ / 注意:用户必须有数据库的修改权限才能使用该命令修改数据库
表操作
查询
查询当前数据库所有表
查询表结构
查询指定表的建表语句
1 2 SHOW CREATE TABLE 表名;/ / 会显示出详细注释,引擎,字符集,校对规则
创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE TABLE 表名( 字段1 字段1 类型 [约束条件] [COMMENT '字段1注释' ], 字段2 字段2 类型 [约束条件] [COMMENT '字段2注释' ], 字段3 字段3 类型 [约束条件] [COMMENT '字段3注释' ], ... 字段n 字段n类型 [COMMENT 字段n注释] )[COMMENT 表注释]; 例子: create table tb_user( id int comment '编号' , name varchar (50 ) comment '姓名' ) comment '用户表' ;
表名和字段只能用反引号或不用符号,不能用单引号
最后一个字段结尾不要有逗号
comment后的字段注释或表注释必须使用引号,而且是单引号 而不是反引号
修改
添加字段
1 2 3 ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT 注释] [约束];/ / alter : 修改/ / add : 添加
修改指定字段数据类型
1 2 ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);/ / modify: 修改
修改字段数据名和字段类型
1 2 ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];/ / change: 修改
删除字段
1 ALTER TABLE 表名 DROP 字段名;
修改表名
1 ALTER TABLE 表名 RENAME TO 新表名;
删除
删除表
1 2 DROP TABLE [IF EXISTS ] 表名;/ / 数据全部删除
删除指定表,并重新创建该表
1 2 TRUNCATE TABLE 表名;/ / 数据全部删除,结构不变
DML(数据操作)
添加
1 INSERT | REPLACE INTO 表名(字段名1 ,字段名2 ,字段名3 ,..) VALUES (值1 ,值2 ,值3 ,..);
1 INSERT | REPLACE INTO 表名 VALUES (值1 ,值2 ,...);
1 2 3 4 5 6 INSERT | REPLACE INTO 表名(字段名1 ,字段名2 ,字段名3 ,..) VALUES (值1 ,值2 ,值3 ,..),(值1 ,值2 ,值3 ,..),(值1 ,值2 ,值3 ,..);/ / 指定字段添加多份数据INSERT INTO 表名 VALUES (值1 ,值2 ,值3 ,..),(值1 ,值2 ,值3 ,..),(值1 ,值2 ,值3 ,..);/ / 所有字段添加多份数据
注意:
插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
字符串和日期型(date型)数据应该包含在引号中
插入的数据大小应该在字段的规定范围内
修改数据
修改
1 2 3 4 5 UPDATE 表名 SET 字段名1 = 值1 , 字段名2 = 值2 ,...[WHERE 条件];例: update test set name = 'kqd' where id= 1 ;/ / 将id为1 的字段name数据修改为kqd
注意:
修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。
删除
1 2 3 4 5 6 7 DELETE FROM 表名 [WHERE 条件]例: / / 删除gender为女的员工delete from employee where gender = '女' ;/ / 删除所有员工delete from employee;
注意:
DELETE语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。
DELETE语句不能删除某一个字段的值(但可以使用UPDATE)。
DQL(查询)
基础查询
1.查询多个字段
1 2 3 4 SELECT 字段1 ,字段2. .. FROM 表名;SELECT * FROM 表名 ; * 代表查询所有的字段
2.设置别名
1 2 3 4 5 6 7 8 9 10 11 SELECT 字段1 [AS 别名1 ],字段2 [AS 别名2 ]... FROM 表名;/ / AS 可省略select 字段1 as '别名' ,...为字段1 取别名 select a.namefrom student as a为student表取别名a
3.去除重复记录
1 SELECT DISTINCT 字段列表 FROM 表名;
条件查询
1 SELECT 字段列表 FROM 表名 WHERE 条件列表;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 条件: 运算符 1. 算数+ , - , * , / 2. 判断> , < , >= , <= , != , <> (不等于) IS NULL | IS NOT NULL (判断是否为NULL )3. 逻辑 AND (&& ), OR (|| ),NOT || ! 4. 范围 BETWEEN 最小值 AND 最大值,IN (值1 ,值2 ,...) / / IN 之后的列表的值为范围5. 模糊匹配 LIKE '_||%||' '_' 表示代表一个字符'%' 表示0 各或多个字符'[]' 表示某一范围的字符,例如[0 -9 ],0 ~ 9 之间的字符'[^]' 表示不再某一范围的字符
聚合函数
介绍:
将一列数据作为一个整体,进行纵向计算
1 2 3 4 5 6 聚合函数: count () 统计元组数量(行数)max () 最大值min () 最小值avg () 平均值sum () 求和
语法:
1 SELECT 聚合函数(字段列表),聚合函数,... FROM 表名;
所有的NULL值不参与所有聚合函数运算,对某个字段中有NULL在使用count时将不会计算数据条数。
count(*)统计的是表中所有的行数,count(字段)是统计该字段非NULL的行数,一般使用前者较多
分组查询
语法:
1 SELECT 字段列表 FROM 表名 [WHERE 条件] GEOUP BY 分组字段名 [HAVING 分组后过滤条件]
where和having的区别:
执行时机不同: where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果的过滤。
判断条件不同:where不能对聚合函数进行判断,而having可以。
注意:
执行顺序:where > 聚合函数 > having.
分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义
排序查询
语法:
1 2 3 4 5 SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1 ,字段二 排序方式排序方式: ASC : 升序(默认值)DESC : 降序
注意 :如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。
分页查询
语法:
1 2 3 SELECT 字段列表 FROM 表名 LIMIT 起始索引(偏移量),查询记录数
注意:
起始索引从0开始,起始索引 = (查询页码-1) * 每页显示记录数,起始索引也叫偏移量,表示从起始索引所在行数的下一行开始查询
分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT
如果查询的是第一页数据,起始索引可以省略,直接简写为LIMIT 10。
DQL执行顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 执行顺序:了解了执行顺序后我们就可以知道哪些部分可以使用别名来访问数据,哪些不能使用 1. FROM 2. WHERE 3. GROUP BY 4. HAVING 5. SELECT 6. ORDER BY 7. LIMIT例如: select name,age from emp where age> 15 order by age ASC ;若取别名 select e.name,e.age from emp as e age where e.age> 15 order by age ASC ; / / 执行成功,先执行from 为emp取别名e,再执行where ,select 若取别名select e.name AS ename, e.age AS eage from emp AS e age where eage> 15 order by age ASC ; / / 错误,select 语句在where 之后执行,在执行select 之前没有eage这个别名
DCL(管理)
用户管理
查询用户
1 2 USE mysql; SELECT * FROM user ;
创建用户
1 2 3 4 5 6 7 CREATE USER '用户名' @'主机名' IDENTIFIED BY '密码' / / 设置任意主机访问该数据库CREATE USER '用户名' @'#' identified by '密码' / / 设置只能在本机访问数据库CREATE USER '用户名' @'localhost' identified by '密码'
修改用户密码
1 ALTER USER '用户名' @'主机名' IDENTIFIED WITH mysql_native_password BY '新密码'
删除用户
注意:
主机名可以使用%通配
这类SQL开发人员操作的比较少,主要是DBA (数据库管理员)使用
权限控制
查询权限
1 SHOW GRANTS FOR '用户名' @'主机名'
授予权限
1 2 3 4 5 GRANT 权限列表 ON 数据库名.表名 TO '用户名' @'主机名' ALL / all 代表所有的权限数据库.* 代表所有的表 * .* 代表所有数据库的所有表
撤销权限
1 2 3 4 5 REVOKE 权限列表 ON 数据库名.表名 FROM '用户名' @'主机名' ALL / all 代表所有的权限* 代表所有的表* .* 代表所有数据库的所有表
注意:
多个权限之间,使用逗号分隔
授权时,数据库名和表名可以使用*进行通配,代表所有 ,
函数
MySQL 十大常用字符串函数_hzbooks的博客-CSDN博客
字符串函数
常用的函数:
CONCAT
1 2 CONCAT(s1,s2,..sn) 将字符串拼接,S1,S2,...Sn拼接成一个字符串,返回该字符串
LOWER
1 2 LOWER (str) 将字符串str全部转换为小写,返回该函数
UPPER
1 2 UPPER (str)将字符串str全部转换为大写,返回该函数
LPAD
1 2 3 4 5 LPAD(str,n,pad) 左填充,用字符串pad对str的左边进行填充,达到n个字符串长度 lpad('01' ,5 ,'-' ) 代表用'-' 填充左边的得到'---01' ,一共五个字符,下面的rpad同理
RPAD
1 2 RPAD(str,n,pad) 右填充,用字符串pad对str的右边进行填充,达到n个字符串长度
TRIM
1 2 TRIM (str)去掉字符串头部和尾部的空格(不除去中间)
SUBSTRING
1 2 SUBSTRING (str,start ,len)返回从字符串str从start 位置起的len个长度的字符串
数值函数
CEIL
FLOOR
MOD
RAND
ROUND
1 2 ROUND(x,y) 求参数x的四舍五入的值,保留y位小数
日期函数
CURDATE
CURTIME
NOW
YEAR
MONTH
DAY
DATE_ADD
1 2 3 4 5 6 7 8 DATE_ADD(date ,INTERVAL expr type) 返回一个日期/ 时间值加上一个时间间隔expr后的时间值 expr 指定数字 type 指定类型:年/ 月/ 日(DAY / MONTH / YEAR ) 例: DATE_ADD(now(),INTERVAL 70 day ) DATE_ADD(now(),INTERVAL 70 month )
DATEDIFF
1 2 3 4 5 DATEDIFF(date1,date2) 之间的天数
流程函数
IF
1 2 3 IF(value ,t,f) 如果value 为true ,则返回t,否则返回f
IFNULL
1 2 3 4 5 6 7 8 9 10 IFNULL(value1,value2) 如果value1不为null ,返回value1,否则返回value2 select sno as '学号' ,sn as '姓名' ,sum (IF(score>= 60 ,credit,NULL )) from s;
CASE WHEN
1 2 3 4 5 6 7 8 9 10 CASE [expr] WHEN [val1] THEN [res1] ...ELSE [default ] END 如果expr(表达式/ 字段)的值等于val1,返回res1,...否则返回default 默认值 例:查询emp表的员工姓名和工作地址,如果工作地址在北京/ 上海,则标明一线城市,其他则为二线城市 select name, (case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end ) as '工作地址' from emp;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CASE WHEN [val 1 ] THEN [RES1] ... ELSE [default ] END 如果val1为true ,返回res1,...否则返回default 默认值 例如:统计成绩,85 分以上为优秀,60 分以上为及格,60 分以下为不及格 select id, name, (case when math>= 85 then '优秀' when math>= 60 then '及格' else '不及格' end ) as '数学' , (case when english>= 85 then '优秀' when math>= 60 then '及格' else '不及格' end ) as '英语' , (case when chinese>= 85 then '优秀' when math>= 60 then '及格' else '不及格' end ) as '语文' , from score;其中math,english,chinese 三个字段使用了流程函数,使select 出来的值进行了指定
多表关系
项目开发中,在进行数据库表结构设计师,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所有各个表结构之间也存在着各种联系,基本分为三种:
一对多(多对一)
案例:部门与 员工的关系
关系:一个部门对应多个员工,一个员工对应多个部门
实现:在多的一方建立外键,指向一的一方主键
案例:学生与课程的关系
关系:一个学生可以选修多么课程,一门课程也可以供多个学生选择
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
多表查询
概述
概述:指从多张表中查询数据
笛卡尔积:笛卡尔乘积是指在数学中,两个集合A集合和B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积 )
1 2 3 4 select * from emp,dept where emp.dept_id = dept.id连接条件为: emp.dept_id = dept.id
内连接
内连接将两张表连接起来,内连接查询的是两张表的交集的部分
隐式内连接
1 2 SELECT 字段列表 FROM 表1 ,表2 WHERE 条件 ...;
显示内连接
1 2 3 4 5 SELECT 字段列表 FROM 表1 INNER JOIN 表2 ON 连接条件 INNER JOIN 表3 ON 连接条件...;SELECT 字段列表 FROM 表1 INNER JOIN 表2 INNER JOIN 表3 ON 连接条件 and 连接条件 ...;
外连接
左外连接
1 SELECT 字段列表 FROM 表1 LEFT (OUTER ) JOIN 表2 ON 条件 LEFT (OUTER ) JOIN 表3 ON 连接条件...;
注:相当于查询左表(表1)的所有数据包含表1和表2交集部分的数据
右外连接
1 SELECT 字段列表 FROM 表1 RIGHT (OUTER ) JOIN 表2 ON 条件 RIGHT (OUTER ) JOIN 表3 ON 连接条件...;
注:相当于查询右表(表2)的所有数据包含表1和表2交集部分的数据
注意:
左外连接可以和右外连接互相转换,只需要交换字段位置
外连接和内连接的区别:内连接只会展示两张表的交集部分当连接的部分中没有原表中的某条数据,即为NULL时,就不会显示出来,而外连接可以将某一张表的所有数据和交集部分显示出来,即可以显示想要知道的NULL
自连接
1 2 3 SELECT 字段列表 FROM 表A AS 别名A JOIN 表A AS 别名B ON 条件 ...;一定要将该表取两个别名,看成两张表
自连接查询,可以是内连接查询,也可以是外连接查询
联合查询
把多次查询的结果合并起来,形成一个新的查询结果集
1 2 3 4 5 6 7 8 9 10 SELECT 字段列表 FROM 表A ...UNION [ALL ]SELECT 字段列表 FROM 表B ...;例子: select * from emp where salary < 5000 union all select * from emp where age > 50 有ALL 可能会导致有重复,但去掉ALL 只用union 则会去除相同的
注意:
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
union all 会将全部的数据直接合并在一起,union会对合并之后的数据去重
or只能单表查询,而union可以多表查询
子查询
概念:SQL语句中嵌套SELECT语句,成为嵌套查询 ,又称子查询
1 2 3 SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);子查询外部的语句可以是:INSERT / UPDATE / DELETE / SELECT 的任何一个。
标量子查询
子查询返回的结果是单个值(数字、字符串、日期等), 是最简单的形式,这种子查询称为标量子查询
常用的操作符:= ,<> ,>, >=, <, <=
1 2 3 4 5 6 7 8 9 10 11 select id from dept where name = '销售部' ;select * from emp where dept_id = 4 ;select * from emp where dept_id = (select id from dept where name = '销售部' );
列子查询
子查询返回的结果是一列(可以是多行), 这种子查询成为列子查询。
常用的操作符: IN 、NOT IN 、ANY 、SOME 、ALL、EXISTS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 IN :在指定的集合范围之内 ,多选一NOT IN : 不在指定的集合范围之内ANY :子查询返回列表中,有任意一个满足即可SOME : 与ANY 等同,使用SOME 的地方都可以使用ANY ALL : 子查询返回列表的所有值都必须满足EXISTS : 也可进行相关子查询,但不返回任何实际数据,只得到真或假例: select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部' );select salary from where dept_id = (select id from dept where name = '财务部' )select * from emp where salary > ALL (select salary from where dept_id = (select id from dept where name = '财务部' )salary )select salary from where dept_id = (select id from dept where name = '研发部' )select * from emp where salary > ANY (select salary from where dept_id = (select id from dept where name = '研发部' ))
1 2 3 4 5 6 select sno,sn from s where not exists (select * from sc where sno = s.sno AND cno = 'C1' )
行子查询
子查询返回的结果是一行(可以是多列),这种子查询成为行子查询
常用的操作符:= ,<> ,IN、NOT IN
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 select salary,managerid from emp where name = '张无忌' ;select * from emp where salary = 12500 and managerid = 1 ;select * from emp where (salary,managerid) = (12500 ,1 );select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '张无忌' );
表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询
常用操作符: IN
1 2 3 4 5 6 7 8 select job,salary from emp where name = 'lzk' or name = 'lyq' ;select from emp where (job,salary) in (select job,salary from emp where name = 'lzk' or name = 'lyq' )
事务简介
事务(transaction)是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作 要么同时成功,要么同时失败
事务操作
方式一
1 2 3 4 5 6 7 SELECT @@autocommit ;SET @@autocommit = 0 ;
方式二
1 2 3 4 START TRANSACTION 或 BEGIN ;
事务的四大特性(ACID)
原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败
一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态(合理加减)。
隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变使永久的。
并发事务问题
丢失更新 :两个事务读入同一数据,并发执行修改操作时,一个事务将另一个事务的修改覆盖,导致这些修改好像丢失了一样
读取脏数据(脏读):一个事务读到另外一个事务 还没有提交 的数据(未commit)
**不可重复读:**在一个事务中先后读取同一条数据,但两次读取的数据不同,称为不可重复读。
**幻象读(幻读):**一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在了,好像出现了"幻影"
事务隔离级别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 脏读 不可重复读 幻读 Read uncommitted: 会出现 会出现 会出现 Read committed: 不会 会 会 Repeatable Read: 不会 不会 会 Serializable: 不会 不会 不会
1 2 3 4 5 6 7 8 SELECT @@TRANSACTION_ISOLATION ;SET [SESSION| GLOBAL ] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED| READ COMMITTED| REPEATABLE READ| SERIALIZABLE]
进阶篇
索引
索引(index) 是帮助MySQL高效获取数据 的数据结构(有序) 。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
优点:
提高数据检索的效率,降低数据库的IO成本
通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
缺点:
索引列需要占用空间
索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率降低
索引结构
MySQL的索引是在储存引擎层实现的,不同的储存引擎有不同的结构,主要包含以下几种:
B+Tree索引:最常见的索引类型,大部分引擎都支持B+树索引
Hash索引:底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询
R-tree:空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少
Full-text:是一种通过建立倒排索引,快速匹配文档的方式,类似于Lucene,Solr,ES
我们平常所说的索引,如果没有特别指明,都是指B+树结构组织的索引。
二叉树缺点:顺序插入时,会形成一个链表,查询性能大大降低。大数据量的情况下,层级较深,检索速度慢。
红黑树:大数据量的情况下,层级较深,检索速度慢。
以一颗最大度数为5(5个子节点)的b-tree为例(每个节点最多储存四个key,5个指针),指针数 = key + 1
1 插入 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88 120 268 250 为例
B-Tree 动态变化的过程可以参考网站:
B-Tree Visualization (usfca.edu)
Data Structure Visualization (usfca.edu)
索引分类
主键索引 :针对于表中主键创建的索引,建表时默认自动创建,只能有一个,关键字是PRIMARY。
唯一索引 :避免同一个表中某数据列中的值重复,可以有多个,关键字UNIQUE。
常规索引 :快速定位特定的数据,可以有多个。
全文索引 :全文索引查找的是文本中的关键词,而不是比较索引中的值,可以有多个,关键字FULLTEXT。
空间索引: 使用了SPATIAL关键字的索引,适用于GEOMETRY ,POINT,POLYGON等空间类型数据的列
在InnoDB储存引擎中,根据索引的存储形式,又可以分为以下两种:
聚集索引(Clustered Index):将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据(记录),必须有,而且只有一个
二级索引(Secondary Index):将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键,可以存在多个
聚集索引的选取规则:
如果存在主键,主键索引就是聚集索引。
如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引
如果表中没有主键,或没有适合的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引
回表查询:先根据字段对应的二级索引去查对应的主键值,在根据主键对应的聚集索引去查行数据。
索引语法
创建索引
1 2 3 4 5 CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name ON table_name(字段名[(索引字符长度) [ASC | DESC ]],...);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 create index idx_user_name on tb_user(name);create index idx_user_name on tb_user(name(3 ) desc );create UNIQUE index idx_user_phone on tb_user(phone);create index idx_user_pro_age_status on tb_user(profession、age、status);联合索引中字段索引是有讲究的 create index idx_user_email on tb_user(email);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 create table 表名( 字段1 数据类型 列约束 comment '注释' , 字段2 数据类型 列约束 comment '注释' , ... [表约束], [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name(字段名[(索引字符长度) [ASC | DESC ]],...), ... [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name(字段名[(索引字符长度) [ASC | DESC ]],...), ) create table classroom( cid int auto_increment, crno varchar (13 ) not null , cbn varchar (10 ) not null , primary key(cid), unique index cn_cb_index(crno,cbn) );
1 2 3 1. 在表约束后,可以使用index关键字为表创建索引,与create index用法相同。2. create table 语句可以一次附带多个索引,不同索引间使用逗号分隔3. create table 创建索引时无需提供表名,而是使用create index语句创建索引时要指明表名
查看索引
1 SHOW INDEX FROM table_name;
1 2 show index from tb_user;
修改索引
Mysql 索引(三)—— 不同索引的创建方式(主键索引、普通索引、唯一键索引)-CSDN博客
删除索引
1 2 DROP INDEX index_name ON table_name;
1 2 drop index idx_user_email on tb_user;
视图
视图(view)是一种虚拟存在的表 。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果 。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。
视图语法
1 2 3 4 CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT 语句 [WITH [CASCADED | LOCAL ] CHECK OPTION]
1 2 3 4 5 SHOW CREATE VIEW 视图名称;SELECT * FROM 视图名称 WHERE...;
1 2 3 4 show create view stu_v_1;select * from stu_v_1;select * from stu_v_1 where id < 3 ;
1 2 3 4 5 CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT 语句 [WITH [CASCADED | LOCAL ] CHECK OPTION]ALTER VIEW 视图名称[(列名列表)] AS SELECT 语句 [WITH [CASCADED | LOCAL ] CHECK OPTION]
1 DROP VIEW [IF EXISTS ] 视图名称,... ;
视图的检查选项
当使用with check option子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如 插入,更新,删除,以使符合视图的定义。MySQL允许基于另一个视图创建视图 ,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项:cascaded 和 local,默认值为cascaded(级联) 。
CASCADED(级联)
cascade 会去递归检查当前视图以及创建时依赖的视图,并且看是否加了检查选项,如果其依赖的视图中没有加入检查选项,则会将cascaded向下传递,使其向下的视图都加上检查选项使其都能检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 create or replace view stu_1 as select id,name from student where id <= 20 select * from stu_1;insert into stu_1 values (6 ,'TOM' )insert into stu_1 values (30 ,'TOM' )create or replace view stu_1 as select id,name from student where id <= 20 with cascaded check option;insert into stu_1 values (30 ,'TOM' )
1 2 3 4 5 6 7 8 9 10 11 12 create or replace view stu_1 as select id,name from student where id <= 20 create or replace view stu_2 as select id,name from student where id >= 10 with cascaded check optioncreate or replace view stu_3 as select id,name from student where id <= 15 insert into stu_3 values (11 ,'tom' );insert into stu_3 values (17 ,'tom' );insert into stu_3 values (28 ,'tom' );
LOCAL
local 会去递归检查当前视图以及创建时依赖的视图,并且看是否加了检查选项,如果有,则进行条件的检查看是否满足条件,如果没有则不进行检查继续递归
1 2 3 4 5 6 7 8 9 10 11 create or replace view stu_1 as select id,name from student where id<= 15 ;create or replace view stu_2 as select id,name from stu_1 where id >= 10 ;create or replace view stu_3 as select id,name from stu_2 where id < 20 with local check option;insert into stu_3 values (13 ,'TOM' );