我的个人博客
百度搜索:【迷你酷吧】网址:,迷你酷吧是一个基于程序员经验为基础分享技术文章、算法解题、大厂面试真题、热门项目的平台,致力于为大家提供更多涵盖前后端技术、技能的学习,助力广大热衷编程开发者全面发展。
SQL分类
SQL全称为结构化查询语言(Structured Query Language);SQL语言包括4部分 DDL(Data Definition Language):数据定义语言‘DML(Data Manipulation Language):数据操纵语言DQL(Data Query Language):数据查询言语TCL(Transaction Control Language):事务控制语言DDL(Data Definition Language ):数据定义语言
DDL语言主要用于定义数据库结构,比如创建、修改、删除数据库、表结构对象。如下SQL语句:
create database(创建数据库)drop database(删除数据库)create table(创建表)drop table(删除表)alter table(增加、修改、删除表字段)create index(表上建立索引)drop index(表上删除索引)
操作Database(数据库)
注意:数据库一般是无法修改名字的,只能通过可视化工具去修改(通过新建库,把所有表复制到新的数据库,然后删除旧的数据库完成的)。
1、创建数据库
create database 数据库名 [charset 字符集];如果不指定字符集,那么默认按照mysql选择的字符集。
2、查看所有已经存在的数据库
show databases;
3、删除数据库
drop database 数据库名;
4、使用数据库
use database;
注意:要操作数据库之前必须先说明对那个数据库进行操作,除了创建数据库的操作,操作其他语言之前先声明使用那个库。
表结构操作
1、查看当前数据库的所有表
show tables;
2、创建表
create table 表名(
字段1 数据类型 [列级约束],
字段2 数据类型 [列级约束],
字段3 数据类型 [列级约束],
[表级约束],
[表级约束]
)
例子1
学生基本表
CREATE TABLE student(sno INT PRIMARY KEY NOT NULL UNIQUE AUTO_INCREMENT COMMENT '主键ID',NAME VARCHAR(20) NOT NULL COMMENT '学生姓名',major VARCHAR(20) NOT NULL COMMENT '学生专业');
学生详细信息表
CREATE TABLE stu_detail(sno INT NOT NULL UNIQUE COMMENT '学生基本表外键',cid char(18) not null comment '学生卡id',age INT COMMENT '学生年龄',address VARCHAR(50) COMMENT '学生住址',phone CHAR(11) NOT NULL COMMENT '学生号码',constraint pk_sno primary key(sno),constraint uk_cid unique (cid),constraint fk_detail_stu foreign key (sno) references student(sno));
#约束可以不需要指定名称,其中主键约束名都是“PRIMARY”
#如果要自己命名,习惯上主键约束pk_表列名,唯一键约束uk_表列名,外键约束fk_从表名_主表名_从表列名;
学生详细表信息表可以简写成:
CREATE TABLE stu_detail(sno INT NOT NULL UNIQUE COMMENT '学生基本表外键',cid char(18) not null comment '学生卡id',sid int not null comment '身份证',age INT COMMENT '学生年龄',address VARCHAR(50) COMMENT '学生住址',phone CHAR(11) NOT NULL COMMENT '学生号码',primary key(sno),unique (sid),foreign key (sno) references student (sno));
2、查看某个表的结构
desc 表名;
查看表的定义:show create teble 表名;
3、删除表
drop table if exists 表名;
drop table 表名;
注意:这样删除表,表的数据和结构都被删除,所有正在运行的相关事务都被提交,所有索引都被删除,drop table语句不能回滚。
修改表结构
1、重命名表名
alter table 旧表名 rename 新表名;
rename table 旧表名 to 新表名;
2、修改表字段(新增、删除、修改字段)
alter table 表名 add /列/约束/索引;
alter table 表名 drop /列/约束/索引;
alter table 表名 modify/change 列定义(包括列约束);
1)增加表字段
alter table 表名 add [column] 列名 数据类型;
alter table 表名 add [column] 列名 数据类型 first 表最前面;
alter table 表名 add [column] 列名 数据类型 after 表某一列名;
2)删除表字段
alter table 表名 drop [column] 列名;
3)修改表字段数据类型
alter table 表名 modify [column] 列名 数据类型;
alter table 表名 modify [column] 列名 数据类型 first;
alter table 表名 modify [column] 列名 数据类型 after 表某一列名;
4)修改字段的名字
alter table 表名 change 旧字段 新字段 数据类型 ;
示例:
create table course(id int not null primary key auto_increment,name char(50) comment '课程名称',num varchar(50) comment '课程编号');1、重命名表coursealter table course rename courses;rename table courses to course;2、新增表字段typealter table course add column type varchar(50) comment '数本类型';3、删除表字段numalter table course drop num;4、修改表字段name的数据类型为varchar(50) not null comment '课程名称';alter table course modify name varcahr(50) not null comment '课程名称';5、修改表字段name为c_name,其他不变;alter table course change name c_name varchar(50) not null comment '课程名称';
建立、删除约束和素引
1、增加主键约束
alter table 表名 [constraint 约束名] primary key (表字段名);
alter table 表名 [constraint 约束名] primary key (字段名1,字段名2);复合主键
2、新增唯一键约束
alter table 表名 add [constraint 约束名] unique [key] (字段名);
alter table 表名 add [constraint 约束名] unique [key] (字段名1,字段名2);
3、增加外键约束
alter table 表名 add [constraint 字段名] foreign key (从表字段名)
references 主表名 (主表被用于参照的字段);
4、增加、删除缺省约束和非空约束
alter table 表名 modify [column] 列名 数据类型 [default 默认值] [not null];
5、增加索引
create index [索引名称] on 表名 (要建立索引的字段);
eg:为表student的name字段建立索引index_name;
create index index_name on student (name);
6、删除索引
1)查看一个表的约束信息
如果不知道表的约束信息,可以通过一下方法查看
show create table 表名;
select * from information_schema.table_constraints where table_name = ‘表名称’;
2)查看表的索引
show index from 表名;
3)删除主键约束,不需要指定主键名,一个表只有一个主键;
alter table 表名 drop primary key;
删除主键约束也会把主键上的索引删除
4)删除唯一键(unique)约束
唯一性约束只能通过删除索引的方法删除,
alter table 表名 drop index 索引名;
5) 删除外键约束
alter table 表名 drop foreign key 约束名;
删除外键约束,不会把外键上的索引删除,需要单独删除索引
示例:
#增加主键约束alter table t_course add primary key (cno);alter table t_score add primary key (sno,cno);#增加唯一键约束alter table t_course add unique (cname);#增加外键约束alter table t_score add foreign key (sno) references t_stu(sno);alter table t_score add foreign key (cno) references t_course(cno);#删除主键约束,主键名总是PRIMARY KEYalter table t_course drop primary key;#唯一键只能通过删除索引的方式删除,默认唯一键约束名为列名alter table t_course drop index cname;#删除外键约束alter table t_score drop foreign key t_score_ibfk_1;alter table t_score drop foreign key t_score_ibfk_2;
总结:删除以上键约束和索引只能通过上面的方式删除,不能通过modify/change列来删除。
DML(Data Manipulation Language)数据操纵语言
(一)新增数据
1、不指定字段名插入数据
没有指定字段名,表示所有字段都要赋值,而且顺序要与表结构中的顺序一致,自增字段,可以写default,也可以写null,但不能省略,否则报【ERROR 1136 (21S01): Column count doesn’t match value count at row 1】
insert into student value(null,‘李斯’,‘20’);
2、指定列名
1)插入一条数据
#如果某列有默认值,则该列位置可以写default使用默认值
insert into student (name,sex,major) value(‘李四’,default,‘计算机’);
2)插入多条数据
insert into t_stu values (null,‘王五’,‘男’,‘bigdata’,‘11期’),
(null,‘赵六’,‘男’,‘bigdata’,‘11期’);
(二)修改数据
update 表名 set 字段1=新值1,字段2=新值2 … where 条件;
注意:如果不写where条件,会把所有行的字段值都修改成新值。
UPDATE student SET name = '李四', age = '25' WHERE sno = '12';
(三)删除数据
delete from 表名 where 条件;
删除整张表的数据,表结构保留:
delete from 表名;
truncate 表名;
区别:truncate相当于删除表再重建一张同名结构的表,操作后得到一张全新表,而delete是在原有表中删除数据。如果决定清空一张表的数据,truncate速度更快一些。truncate语句不能回滚。
DQL(Data Query Language)数据查询语言
DQL的查询语言是select语言,可以包含5中句子:一次是where、group by、having、order by、limit;
select (属性列表) from 表名 [where 条件] [group by 属性名 [having 条件表达式]] [order by 属性名 desc/asc][limit m,n];
1、查询所有行
select * from 表名;
2、查询部分字段
select name,age from 表名;
3、查询name = '李四’的所有属性
select * from 表名 where name = ‘李四’;
where 条件查询
(1)算术运算符:+ - * /(除也可以写成div) %(取模可以写成mod)
(2)比较运算符:= > >= < <= !=(不等于还可以写成<>)
(3)逻辑运算符:&&(逻辑与也可以写成and) ||(逻辑或也可以写成or) not(逻辑非)
(4)范围:表达式 between … and … (也可以写成 表达式>=… and 表达式 <=…)
表达式 not between … and …(也可以写成 表达式<… || 表达式 >…)
(5)集合:in (值,值,值…) not in(值,值,值…)
(6)模糊查询:LIKE NOT LIKE,通配符:%表示0-n个字符,_下划线代表一个字符
(7)位运算符:&(按位与) |(按位或) 注意:极少用,可忽略
(8)NULL值判断,is null 或 is not null,如果使用null=null,null<>null,null=0,null<>0,null=false等都不对
#选择操作的数据库USE test;#创建表格CREATE TABLE temp (id int(11),name char(20) DEFAULT NULL,sex char(1) DEFAULT NULL,age int(11) DEFAULT NULL,PRIMARY KEY (id));#插入数据INSERT INTO temp VALUES ('1', '张三', '男', '20');INSERT INTO temp VALUES ('2', '李四', '女', '18');INSERT INTO temp VALUES ('3', '张丰', '男', '0');INSERT INTO temp VALUES ('4', '王五', '男', '24');INSERT INTO temp VALUES ('5', '赵六', '女', '27');INSERT INTO temp VALUES ('6', '钱七', '男', '23');INSERT INTO temp VALUES ('7', '孙八', '男', '32');INSERT INTO temp VALUES ('8', '老九', '女', '22');INSERT INTO temp VALUES ('9', '老十', '女', '25');INSERT INTO temp VALUES ('10', null, null, null);INSERT INTO temp VALUES ('1', '2', '张三');INSERT INTO temp VALUES ('2', '0', '张三丰');INSERT INTO temp VALUES ('3', null, null);
1、查看所有数据
select id,name from temp;
2、算术运算符
select * from temp where id%2=0;
update temp set age = age+1;
3、比较运算符
select * from temp where age > 30;
4、逻辑运算符
select * from temp where age < 20 and sex = ‘男’;
5、区间范围
select * from temp where age between 20 and 30;
6、集合范围
select * from temp where age in (20,30);
7、模糊查询
select * from temp name like ‘李%’;
select * from temp name like ‘李_’;
8、null值判断
select * from temp where name is null;
group by 分组
作用:把行按照字段分组,语法:group by 字段名;
1、聚合函数:AVG(expr)
select gender,AVG(age)from temp group by gender;
2、聚合函数:COUNT(expr)
1)select count(*) from temp;–返回检索行的数目,无论是否包含null值
2)select count(name) from temp;–返回select语句检索name的非null值的数目;
3、聚合函数:MIN(expr)、MAX(expr)
select MIN(age),MAX(age) from temp;
4、聚合函数:SUM(expr)
select SUM(age) from temp;–返回字段相加的总和。
示例
#按专业统计人数select major,count(1) as "人数" from t_stu group by major;#按课程分组统计各科的平均成绩select cno,avg(score) from t_score group by cno;#求课程编号1的平均成绩select cno,avg(score) from t_score where cno=1 group by cno ;#求课程编号1,2,3的各科的平均成绩select cno,avg(score) from t_score where cno in (1,2,3) group by cno ;#按课程找出最高分,即求每科的最高分select cno,max(score) from t_score group by cno;#按课程找出最低分,即求每科的最低分select cno,min(score) from t_score group by cno;#按部门统计奖金总额,工资总额select deptno,sum(salary) as "工资总额",sum(comm) as "奖金总额" from employee group by deptno;
注意:用count(),count(1),谁好呢?
其实,对于myisam引擎的表,没有区别的.
这种引擎内部有一计数器在维护着行数.
Innodb的表,用count()直接读行数,效率很低,因为innodb真的要去数一遍。
having 筛选
having与where类似,可筛选数据
having与where不同点:
1、where针对表中的列发挥作用,查询数据;having针对查询结果中的列发挥作用,筛选数据
2、where后面不能写分组函数,而having后面可以使用分组函数
3、having只用于group by分组统计语句
select id,sum(salary) as "工资总额" from employees group by id HAVING sum(salary) > 5000;
order by 排序
1、按一个或多个字段对查询结果进行排序
用法:order by col1,col2,col3
说明:先按col1排序如果col1相同就按照col2排序,依次类推
col1,col2,col3可以是select后面的字段也可以不是
2、默认是升序,也可以在字段后面加asc显示说明是升序,desc为降序
例如:order by count desc;
如果两个字段排序不一样,例如: order by 字段1 asc ,字段2 desc;
倒序:从大到小
select id,sum(salary) as "工资总额" from myemployees.employees group by id HAVING sum(salary) > 5000 ORDER BY sum(salary) DESC;
正序:从小到大
select id,sum(salary) as "工资总额" from myemployees.employees group by id HAVING sum(salary) > 5000 ORDER BY sum(salary) ASC;
limit 分页
limit m,n
m表示从下标为m的记录开始查询,第一条记录下标为0,n表示取出n条出来,如果从m开始不够n条了,就有几条取几条。m=(page-1)*n,(page页码,n表示每页显示的条数)
第一页 limit 0,n,那么第二页 limit n,n。
TCL(Transation Control Language)事务控制语言
TCL用来控制数据库的访问,包括如下SQL语句:
1、GRANT:授予访问权限
2、REVOKE:撤销访问权限
3、COMMIT:提交事务处理
4、ROLLBACK:回滚事务
5、SAVEPOINT:设置保存点
6、LOCK:对数据库的特点部分进行锁定
事务
思考:我去银行给朋友汇款,我卡上有5000元,朋友卡上500元,我给朋友转账500元(无手续费),如果我的钱刚扣,而朋友的钱又收到,网线断了,怎么办?
事务的ACID特性:
原子性(Atomicity):原子意为最小的粒子,或者说不能再分的事物。数据库事务的不可再分的原则即为原子性。 组成事务的所有查询必须:要么全部执行,要么全部取消(就像上面的银行例子,这个事件不能再分,是一个整体)。一致性(Consistency):指数据的规则,在事务前后应保持一致。隔离性(Isolation):简单点说,某个事务的操作对其他事务不可见的。持久性(Durability):当事务提交完成后,其影响应该保留下来,不能撤消。
事务的用法:
开启事务(start transaction)执行sql操作(普通sql操作)提交 / 回滚(commit / rollback)
注意:
1)建表的时候,选择 Innodb引擎才支持事务
2)默认情况下,MySQL是自动提交事务,每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。如果某一组操作需要在一个事务中,那么需要使用start transaction,一旦rollback或commit就结束当次事务。
3)如果需要在当前会话的整个过程中都取消自动提交事务,进行手动提交事务,就需要设置set autocommit = false;或set autocommit = 0;那样的话每一句SQL都需要手动commit提交才会真正生效。rollback或commit之前的所有操作都视为一个事务。
#开启手动处理事务模式#set autocommit = false;#开始事务(推荐)start transaction;#查看当前表的数据select * from t_stu_detail;#删除整张表的数据delete from t_stu_detail;#查询该表数据,发现显示删除后的结果select * from t_stu_detail;#回滚rollback#查看当前表的数据,发现又回来了select * from t_stu_detail;#删除整张表的数据delete from t_stu_detail;#提交事务commit;#查看当前表的数据,发现真删除了select * from t_stu_detail;#开始事务begin;#插入一条记录INSERT INTO t_stu_detail VALUES (1, '123456789012345678', '1990-01-21', '12345678901', 'a@', '北七家');#保存还原点1savepoint point1;#插入一条记录INSERT INTO t_stu_detail VALUES (2, '123456789012345677', '1990-02-21', '12345678902', 'b@', '北七家');#保存还原点2savepoint point2;#查看当前效果select * from t_stu_detail;#回滚到某个还原点rollback to point1;#提交事务commit;#清空表truncate t_stu_detail;#回滚,对于truncate无法回滚rollback;#修改表结构alter table t_stu_detail add description varchar(50);#回滚,对于修改表结构的语句无法回滚rollback;
数据库的隔离级别(了解)
隔离基于MySQL8.X
对于同时运行的多个事务(多线程并发), 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题: (问题的本质就是线程安全问题,共享数据的问题)
数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题. 一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。
(一)脏读
A事务,会读取到B事务还未提交的数据。因为B事务可能会因为各种原因数据回滚,所以如果A事务读取了B未提交的数据,然后基于此进行一些业务操作,但是B事务发生错误回滚了,那A事务的业务操作就错了。
(二)不可重复读
在同一个事务生命周期内,也就是这个事务还未提交之前。如果另外一个事务,对数据进行了编辑(update)或者删除(delete)操作。那么A事务就会读取到。简单理解,就是在一个事务生命周期内,多次查询数据,每次都可能查出来的不一样。
(三)幻读
幻读的结果其实和不可重复读是一样的表现,差异就在于,不可重复读,主要是针对其他事务进行了编辑(update)和删除(delete)操作。而幻读主要是针对插入(insert)操作。也就是在一个事务生命周期内,会查询到另外一个事务新插入的数据。
锁
行锁
即操作时只会锁某一行,不对其他行有影响,适合高并发的操作。
表锁定
即使操作一条记录也会锁定整个表,不适合高并发的操作。
如果觉得《MySql基础篇之SQL语句(DDL DML DQL RCL)》对你有帮助,请点赞、收藏,并留下你的观点哦!