MySQL基础学习笔记

本文详细介绍了MySQL数据库中的SQL命令,包括选择、计数、别名、拼接、去除重复、处理NULL值、条件查询、排序、分组、流程控制函数、子查询、连接查询、DML操作、DDL操作以及事务处理。还探讨了数据类型、时间类型、字符串类型、索引、视图、全文检索和数据库范式。内容涵盖了数据查询语言DQL、数据操纵语言DML、数据定义语言DDL和数据控制语言DCL的主要用法。
摘要由CSDN通过智能技术生成

https://www.bilibili.com/video/BV12b411K7Zu

https://www.bilibili.com/video/BV1Vy4y1z7EX

常用的SQL命令

select * from stu;
select count(*) from stu where username='zhangsan' and password='123456';#进行登陆验证
select `name` from `stu`;#加上点号不会出现和关键字重合的问题
select * from stu where sex='男';#注意字符型要加单引号或双引号
select name as '名字' from stu;#或者是不写as写成空格
select concat(id,name) from stu;#将两列合并为一列
select distinct id from stu;#去除重复元素
select ifnull(name,'无名氏') from stu;#起别名,如果是null则返回无名氏
select name from stu where id=1;#查询id为1的用户
select name from stu where id>=10 and id <=100;#查询id在[10,100]的名称
select name from stu where id between 10 and 100;#作用同上
select id from stu where name like '_e%'#_代表单个字符,%代表大于等于0个字符
select name from stu where id in (1,2,3);#查询id在1,2,3的名称
select * from stu where name is null;#is not null
select * from stu where id>10 order by id asc,name desc;#id升序,名字降序排列

SQL语句的分类

  • DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等;
  • DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据);
  • DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;
  • DQL(Data Query Language):数据查询语言,用来查询记录(数据)。

我们写的语句将近80%是查询语句

基本数据类型

数值类型

类型大小范围(无符号)用途
TINYINT1 Bytes(0,255)小整数值
SMALLINT2 Bytes(0,65 535)大整数值
MEDIUMINT3 Bytes(0,16 777 215)大整数值
INT或INTEGER4 Bytes(0,4 294 967 295)大整数值
BIGINT8 Bytes(0,18 446 744 073 709 551 615)极大整数值
FLOAT4 Bytes0,(1.175 494 351 E-38,3.402 823 466 E+38)单精度 浮点数值
DOUBLE8 Bytes0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)双精度 浮点数值
DECIMAL对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2依赖于M和D的值小数值

时间类型

类型大小 ( bytes)范围格式用途
DATE31000-01-01/9999-12-31YYYY-MM-DD日期值
TIME3‘-838:59:59’/‘838:59:59’HH:MM:SS时间值或持续时间
YEAR11901/2155YYYY年份值
DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值
TIMESTAMP41970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07YYYYMMDD HHMMSS混合日期和时间值,时间戳

字符串类型

类型大小用途
CHAR0-255 bytes定长字符串
VARCHAR0-65535 bytes变长字符串
TINYBLOB0-255 bytes不超过 255 个字符的二进制字符串
TINYTEXT0-255 bytes短文本字符串
BLOB0-65 535 bytes二进制形式的长文本数据
TEXT0-65 535 bytes长文本数据
MEDIUMBLOB0-16 777 215 bytes二进制形式的中等长度文本数据
MEDIUMTEXT0-16 777 215 bytes中等长度文本数据
LONGBLOB0-4 294 967 295 bytes二进制形式的极大文本数据
LONGTEXT0-4 294 967 295 bytes极大文本数据

注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。

DQL:查询数据

DQL就是数据查询语言,数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。

语法:

select
	selection_list /*要查询的列名称*/
from
	table_list /*要查询的表名称*/
where
	condition /*行条件*/
group by 
	grouping_columns /*对结果分组*/
having
	condition /*分组后的行条件*/
order by
	sorting_columns /*对结果分组*/
limit
	offset_start, row_count /*结果限定*/

简单查询

基础查询

select column1,column2,column3 from table;
select * from table;

select后面可以跟多个字段

