Mysql 笔记记录
MySQL学习笔记
一、 DDL
1. DDL 查询和创建数据库
#查询所有数据库
SHOW DATABASES;
#查询某个数据库的创建语句
show create DATABASE mysql;
#创建数据库
create DATABASE db1;
#创建数据库,判断如果不存在则创建
create DATABASE if not EXISTS db2;
#创建数据库指定字符集
create DATABASE db3 CHARACTER set utf8;
#查看db3数据库的字符集
show create DATABASE db3;
#练习:创建db4数据库,如果不存在则创建并指定字符集gbk
create DATABASE if not EXISTS db4 CHARACTER set gbk;
#查看db4的字符集
show create DATABASE db4;
2. DDL 修改、删除、使用数据库
#修改数据库的字符集
alter DATABASE db4 CHARACTER set utf8;
#查看db4是否改为utf8
show create DATABASE db4;
#删除数据库
drop DATABASE db1;
#删除数据库,判断如果存在则删除
drop DATABASE if EXISTS db2;
#使用数据库
use db4;
#查询当前正在使用的数据库
select DATABASE();
3. DDL 查询数据表
#使用mysql数据库
use mysql;
#当前使用数据库
SELECT DATABASE();
#查询库中所有的表
show TABLEs;
#查询表结构
desc user;
#查询数据表的字符集
show table status from mysql like 'user';
4. DDL 创建数据表
#使用db3数据库
use db3;
#创建数据表
CREATE TABLE product ( id INT, NAME VARCHAR ( 20 ), price DOUBLE, stock INT, insert_time date );
#查看product详细表结构
desc product;
5. DDL 修改数据表
#使用db3数据库
use db3;
#修改表名product为product2
ALTER table product rename to product2;
#查看product2表的字符集
show table status from db3 like 'product2';
#修改表的字符集为gbk
alter table product2 CHARACTER set gbk;
#给表product2添加一列color
alter table product2 add color varchar(20);
#将product2中color的类型改为int
alter table product2 MODIFY color int;
#查看表的详细结构
desc product2;
#修改表中的名称和数据类型
alter table product2 change color colors varchar(25);
#删除某列 colors列
alter table product2 drop colors;
6. DDL 删除数据表
#使用db3数据库
use db3;
#删除数据表 product2
drop table product2;
#删除数据表 判断如果存在则删除
drop table if exists product2;
二、DML
1. DML新增表数据
#向product表添加一条数据
insert into product (id,name,price,stock,insert_time) values(1,'手机',199.9,25,'2020-02-02');
#向product表添加指定列数据
insert into product(id,name,price) values (2,'电脑',399.65);
#给全部列添加数据
insert into product values(3,'电话',18.5,56,'2023-06-05');
#批量添加数据
insert into product values(4,'电话4',18.5,56,'2023-06-05'),(5,'电话5',18.5,56,'2023-06-05');
2. DML 修改和删除表数据
#修改表数据
update product set price=3400 where name='电话';
#修改表数据
update product set price=1800,stock=36 where name='电脑';
#删除数据
delete from product where name='电话5';
#删除库存为10的表数据
delete from product where stock=56;
三、 DQL
1. DQL 表数据查询——查询全部
#创建数据库 db1
create database db1;
#使用db1数据库
use db1;
#创建数据表
create table product(
id int,
name varchar(20),
price double,
brand varchar(10),
stock int,
insert_time date
)
#添加数据
insert into product VALUES
(1,'华为手机',3999,'华为',23,'2088-03-10'),
(2,'小米手机',2999,'小米',30,'2088-05-15'),
(3,'苹果手机',5999,'苹果',18,'2088-08-20'),
(4,'华为手机',6999,'华为',14,'2088-06-16'),
(5,'小米手机',4999,'小米',26,'2088-07-08'),
(6,'苹果手机',8999,'苹果',15,'2088-10-25'),
(7,'联想手机',7999,'联想',NULL,'2088-11-11');
#查询全部的表数据
select * from product;
#查询指定字段表的数据
select name,price,brand from product;
#查询去重后的数据
select DISTINCT brand from product;
#简单运算 查询商品名称和库存,库存数量在原有基础上+10,如果某一列为null,使用ifnull替换
select name,stock+10 from product;
#ifnull替换的使用
select name,IFNULL(stock,0)+10 from product;
#起别名查询
select name 商品名,IFNULL(stock,0)+10 库存 from product;
2. DQL 表数据查询 ——条件查询
#查询库存大于20的商品信息
select * from product where stock>20;
#查询品牌为华为的商品信息
select * from product where brand='华为';
#查询金额在4000-6000之间的商品信息
select * from product where price BETWEEN 4000 and 6000;
select * from product where price >=4000 and price<=6000;
#查询库存为14.30.23的商品信息
select * from product where stock in(14,30,23);
select * from product where stock=14 or stock=30 or stock=23;
#查询库存为null的商品信息
select * from product where stock is null;
#查询库存不为null的商品信息
select * from product where stock is not null;
#查询名称以小米为开头的商品信息
select * from product where name like '小米%';
#查询名称第二个字是为的商品信息
select * from product where name like '_为%';
#查询名称为四个字符的商品信息
select * from product where name like '____';
#查询名称中包含电脑的商品信息
select * from product where name like '%小米%';
3. DQL 表数据的查询——聚合函数查询
#计算product表中总记录条数
select count(*) from product;
#获取最高价格
select max(price) from product;
#获取最低库存
select min(stock) from product;
# 获取总库存数
select sum(stock) from product;
#获取品牌为苹果的总库存数量
select sum(stock) from product where brand='苹果';
#获取品牌为小米的平均商品价格
select avg(price) from product where brand='小米';
4. DQL 表数据的查询——排序查询
#按照库存升序排序
select * from product order by stock asc;
#查询名称中包含手机的商品信息。按照金额降序排序
select * from product where name like '%手机%' order by price desc;
#按照金额升序排序,如果金额相同,按照库存降序排列
select * from product order by price asc ,stock desc;
5. DQL 表数据的查询——分组查询
#按照品牌分组,获取每组商品的总金额
select brand,sum(price) from product group by brand;
#对于金额大于4000元的商品,按照品牌分组,获取每组商品的总金额
select brand,sum(price) from product where price>4000 group by brand ;
#对于金额大于4000元的商品,按照品牌分组,获取每组商品的总金额,只显示总金额大于7000元的
select brand,sum(price) getsum from product where price>4000 group by brand having getsum>7000;
#对于金额大于4000元的商品,按照品牌分组,获取每组商品的总金额,只显示总金额大于7000元的,并且按照总金额降序
select brand,sum(price) getsum from product where price>4000 group by brand having getsum>7000 order by getsum desc;
5. DQL 表数据的查询——分页查询
# limit 当前页数,每页显示的条数
#公式:当前页数=(当前页数-1)*每页显示的条数
#每页显示3条数据 第1页 当前页数=(1-1)*3
select * from product limit 0,3;
#每页显示3条数据 第2页 当前页数=(2-1)*3
select * from product limit 3,3;
#每页显示3条数据 第3页 当前页数=(3-1)*3
select * from product limit 6,3;
四、 约束
1. 约束的介绍
2. 主键约束
#创建学生表(编号,姓名,年龄) 编号为主键
create table student (
id int primary key,
name varchar(30),
age int
);
#查询学生表详细信息
desc student;
#添加数据
insert into student values(1,'张三',12)
#删除主键
alter table student drop PRIMARY key;
#建表后单独添加主键约束
alter table student modify id int PRIMARY key;
3. 主键自增约束
#创建学生表(编号,姓名,年龄) 编号为主键并且自增
CREATE TABLE stu ( id INT PRIMARY KEY auto_increment, NAME VARCHAR ( 20 ), age INT );
#查看学生表详细信息
desc stu;
#添加数据
insert into stu values(null,'张三',5);
insert into stu values(null,'张三',5);
#删除自增约束
alter table stu modify id int;
#建表后单独添加自增约束
alter table stu modify id int auto_increment;
4. 唯一约束
#创建学生表(编号,姓名,年龄) 编号为主键并且自增
create table stu1(
id int PRIMARY KEY auto_increment,
name VARCHAR(50),
age int unique
);
#查看学生表的详细信息
desc stu1;
#添加数据
insert into stu1 values(null,'张三',25);
insert into stu1 values(null,'张三',26);
#删除唯一约束
alter table stu1 drop index age;
#单独添加唯一约束
alter table stu1 MODIFY age int unique;
5. 非空约束
#创建学生表(编号,姓名,年龄) 编号为主键并且自增,姓名设为非空,年龄设置为唯一
create table stu2 (
id int primary key auto_increment,
name varchar(50) not null,
age int unique
);
#查看学生表详细信息
desc stu2;
#添加数据
insert into stu2 values (null,'设置',23);
#删除非空约束
alter table stu2 modify name varchar(20);
#建表后单独添加非空约束
alter table stu2 modify name varchar(30) not null;
6. 外键约束
#创建用户表
create table user(
id int primary key auto_increment,
name varchar(20) not null
);
#添加数据
insert into user values(null,'张三'),(null,'李四');
#创建订单表
create table orderlist(
id int primary key auto_increment,
number varchar(20) not null,
uid int,
CONSTRAINT ou_fk1 FOREIGN key (uid) REFERENCES user(id)
);
#添加订单数据
insert into orderlist values (null,'hm001',1),(null,'hm002',1),(null,'hm003',2),(null,'hm004',2);
#查看表信息
desc orderlist;
#添加一个订单,但是没有真实用户 因为没有3号用户所以添加
insert into orderlist values (null,'hm005',3);
#删除李四用户 删除失败 因为需要先删除关联表信息
delete from user where name='李四';
#删除外键约束
alter table orderlist drop FOREIGN key ou_fk1;
#创建表之后单独创建外键约束
alter table orderlist add CONSTRAINT ou_fk1 FOREIGN key (uid) REFERENCES user(id);
7. 外键的级联更新和级联删除
#添加级联更新
#添加级联删除
#删除外键约束
alter table orderlist drop FOREIGN key ou_fk1;
#添加外键约束,同时添加级联更新和级联删除
alter table orderlist add CONSTRAINT ou_fk1 FOREIGN key (uid) REFERENCES user(id)
on update cascade on DELETE cascade;
#将李四这个用户id改为3 所属订单也会改变 级联更新
update user set id=3 where name='李四';
#将李四用户删除,所属订单也会删除 级联删除
delete from user where name='李四';
五、多表操作
Ⅰ. 一对一
#创建person表
create table person(
id int primary key auto_increment,
name varchar(20)
);
#添加数据
insert into person values(null,'张三'),(null,'李四');
#创建card表
create table card(
id int primary key auto_increment,
number varchar(20) unique not null,
pid int unique,
constraint cp_fk1 foreign key (pid) REFERENCES person(id)
);
#添加数据
insert into card values (null,'1234565',1),(null,'12565',2);
Ⅱ. 一对多
create table user(
id int primary key auto_increment,
name varchar(20) not null
);
#添加数据
insert into user values(null,'张三'),(null,'李四');
#创建订单表
create table orderlist(
id int primary key auto_increment,
number varchar(20) not null,
uid int,
CONSTRAINT ou_fk1 FOREIGN key (uid) REFERENCES user(id)
);
#添加订单数据
insert into orderlist values (null,'hm001',1),(null,'hm002',1),(null,'hm003',2),(null,'hm004',2);
#查看表信息
desc orderlist;
#
Ⅲ. 多对多
需要中间表
#创建学生表
create table student (
id int primary key auto_increment,
name varchar(20)
);
#添加数据
insert into student values (null,'李四'),(null,'张三');
#创建course表
create table course(
id int primary key auto_increment,
name varchar(10)
);
#添加数据
insert into course values (null,'语文'),(null,'数学');
#常见中间表
create table stu_course(
id int primary key auto_increment,
sid int,
cid int,
constraint sc_fk1 FOREIGN key (sid) REFERENCES student(id),
constraint sc_fk2 FOREIGN key (cid) REFERENCES course(id)
);
#添加数据
insert into stu_course values(null,1,1),(null,1,2),(null,2,1),(null,2,2);
1. 多表查询_数据准备
#创建db4数据库
create database db4;
#使用db4
use db4;
#创建user表
create table user(
id int primary key auto_increment,
name varchar(20),
age int
);
#添加数据
insert into user values(null,'张三',23),(null,'李四',24),(null,'王五',25),(null,'赵六',26);
#创建订单表
create table orderlist(
id int primary key auto_increment,
number varchar(30),
uid int,
constraint ou_fk1 FOREIGN key (uid) REFERENCES user(id)
);
#添加数据
insert into orderlist values(null,'hm001',1);
insert into orderlist values(null,'hm002',1);
insert into orderlist values(null,'hm003',2);
insert into orderlist values(null,'hm004',2);
insert into orderlist values(null,'hm005',3);
insert into orderlist values(null,'hm006',3);
insert into orderlist values(null,'hm007',null);
#创建商品分类表
create table category(
id int PRIMARY key auto_increment,
name varchar(10)
);
#添加数据
insert into category values (1,'手机数码');
insert into category values (2,'电脑办公');
insert into category values (3,'烟酒茶糖');
insert into category values (4,'鞋靴箱包');
#创建商品表
create table product(
id int primary key auto_increment,
name varchar(30),
cid int ,
CONSTRAINT cp_fk1 FOREIGN key (cid) REFERENCES category(id)
);
#添加数据
insert into product values(1,'华为手机',1);
insert into product values(2,'小米手机',1);
insert into product values(3,'联想电脑',2);
insert into product values(4,'苹果电脑',2);
insert into product values(5,'中华香烟',3);
insert into product values(6,'玉溪香烟',3);
insert into product values(7,'计生用品',null);
#多对多关系创建 中间表 user and product
create table us_pro(
upid int primary key auto_increment,
uid int,
pid int ,
CONSTRAINT up_fk1 FOREIGN key (uid) REFERENCES user(id),
CONSTRAINT up_fk2 FOREIGN key (pid) REFERENCES product(id)
);
#添加数据
insert into us_pro values (null,1,1);
insert into us_pro values (null,1,2);
insert into us_pro values (null,1,3);
insert into us_pro values (null,1,4);
insert into us_pro values (null,1,5);
insert into us_pro values (null,1,6);
insert into us_pro values (null,1,7);
insert into us_pro values (null,2,1);
insert into us_pro values (null,2,2);
insert into us_pro values (null,2,3);
insert into us_pro values (null,2,4);
insert into us_pro values (null,2,5);
insert into us_pro values (null,2,6);
insert into us_pro values (null,2,7);
insert into us_pro values (null,3,1);
insert into us_pro values (null,3,2);
insert into us_pro values (null,3,3);
insert into us_pro values (null,3,4);
insert into us_pro values (null,3,5);
insert into us_pro values (null,3,6);
insert into us_pro values (null,3,7);
insert into us_pro values (null,4,1);
insert into us_pro values (null,4,2);
insert into us_pro values (null,4,3);
insert into us_pro values (null,4,4);
insert into us_pro values (null,4,5);
insert into us_pro values (null,4,6);
insert into us_pro values (null,4,7);
1.1 内连接
#显式内连接
#查询用户信息和对应的订单信息
select * from user u join orderlist o on u.id=o.uid
#查询用户姓名,年龄和订单编号
select u.NAME name ,u.age,o.number from user u join orderlist o on u.id=o.uid
#隐式内连接
select u.NAME name ,u.age,o.number from user u,orderlist o where u.id=o.uid
1.2 外连接
1.2.1 左外连接
#左外连接
#查询用户的所有信息以及用户对应的订单信息
select * from user u left join orderlist o on u.id=o.uid
#右外连接
#查询订单的所有信息以及订单对应的用户信息
select * from user u right join orderlist o on u.id=o.uid
1.2.2 右外连接
#左外连接
#查询用户的所有信息以及用户对应的订单信息
select * from user u left join orderlist o on u.id=o.uid
#右外连接
#查询订单的所有信息以及订单对应的用户信息
select * from user u right join orderlist o on u.id=o.uid
1.3 子查询
1.3.1 结果为单行单列
#查询年龄最高的用户
#使用的子查询查询数据是单行的
#eg:select max(age),name from user;此时查询出的姓名并不能对应年龄最大的年龄的人的姓名,是根据聚合数据信息来展示的
#可以改为:
select name,age from user where age=(select max(age) from user);
1.3.2 结果为多行单列
#查询张三和李四的订单信息
#使用的子查询查询数据是多行单列
select u.name,o.number from orderlist o join `user` u on o.uid=u.id
where name in(select name from user where name in('张三','李四'))
#简单版本
select * from orderlist where uid in(select id from user where name in('张三','李四'))
1.3.3 结果为多行多列
#查询订单表中id大于4的订单信息和所属用户信息
#使用的子查询查询数据是多行多列的
select * from orderlist where id>4
select o.id,u.name,o.number from user u,(select * from orderlist where id>4) o where u.id=o.uid
1.4 自关联查询
六、 视图
1. 视图创建和查询
create view city_country(city_id,city_name,country_name) as
select c1.cid,c1.`name`,c2.`name` from city c1,country c2 where c1.cid=c2.id;
select * from city_country;
2. 视图的修改和删除
#将视图中的深圳改为北京
update city_country set city_name='北京' where city_name='深圳';
#修改视图数据会把原来的表数据也更变
alter view city_country (city_id,city_name,name) as
select c1.cid,c1.`name`,c2.`name` from city c1,country c2 where c1.cid=c2.id
#删除视图
drop view if EXISTS city_country
七、数据库的备份和恢复
1. Linux 备份案例 命令行
2. 右键数据库 转存sql文件即可
八、存储过程和函数
1. 存储过程的创建和调用
create database db6;
use db6;
create table student(
id int PRIMARY key auto_increment,
name varchar(20),
age int ,
gender varchar(5),
score int
);
insert into student values (null,'张三',23,'男',95),(null,'李四',24,'男',98),(null,'王五',25,'女',100),(null,'赵六',26,'女',90);
select * from student;
#按照性别进行分组,查询每组学生的总成绩,按照总成绩的升序排序
select gender,sum(score) total from student group by gender order by total asc;
#创建stu_group()存储过程,封装 分组查询总成绩,并按照总成绩升序排序的功能
DELIMITER $
create procedure stu_group()
begin
select gender,sum(score) total from student group by gender order by total asc;
end $
DELIMITER;
#调用存储过程
call stu_group();
2. 存储过程的查看和删除
#查看数据库所有存储过程
select * from mysql.proc where db='db6'
#删除存过程
drop procedure if exists stu_group;
3. 变量的使用&if语句的使用
3.1 变量
#定义一个int类型的变量 并且 赋值为10
delimiter $
create procedure pro_test1()
begin
-- 定义变量
DECLARE num int default 10;
-- 使用变量
select num;
end$
delimiter ;
#调用存储过程
call pro_test1();
#变量赋值方式一
delimiter $
create procedure pro_test2()
begin
DECLARE name varchar(10);
set name='存储过程';
select name;
end$
delimiter ;
#调用pro_test2存储过程
call pro_test2();
#变量赋值方式二
#定义两个int变量用于存储难女同学的总分数
delimiter $
create procedure pro_test3()
begin
-- 定义两个变量
DECLARE men,women int ;
-- 查询男同学的总分数 为men赋值
select sum(score) into men from student where gender='男';
select sum(score) into women from student where gender='女';
select men,women;
end$
delimiter ;
#调用pro_test3存储过程
call pro_test3();
3.2 if使用
#定义一个int变量 用于存储班级总成绩;定义一个varchar变量用于存储分数描述,根据总成绩判断,380分及以上为学习优秀,320-380之间为学习不错,320以下为学习一般
delimiter $
create procedure pro_test4()
begin
-- 定义变量
declare total int;
declare info varchar(10);
-- 查询总成绩 为total赋值
select sum(score) into total from student;
-- 对成绩做判断
if total >380 then set info='学习优秀';
elseif total>=320 and total<=380 then set info ='学习不错';
else set info ='学习一般';
end if;
select total,info;
end$
delimiter ;
#调用存储过程
call pro_test4();
4. 参数传递
#输入总成绩变量,代表学生总成绩 输出分数描述变量 代表学生纵横及的描述信息 根据总成绩判断
delimiter $
create procedure pro_test5(in total int ,out info varchar(10))
begin
-- 对纵横的判断
if total >380 then set info='学习优秀';
elseif total>=320 and total<=380 then set info ='学习不错';
else set info ='学习一般';
end if;
end$
delimiter ;
#调用存储过程
call pro_test5(select sum(score) from student,@info);
select @info;
5. while循环
#使用while循环 初始化语句 计算1-100之间的偶数和
delimiter $
create procedure protest6()
begin
-- 定义求和变量
DECLARE result int DEFAULT 0;
-- 定义初始化变量
DECLARE num int DEFAULT 1;
-- while循环
while num<=100 do
if num%2=0 then set result=result+num;
end if;
set num=num+1;
end while;
-- 查询结构
select result;
end$
delimiter ;
#调用存储过程
call protest6();
6. 存储函数
#创建存储函数
#定义存储函数 获取学生表中成绩大于95分的学生数量
delimiter $
create FUNCTION test1()
RETURNS int
begin
-- 定义个变量
DECLARE count int;
-- 查询成绩大于95分的数量赋值给count
select count(*) into count from student where score>95;
return count;
end$
delimiter ;
#调用函数
select test1();
#删除函数
drop FUNCTION test1;
九、触发器
1. insert型触发器
create DATABASE db7;
use db7;
create table account(
id int PRIMARY key auto_increment,
name varchar(20),
money double
)
insert into account values (null,'张三',1000),(null,'李四',1000);
#创建触发器 日志记录表
create table accountlog(
id int PRIMARY key auto_increment,
operation varchar(20),
operation_time datetime,
operation_id int,
operation_params varchar(200)
);
#创建insert形触发器
delimiter $
create TRIGGER account_insert
after insert
on account
for each row
begin
insert into accountlog values (null,'insert',now(),new.id,concat('插入后{id=',new.id,',name=',new.name,',money=',new.money,'}'));
end$
delimiter ;
#向account中插入一条记录
insert into account values(null,'王五',2000);
select * from account;
select * from accountlog;
2. update 型触发器
#创建update形触发器
delimiter $
create TRIGGER account_update
after update
on account
for each row
begin
insert into accountlog values (null,'update',now(),new.id,concat('更新前{id=',new.id,',name=',new.name,',money=',new.money,'}'));
end$
delimiter ;
#修改account表中李四的金额为2000
update account set money=2000 where name='李四'
insert into account values(null,'王五',2000);
select * from account;
select * from accountlog;
3. delete 型触发器
#创建delete形触发器
delimiter $
create TRIGGER account_deletes
after delete
on account
for each row
begin
insert into accountlog values (null,'delete',now(),old.id,concat('删除前{id=',old.id,',name=',old.name,',money=',old.money,'}'));
end$
delimiter ;
#删除account中的王五
delete from account where id=2;
select * from account;
select * from accountlog;
4. 触发器的操作
#查看触发器
show TRIGGERs
#删除触发器
drop trigger account_delete
十、事物
1. 事物的介绍![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d26aa35167e3b13eaf7a42deb3161b31.png)
2. 事务的基本使用
create database db8;
use db8;
create table account (
id int primary key auto_increment,
name varchar(20),
money double
);
insert into account values(null,'张三',1000),(null,'李四',1000);
#使用事务
start TRANSACTION
# 张三给李四转账500
#1.给张三见-减500源
update account set money=money-500 where name='张三';
#2.给李四账户+500
update account set money=money+500 where name='李四';
#回滚事务
ROLLBACK;
#提交事务
commit
3. 事务的提交方式
#查询事务的提交方式 1为自动提交0为手动提交
select @@autocommit;
#修改事务的提交方式
set @@autocommit=1;
#修改事务提交方式为手动时 修改语句操作要手动提交事务 commit
4. 事务的四大特征
5. 事务的隔离级别
#查询事务的隔离级别
select @@tx_isolation;
#修改事务的隔离级别(修改后需要重新连接)
set GLOBAL TRANSACTION ISOLATION level read COMMITTED;
6. 各种隔离级别引发问题的理解
- 脏读: 在一个事务当中读取到了另一个事务未提交的数据;解决办法 修改隔离级别为read COMMITTED;
- 不可重复读:在一个事务中读取到了另一个事务已经提交的数据; 解决办法 修改隔离级别为repeatable read;
- 幻读: 两种情况:(1)查询数据不存在,插入数据发现已经存在插入失败。(2)查询数据不存在,执行删除,却删除执行成功。 解决办法 修改隔离级别为 serializable
十一、 存储引擎
1. 存储引擎介绍
2. 存储引擎的操作
#mysql支持的引擎
show engines;
#查询数据库所有数据表的存储引擎
show table status from db8;
#查询指定数据库中数据表的存储引擎
show table status from db8 where name='account'
#创建数据库表可以指定存储引擎
create table db9(
id int PRIMARY key auto_increment,
name varchar(20)
) ENGINE=myisam;
#修改数据表的存储引擎
alter table db9 engine=INNODB;
3. 存储引擎选择
十二 、索引
1. 索引介绍
有无索引效率会很受影响
2. 索引的操作
#为account表中的name列创建一个普通索引
create index idx_name on account(name);
#为account表中的money列创建一个普通索引
create unique index idx_money on account(money);
#查看索引
show index from account;
#存在外键也会和主键列一样 自带主键和外键索引
3. 索引的原理
BTree:在每一个结点上,除了保存键值外,还要保存真实的数据。
B+Tree:在分支结点上只保存键值不保存数据,所有真实的数据只保存在叶子节点上,较少了IO的次数。
4. 索引的设计原则
组合索引:
十三、 锁
1. 锁的介绍
2. 共享锁和排他锁
数据库上的操作可以归纳为两种:读和写。
多个事务同时读取一个对象的时候,是不会有冲突的。同时读和写,或者同时写才会产生冲突。因此为了提高数据库的并发性能,通常会定义两种锁:共享锁和排它锁。
2.1 共享锁
对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源(也可以再继续加共享锁,即 共享锁可多个共存),但无法修改。要想修改就必须等所有共享锁都释放完之后。
实际情况:
如果T1和T2都是执行的查询,也就是都加共享锁
这时候就不用等待,可以立马执行
因为同一资源上可以同时存在多个共享锁,也被称为,共享锁与共享锁兼容
意味着共享锁不阻止其他人同时读取资源,但是阻止其他人修改资源
T1: select * from table lock in share mode
T2: select * from table lock in share mode
2.2 排他锁
对某一资源加排他锁,自身可以进行增删改查,其他人无法进行任何操作。
实际情况:
这里我们以两个操作数据库的请求为例,假设这两个请求分别为T1和T2
假设T1为查询请求,而T2为更新数据请求,在T1查询很长时间的时候,还没有返回结果,但是这时候T2过来请求更新了
这个流程应该是: T1运行加共享锁、T2运行、发现T1未完成等待其完成、T1完成、T2开始执行
T2之所以要等待,是因为T2执行更新的时候需要给表加排他锁,但是数据库规定,不能在同一资源上同时共存这两种锁,所以T2必须等T1执行完,释放锁后,才可以正常操作
//共享锁
select * from 表名 lock in share mode
//排他锁
select * from 表名 for update