起别名as

select name as '用户名' from stu;#单引号双引号都可以
select name  '用户名' from stu;

可以写as或者加空格就OK了,注意字符要加引号的,单引号双引号都可以

将多列拼为一列concat

select concat(id,'-',name) as name from stu;

concat可以将多列拼在一起,加个-就是在两列之间加个-,最后返回为一个数据

去除重复元素distinct

select distinct id from stu;

将返回的id去除重复元素之后再返回

查看表的结构desc

desc stu;
/*或者*/
show columns from stu;

处理null值ifnull

select ifnull(name,'无名氏') from stu;

如果name是null则返回无名氏

条件查询where

select 字段
from 表明
where 筛选条件

执行顺序:from、where、select

关系运算符

> 、<、>=、<=、=、!=、<>

select name from stu where id=10;
select name from stu where id>=10;

逻辑运算符

and、or、not、&&、||、!

select name from stu where id>=10 and id<=100;

模糊查询

like

一般用于字符串的查询,通常和通配符一起使用

通配符:_代表任意单个字符,%代表任意多个字符(大于等于0)

select * from stu where name like '%e';#查询以e结尾的名称

转义字符:可以使用\,或者自定义转义字符

select * from stu where name like '_$_' escape '$';指定¥为转义字符
in、not in
select * from stu where id in (1,2,3,4,5);

查找符合id在这个集合中的数据

between and 、not between and
select * from stu where id is null;

查询id为空的数据

is只能判断是否为null,写成is 0报错。
=只能判断简单数值,写成=null则为空。
<=>安全等于号技能判断null也能判断数值

排序查询(默认升序)

select 查询列表
from 表名
[where 筛选条件]
order by 排序列表;

执行顺序:表名、筛选条件、查询列表、排序列表

特点:

  • 排序列表可以是单个字段、多个字段、表达式、函数、常量(列次序)以及以上的组合
  • 升序:通过asc(ascend)
  • 降序:通过desc(decrease)
  • 也可以通过自己起的别名进行排序

基础用法

# 根据id升序
select * from stu order by id;
# 将返回到的结果根据id升序排列
select * from stu order by length(name);
# 现根据id升序,再根据name降序
select * from stu order by id asc,name desc;

不能在where中使用select的别名

根据sql执行的顺序优先级可以知道,先执行select字句,再执行order by字句,因此,在select字句中起的别名可以在order by字句中使用。但是where的优先级高于select,因此,where字句不能使用

使用列次序排列

select * from stu order by 2;

根据第二列升序排列

常见函数

直介绍常用的,如果感觉不全面可以自行百度

字符函数

函数功能示例示例结果
concat拼接字符串select concat(id,’-’,name) 信息 from stu;最后返回的结果是id-name的形式,即:1-帅龙
length获取字节长度select length(‘I love 帅帅龙’);返回16=7+3*3,utf-8编码规范中,一个汉字占据3个字节
char_length获取字符长度select char_length(‘I love 帅帅龙’);返回10,返回的就是len,一个汉字也是1,一个空格也是1
sub_str截取指定字串sub_str(‘我爱帅帅龙’,2,2)返回爱帅,第一个参数是需要处理二点字段,第二个参数是起始的index(从1开始),第三个参数是截取的长度,不写默认到最后
left/right:截取左/右指定长度字串select left(‘我爱帅帅龙’,2);返回我爱
trim去除两端字符select trim(’ 我爱帅帅龙 ');返回我爱帅龙
trim去除两端字符select trim(‘x’ from ‘xxaa我爱帅帅龙aa’);返回aa我爱帅龙aa
lpad/rpad左/右填充指定字符,第一个参数是填充的字段,第二个参数是填充的个数,第三个参数是填充的字符select lpad(‘我爱帅帅龙’,10,‘x’);返回xxxxxxxxxx我爱帅帅龙
upper/lower变大写/小写select upper(‘love’);返回LOVE
strcmp比较字符大小select strcmp(‘love’,‘abc’);返回love
instr获取字串首次出现的索引select instr(‘我爱帅帅龙’,‘帅’);返回3

数学函数

  • abs()取绝对值
  • floor()向下取整
  • ceil()向上取整
  • round(数字,四舍五入保留的位数)
  • truncate(数字,截取后剩下的长度)
  • %取余
select abs(money) from stu;

日期函数

  • now()获取当前日期+时间
  • curdate()获取当前日期
  • curdtime()获取当前时间
  • datediff(a,b)两时间做差,前面减去后面,返回天数
  • date_format将日期转为指定格式字符串
select date_format('1998-7-16','%Y年%m月%d日 %H时%i分%s秒');
  • str_to_date字符串转为时间
select str_to_date('7/16 1998','%m/%d %Y');

在这里插入图片描述

聚合函数

  • sum()
  • avg()
  • max()
  • min()
  • count(字段)统计该字段非null的有几个
select sum(money) from stu;

聚合函数常常和分组查询连用

流程控制函数

if语句

格式

select if(条件,成立的结果,不成立的结果);

示例

select if(money if null,0,money) from stu;

如果money是null就返回0,不是null就返回原本数值

case语句

格式

case 表达式
when1 then 结果1
when2 then 结果2
...
else 结果n
end

别忘记最后的end

case组合的类if-else结构

格式

case 
when 判断1 then 结果1
when 判断2 then 结果2
...
else 结果n
end

别忘记最后的end

分组查询

格式:

select 列表/分组函数
from 表明
where 条件
group by 分组列表;

示例

计算不用类别学生的金钱总额,会先分组,然后求和

select sum(money) from stu group by `type`; 

计算不同类型的人数,会先分组,然后计数

select count(*) from stu group by `type`; 

当根据多个字段进行分组的时候,只有当这几个字段都相同的时候,才分为一组,下面代码就是当groupid和type都相同的才分为一组

select count(*) from stu group by `type`,`group_id`; 

连接(sql99语法)

内连接(查询交集部分)

等值连接(连接条件是固定值,两值相等筛选出来)

格式:inner可以省略

select 字段
from1 别名1
[inner] join2 别名2
on 连接条件
where 筛选条件
group by 分组条件
having 分组后筛选
order by 排序条件

示例:首先得到id相同的数据,然后根据city分组

select count(*) 部门个数,l.city
from departent d
join location l
on d.location=l.location
group by l.city
非等值连接(连接条件不是固定值,满足条件的筛选出来)

和等值连接差别不是很大,只不过是连接条件有所改动

select count(*) 个数,grade
from employees e
join sal_grade g
on e.salary between g.min_salary and max_salary
group by g.grade
自连接(自己和自己连接)

员工和领导的名字一一对应

select e.name,m.name
from employees e
join employees m
on e.manange_id=m.employees.id

外连接(一般查A表有B表没有)

左外连接(左连接)、右外连接(右连接)

大家想一下,什么时候用内连接呢?是表a和表b的数据都存在的时候才可以,那现在有如下需求,查出表a中没有女朋友的个数,此时就需要使用到外连接了

外连接分主表和从表,查询结果是主表的所有记录,用where进行筛选结果,如果从表中有和主表对应的数据则返回该数据,否则返回null,但如果是内连接的话就不会返回null

  • 在左外连接中,left join左边的是主表
  • 在右外连接中,right join右边的是主表

格式:

select count(*) 
from1 别名1
left/right outer join2 别名2
on 连接条件
where 筛选条件

如果写left则表1为主表,如果写right则表2为主表,通常写left,即主表在上

全外连接(MySQL不支持)

全外连接 = 内连接的结果 + 表1中有但表2没有的 + 表2中有但表1没有的

交叉连接(求了个笛卡尔乘积)

就是相当于求了个笛卡尔乘积,4*11 = 44

select b.*,bo.*
form beauty b
cross join boys bo

子查询(其他语句中的se1ect语句)

出现在其他语句(不仅仅是select语句)中的se1ect语句,称为子查询或内查询。一个语句中嵌套了完整的select语句,被嵌套的成为子查询或内查询,外面的为主查询或外查询

根据子查询的位置可以分为这几种:

  • select后面:要求结果为单行单列,用的不多
  • from后面:可以为多行多列,也就是咱们平时的数据表格式
  • where或having后面:用的最多,子查询结果必须为单列
  • exists后面:相关子查询,结果为单列

子查询特点:

  • 放在条件右侧,大于小于右侧
  • 子查询一般放在括号里
  • 单行子查询配合单行操作符符号:>、<、=、>=、<=
  • 多行子查询配合多行子查询符号:any/some、all、in

单行子查询

查询和zrl相同部门的员工姓名和工资

select name,salary
from employees
where department_id=(
		select department_id
		from employees
		where name='zrl'
	);

多行子查询

  • in:在…中
  • any/some:满足大于或小于其中一个即可
  • all:要大于或小于全部数值
    在employee中找到薪水大于stu表中任意一人的薪水,即可以优化为大于其中的最小值
select *
from employees
where maoney>any(
		select money
		from stu
	);

分页查询

我以前以为只有使用分页工具才可以返回Page对象的,原来可以直接查啊,真滴舒服

格式:

select 
from
join
on
where
group by
having
order by
limit 起始索引(从0开始,不写的话默认为0,需要显示的条目数

顺序是:from、join、on、where、group by、having、select、limit

联合查询(列拼接在一起)

联合查询可以理解为一种简化的查询方式,下面两条SQL等价

SELECT FROM employees WHERE email LIKE '%a%' OR department_id>90;
SELECT* FROM employees WHERE email LIKE
UNION
SELECT FROM employees WHERE department_id>90;

当查询的结果来自多张表的时候,并且多张表无关联,需要使用联合查询把几列竖向拼接在一起,注意多条多列数据的列数必须匹配,谁写在第一个最后显示的字段名就是什么,使用union会自动去重,如果想保留重复数据可以使用union all

select id,cname,csex from t_ca where csex='男'
union
select t_id,t_name,t_gender from t_ua where t_gender='male';

在这里插入图片描述

DML:增删改数据

insert插入数据

插入一条数据

#当插入一条数据的时候可以使用value,但是为了好记就记成values吧,因为插入多条数据使用calues
insert into stu(字段1,字段2,字段3...) values(1,2,3...);

插入多条数据

insert into stu(字段1,字段2,字段3...) values
(1,2,3...),(1,2,3...),(1,2,3...);

特点

  • 如果写了字段,那么顺序没有要求,但是字段和值要一一对应,同时值要满足约束要求
  • 如果不写字段,那么数据就和表结构的字段顺序一一对应,格式如下
insert into stu values(1,2,3...);
  • 数值型不用引号,但是非数值型需要引号,例如字符、时间等
  • 插入可空约束数据,但是没数据,要么不写这个字段,要么字段对应的值写null
  • 插入有默认数值约束数据,要么不写这个字段,要么字段对应的值写default
  • 插入有递增约束数据,要么不写这个字段,要么字段对应的值写null

delete删除数据

两种方式

delete from 表名 where 条件;#写了where就只删除一条,否则全部删除
truncate table 表名;#删除全部数据

delete与truncate的区别:

  • delete可以写where条件
  • delete可以返回受影响行数
  • delete可以支持事务回滚
  • delete删除数据后,自增约束的字段从断点继续自增,truncate删除数据后,自增约束的字段从0开始自增
  • truncate效率高,但是更象DDL,管理数据表的语言

updates更新数据

updates 表名 set name='张三' where id=1;

多表修改也是可以的,但是挺麻烦,也不常用,等遇到了再补充吧,现在先不写了

DDL:操作数据库、表

库的管理

创建库

creat database test;
creat database if not exists test;#写这个容错性好一点

删除库

drop database test;
drop database if exists test;#这样写容错性好一点 

表的管理

常见约束

  • PRIMARY KEY主键
  • AUTO_INCREMENT自增
  • NOT NULL非空
  • DEFAULT默认值
  • UNIQUE唯一
  • FOREIGN KEY外键
  • CHECK检查,mysql不支持

注:

  • 设置了自增,要么插入数据时候不操作这个字符段,要么写null,如果填入具体数值则不能自增
  • 主键按只能有一个,设置了很多的时候视为一组,只有这几条数据同时存在于一条已存放的数据的时候才算主键重复
  • 唯一键约束可以有多个
  • 如果设置外键必须满足两个要求:主表关联列必须为主键;两列的数据类型相同

创建表

creat table if not exists stuinfo(
	stuid int primary key,
	stuname varchar(20) unique not null,
	gender char default '男',
	email varchar(20) not null,
	age int check(age between 0 and 90),#mysql就算写了也不给你检查
	major_id int,
	#外键约束要放在最后单独写
	foreign key (major_id) references major(id)#major表的id字段
);

修改表

alter table 表名 add|modify|change|drop column 字段;
功能示例
修改表名alter table stu rename to studata;
添加字段alter table stu add column id int primary key;
修改字段名alter table stu change brithday birthday_data date;
修改字段类型alter table stu modify column birthday timestamp;
删除字段alter table stu drop column birthday;

复制表

仅复制表的结构

creat table new_table like old_table;

复制表的结构和数据

creat table new_table select * from old_table;

主键

什么类型适合做主键

不建议使用 varchar 来做主键,因为MYSQL数据库,因为主键默认有个排序,varchar类型会严重影响效率,主键值一般都是数字或定长的字符

主键的分类

主键除了单一主键和复合主键之外,还可以分为自然主键和业务主键:

  • 自然主键:主键值是一个自然数,和业务没关系
  • 业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。这就是业务主键!

在实际开发中使用业务主键多,自然主键使用比较多,因为主键只要做到不重复就行,不需要有意义

业务主键不好,因为主键一旦和业务挂钩,那么当业务发生变动的时候,可能会影响到主键值,所以业务主键不建议使用,尽量使用自然主键

外键

涉及到的相关术语

外键约束涉及到的相关术语:

  • 外键约束:一种约束( foreign key)
  • 外键字段:该字段上添加了外键约束
  • 外键值:外键字段当中的每一个值

设置外键的要求

如果设置外键必须满足两个要求:

  • 主表关联列必须为主键
  • 两列的数据类型相同

创建一个外键

为了保证表引用(子表)的数据id是有效的,因此要添加外键约束,如果不加这个约束的话。这个值可能会瞎写,不能保证正确性,加上了只能引用指定外键的数据

creat table if not exists stuinfo(
	stuid int primary key,
	stuname varchar(20) unique not null,
	gender char default '男',
	email varchar(20) not null,
	age int check(age between 0 and 90),#mysql就算写了也不给你检查
	major_id int,
	#外键约束要放在最后单独写
	foreign key (major_id) references major(id)#major表的id字段
);

操作父、子表的顺序

删除表的顺序:先删子,再删父

创建表的顺序:先创建父,再创建子

删除数据的顺序:先删子,再删父

插入数据的顺序:先插入父,再插入子

存储引擎

InnoDB存储引擎

​ 这是mysql默认的存储引擎,同时也是一个重量级的存储引擎。
​ InnoDB支持事务,支持数据库崩溃后自动恢复机制。
​ InnoDB存储引擎最主要的特点是:非常安全。

它管理的表具有下列主要特征:

  • 每个 InnoDB 表在数据库目录中以.frm 格式文件表示
  • InnoDB 表空间 tablespace 被用于存储表的内容(表空间是一个逻辑名称。表空间存储数据+索引。)
  • 提供一组用来记录事务性活动的日志文件
  • 用 COMMIT(提交)、SAVEPOINT 及ROLLBACK(回滚)支持事务处理
  • 提供全 ACID 兼容
  • 在 MySQL 服务器崩溃后提供自动恢复
  • 多版本(MVCC)和行级锁定
  • 支持外键及引用的完整性,包括级联删除和更新

InnoDB最大的特点就是支持事务,以保证数据的安全。

效率不是很高,并且也不能压缩,不能转换为只读,不能很好的节省存储空间。

MEMORY存储引擎

MEMORY 存储引擎以前被称为HEAP 引擎。使用 MEMORY 存储引擎的表,其数据存储在内存中,且行的长度固定,这两个特点使得 MEMORY 存储引擎非常快。

MEMORY 存储引擎管理的表具有下列特征:

  • 在数据库目录内,每个表均以.frm 格式的文件表示。
  • 表数据及索引被存储在内存中。(目的就是快,查询快!)
  • 表级锁机制。
  • 不能包含 TEXT 或 BLOB 字段。

MEMORY引擎优点:查询效率是最高的。不需要和硬盘交互。

MEMORY引擎缺点:不安全,关机之后数据消失。因为数据和索引都是在内存当中。

事务

什么是事务

事务对应的英语单词是:transaction,只有DML语句(增删改)才会有事务这一说,其它语句和事务无关!!!

一个事务其实就是一个完整的业务逻辑,即一件事,是一个最小的工作单元,不可再分。一个事务由一个或多个sql组成,要么所有sql全部执行成功,要么全部都执行不成功。如果一个事务只有一条DML语句,那事务没有存在的必要

事务的分类

  • 隐式事务
    例如update、delete、insert语句
  • 显式事务
    分为五步,具体参看下面操作

提交事务、回滚事务

  • 提交事务:commit; 语句

  • 回滚事务:rollback; 语句(回滚永远都是只能回滚到上一次的提交点!)

---------------------------------回滚事务----------------------------------------
# 取消隐式事务自动开启,可有可无
mysql> set autocommit=0;
mysql> start transaction;
...
mysql> rollback;
# 恢复默认设置,可有可无
mysql> set autocommit=1;
---------------------------------提交事务----------------------------------------
# 取消隐式事务自动开启,可有可无
mysql> set autocommit=0;
mysql> start transaction;
...
mysql> commit;
mysql> rollback;
# 恢复默认设置,可有可无
mysql> set autocommit=1;

事务的四大特性(ACID)

  • 原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
  • 一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
  • 隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
  • 持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

事务的隔离性

A教室和B教室中间有一道墙,这道墙可以很厚,也可以很薄。这就是事务的隔离级别,这道墙越厚,表示隔离级别就越高。

事务和事务之间有四个隔离级别:

  • 读未提交:read uncommitted(最低的隔离级别)《没有提交就读到了》

    • 事务A可以读取到事务B未提交的数据。这种隔离级别存在的问题就是脏读现象!(Dirty Read),我们称读到了脏数据。这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二档起步!
  • 读已提交:read committed《提交之后才能读到》

    • 事务A只能读取到事务B提交之后的数据,这种隔离级别解决了解决了脏读的现象。这种隔离级别存在的问题是不可重复读取数据。
    • 什么是不可重复读取数据呢?
      在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4称为不可重复读取。这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实。oracle数据库默认的隔离级别是:read committed
  • 可重复读:repeatable read《提交之后也读不到,永远读取的都是刚开启事务时的数据》

    • 事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读。可重复读解决了解决了不可重复读取数据,但可重复读可能会出现幻影读,每一次读取到的数据都是幻象。不够真实!例如早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样!读到的是假象,不够绝对的真实。

      mysql中默认的事务隔离级别就是这个!!!!!!!!!!!

  • 序列化/串行化:serializable(最高的隔离级别)

    • 这是最高隔离级别,效率最低。解决了所有的问题。这种隔离级别表示事务排队,不能并发synchronized,线程同步(事务同步)每一次读取到的数据都是最真实的,并且效率是最低的。

事务的使用

Spring Boot实现事务特别特别简单,没有多余操作,类上添加一个注解@Transactional搞定

索引

什么是索引

索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制。

索引的实现原理

  • 提醒1:在任何数据库当中主键上都会自动添加索引对象,id字段上自动有索引,
    因为id是PK。另外在mysql当中,一个字段上如果有unique约束的话,也会自动
    创建索引对象。
  • 提醒2:在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有
    一个硬盘的物理存储编号。
  • 提醒3:在mysql当中,索引是一个单独的对象,不同的存储引擎以不同的形式
    存在,在MyISAM存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中
    索引存储在一个逻辑名称叫做tablespace的当中。在MEMORY存储引擎当中索引
    被存储在内存当中。不管索引存储在哪里,索引在mysql当中都是一个树的形式
    存在。(自平衡二叉树:B-Tree)

什么条件下会给字段添加索引呢

在mysql当中,主键上,以及unique字段上都会自动添加索引的!!!!

  • 条件1:数据量庞大(到底有多么庞大算庞大,这个需要测试,因为每一个硬件环境不同)
  • 条件2:该字段经常出现在where的后面,以条件的形式存在,也就是说这个字段总是被扫描。
  • 条件3:该字段很少的DML(insert delete update)操作。(因为DML之后,索引需要重新排序。)

建议不要随意添加索引,因为索引也是需要维护的,太多的话反而会降低系统的性能。建议通过主键查询,建议通过unique约束的字段进行查询,效率是比较高的。

注意:唯一性比较弱的字段上添加索引用处不大。

索引创建与删除

创建索引:给emp表的ename字段添加索引,起名:emp_ename_index

create index emp_ename_index on emp(ename);

删除索引:将emp表上的emp_ename_index索引对象删除。

drop index emp_ename_index on emp;

索引失效

  • 查询语句中使用LIKE关键字时,%在第一个位置
  • 查询语句中使用多列索引(复合索引),在表的多个字段上创建一个索引,只有查询条件中使用了这些字段中的第一个字段,索引才会被使用
  • 查询语句只有 OR 关键字时,如果 OR 前后的两个条件的列都是索引,那么查询中将使用索引。如果 OR 前后有一个条件的列不是索引,那么查询中将不使用索引。
  • 在where当中索引列参加了运算,索引失效。
  • 在where当中索引列使用了函数
  • 后面深入学习MySQL的时候再补充哈…

数据库三种范式

https://www.bilibili.com/video/BV1Vy4y1z7EX?p=127

  • 第一范式(最重要):要求任何一张表必须有主键,每字段原子性不可再分
  • 第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖(例如老师编号和学生编号是复合主键,老师依赖老师编号、学生依赖学生编号),这是多对多的情况,可以用三张表表示两者关系(学生表、教师表、学生教师关系),但是一对多就没事,只需要判断和主键的依赖关系即可。多对多,三张表,关系表加两个外键
  • 第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖(一年一班依赖01,01依赖1001,拆分成两张表:学生表、班级表)。一对多,两张表,对多的表加外键

注意:三范式是面试官经常问的,所以一定要熟记在心!

设计数据库表的时候,按照以上的范式进行,可以避免表中数据的冗余,空间的浪费

视图

http://c.biancheng.net/mysql/80/

  • 视图是一张虚拟表,将复杂的SQL封装,让其可重用同时可以简化开发
  • 索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。

存储过程、游标、触发器

http://c.biancheng.net/mysql/85/

  • 存储过程是数据库中的一个重要功能,存储过程可以用来转换数据、数据迁移、制作报表,它类似于编程语言,一次执行成功,就可以随时被调用,完成指定的功能操作。
  • 在 MySQL 中,存储过程或函数中的查询有时会返回多条记录,而使用简单的 SELECT 语句,没有办法得到第一行、下一行或前十行的数据,这时可以使用游标来逐条读取查询结果集中的记录。游标在部分资料中也被称为光标。
  • MySQL 的触发器和存储过程一样,都是嵌入到 MySQL 中的一段程序,是 MySQL 中管理数据的有力工具。不同的是执行存储过程要使用 CALL 语句来调用,而触发器的执行不需要使用 CALL 语句来调用,也不需要手工启动,而是通过对数据表的相关操作来触发、激活从而实现执行。比如当对 student 表进行操作(INSERT,DELETE 或 UPDATE)时就会激活它执行。

全文检索

MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。

innodb不支持全文检索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笼中小夜莺

嘿嘿嘿,请用金钱尽情地蹂躏我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值