MySQL学习笔记(基础入门篇)

MySQL学习笔记(基础篇)

SQL

  • SQL通用语法

1、SQL可以单行或多行书写,以分号结尾

2、SQL可以用空格/缩进来增强语句可读性

3、MySQL数据库的SQL语句不区分大小写,关键字建议用大小写

4、单行注释–或#,多行注释/* */

  • SQL分类

1、DDL—数据定义语言,定义对象

2、DML—数据操作语言,对数据增删改

3、DQL—数据查询语言,查询表的记录

4、DCL—数据控制语言,创建用户、控制访问权限

DDL

  • DDL-数据库操作
查询所有数据库
show databases;

查询当前数据库
select database();

创建
create database [if not exists] 数据库名;

删除
drop database [if exists] 数据库名;

使用
use 数据库名;
  • 创建表

在这里插入图片描述

几个注意的点:1、创建字符串类型用varchar(num) 2、comment 之后为注释,可写可不写 3、最后一个字段没有括号4、逗号和分号都要是英文输入5、单词一定不能打错比如create和comment

只要错一个点,表就建立不起来

  • DDL-表操作-查询
查询当前数据库所有表
show tables;

查询表结构
desc 表名;

查询指定表的建表
show create table 表名;
  • DDL-表操作-修改
添加字段
alter table 表名 add 字段名 类型 [comment][约束];

修改数据类型
alter table 表名 modify 字段名 新数据类型;

修改字段名和字段类型
alter table 表名 change 旧字段名 新字段名 新类型;

删除字段
alter table 表名 drop 字段名;

修改表名
alter table 表名 rename to 新表名
  • DDL-表操作-删除
删除表,全部删除
drop table [if exists] 表名;

删除指定表,并重新创建该表,只删数据
truncate table 表名;

DML

  • DML-添加数据
给指定字段添加数据
insert into 表名(字段名1,字段名2...) values(1,值2...);
    
给全部字段添加数据
insert into 表名 values(1,值2...);

批量添加数据
insert into 表名(字段1,字段2...) values(1,值2...),(1,值2...);

insert into 表名 values(1,值2...),(1,值2...);

注意:

1、插入数据时,指定的字段顺序需要与值的顺序时一一对应的

2、字符串和日期型数据应该包含在单引号中

3、插入的数据大小,应该在字段的规定范围内

  • DML-修改数据
update 表名 set 字段1=1,字段2=2,...[where 条件]

条件可以有,也可以没有,如果没有条件,则修改整张表所有数据

  • DML-删除数据
delete from 表名 [where 条件]

注意:

1、条件可有可无,如果没有条件,则删除整张表所有数据

2、delete不能删除某一个字段的值(可以使用update)

DQL

  • DQL-基本查询
查询多个字段
select 字段1,字段2,... from 表名;
select * from 表名;

设置别名
select 字段1[as 别名1],... from 表名;

去除重复记录
select distinct 字段列表 from 表名;
  • 条件查询
select 字段列表 from 表名 where 条件列表;

在这里插入图片描述

  • DQL-聚合函数
select 聚合函数(字段列表) from 表名;

常见聚合函数
count--->统计数量
max--->最大值
min--->最小值
avg--->平均值
sum--->求和

null值不参与所有聚合函数的运算的
  • DQL-分组查询
select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];

where 与having的区别:

1、执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤

2、判断条件不同:where不能对聚合函数进行判断,而having可以

  • DQL-排序查询
select 字段列表 from 表名 order by 字段1 排序方式1, 字段2 排序方式2;

排序方式:
ASC:升序(默认值)
DESC:降序

注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序
  • DQL-分页查询
select 字段列表 from 表名 limit 起始索引,查询记录数

注意:

  • 起始索引从0开始,起始索引=(查询页码-1)*每页显示记录数
  • 分页查询是数据库方言,不同数据库有不同实现语法
  • 如果查询的是第一页数据,起始索引可以省略,可简写为limit 10
  • DQL-执行顺序

from->where->(group by->)select->order by->limit

DCL

  • DCL-管理用户
查询用户
use mysql;
select * from user;

创建用户
create user '用户名'@'主机名' identified by '密码';

修改用户密码
alter user '用户名'@'主机名' identified with mysql_native_password by '新密码'

删除用户
drop user '用户名'@'主机名';
  • DCL-权限控制
查询权限
show grants for '用户名'@'主机名';

授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';

撤销权限
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';

函数

  • 字符串函数
字符串拼接,将s1,s2,...sn拼接成一个字符串
concat(s1,s2,...sn)

将字符串str全部转为小写
lower(str)  

将字符串str全部转为大写
upper(str)

左填充,用字符串pad对str左边进行填充,达到n个字符串长度
lpad(str, n, pad)

右填充,用字符串pad对str右边进行填充,达到n个字符串长度
rpad(str, n, pad)

去掉字符串头部和尾部的空格
trim(str)

返回字符串str从start位置起的len个长度的字符串
substring(str, start, len)

练习

由于业务需求变更,企业员工工号统一为5位数,目前不足5位数的全部在前面补0.比如:1号员工的工号应该为00001

update emp set workno = lpad(workno, 5, '0');
  • 数值函数
向上取整
ceil(x)

向下取整
floor(x)

返回x/y的模
mod(x, y)

返回0-1内的随机数
rand()

求参数x的四舍五入的值,保留y位小数
round(x, y)

练习

生成一个六位数随机验证码

select lpad(round(rand()*1000000, 0), 6, '0');
  • 日期函数
返回当前日期
curdate()

返回当前时间
curtime()

返回当前日期和时间
now()

获取指定date的年份
year(date)

获取指定date的月份
month(date)

获取指定date的日期
day(date)

返回一个日期/时间值加上一个时间间隔expr后的时间值,expr可正可负
date_add(date, interval expr type)

返回起始时间date1和结束时间date2之间的天数
datediff(date1,date2)

练习

查询所有员工的入职天数,并根据入职天数倒叙排序

select name , datediff(curdate(), entrydate) as count from emp order by count desc ;
  • 流程函数
如果valuetrue,则返回t,否则返回f
if(value, t, f)

如果value1不为空,返回value1,否则返回value2
ifnull(value1, value2)

如果val1为true,返回res1,否则返回default默认值
case when [val1] then [res1]...else[default] end

如果expr的值等于val1,返回res1,否则返回default默认值
case[expr] when [val1] then [res1] .. else[default] end

练习

1、查询emp表员工姓名和工作地址 内蒙/新疆–>一线城市 其他–>二线城市

select
    name,
    (case workaddress when '内蒙' then '一线城市' when '新疆' then '一线城市' else '二线城市' end) as '工作地址'
from emp;

2、统计班级各个学员成绩>=85为优秀 >=60为及格

select id,
       name,
       (case when math >= 85 then '优秀' when math >= 60 then '及格' else '不及格' end) as 数学,
       (case when English >= 85 then '优秀' when English >= 60 then '及格' else '不及格' end) as 英语,
       (case when Chinese >= 85 then '优秀' when Chinese >= 60 then '及格' else '不及格' end) as 语文
from score;

注意两个函数的使用,存在细微差别。第一个是判断确切的某个值,而第二个是判断其范围在什么位置

约束

  • 分类
非空约束
not null

唯一约束
unique

主键约束
primary key

自增约束
auro_increment

默认约束
default

检查约束
check

外键约束
foreign key

创建案例

create table user(
    id int primary key  auto_increment comment '主键',
    name varchar(10) not null unique comment '姓名',
    age int check ( age > 0 && age <= 120 ) comment '年龄',
    status char(1) default '1' comment '状态',
    gender char(1) comment '性别'
) comment '用户表';

多表查询

select * from emp, dept where emp.dept_id = dept.id;
  • 内连接(查询两表交集部分)
隐式内连接
select 字段列表 from1,表2 where 条件;

显示内连接
select 字段列表 from1 [inner] join2 on 连接条件;

练习

查询每一个员工的姓名,及关联部门的名称分别用隐式和显示内连接

select emp.name, dept.name from emp, dept where emp.dept_id = dept.id;

select emp.name, dept.name from emp join dept on emp.dept_id = dept.id;
  • 外连接
左外连接用left 右外连接用right
select 字段列表 from1 left/right [outer] join2 on 条件;

练习

查询emp所有数据和对应部门姓名

select emp.*, dept.name from emp left join dept on emp.dept_id = dept.id;
  • 自连接

练习

1、查询员工及其所属领导的名字(用内连接)

select a.name, b.name from emp a, emp b where a.managerid = b.id;

2、查询所有员工emp及其领导名字emp,如果员工没有领导,也需要查询出来(用外连接)

select a.name '员工' b.name '领导' from emp a left join emp b on a.managerid = b.id;

注意:在资连接的时候一定要给字段列表起别名,否则区别不了。

  • 联合查询-union,union all
select * from emp where id > 10
union [all]
select * from emp where gender = 'M';

按顺序输出两张表,无all关键字表示去重,有all则只要是符合条件的全部显示

注意:上表和下表查询的列数一定要一致

  • 子查询

    • 标量子查询(子查询返回单个值)

    练习

    1、根据研发部的id 查询员工信息

    select * from emp where dept_id = (select id from dept where name = '研发部');
    
    理解不了可以拆分成两部分来写再最后进行合并
    1select id from dept where name = '研发部';--->显示结果为3
    
    2select * from emp where dept_id = 3;--->显示研发部员工信息
    
    最后将第一步的整体将第二部的3整体替换,并且要加上括号!
    

    2、查询在dyt(2000-01-05)之后的员工信息

    select * from emp where entrydate > (select entrydate from emp where name = 'dyt');
    
    • 列子查询(子查询返回一列)

    常用操作符:IN、NOT IN、ANY、SOME、ALL

    在这里插入图片描述

练习

1、查询销售部和市场部的所有员工信息

select * from emp where dept_id in(select id from emp where name = '市场部' or name = '销售部');

2、查询比财务部所有人年龄都高的员工信息

select * from emp where age > all(select age from emp where dept_id = (select id from dept where name = '财务部'));

3、比研发部其中任意一人年龄高的员工信息

select * from emp where age > any(select age from emp where dept_id = (select id from dept where name = '研发部'));
    • 行子查询(子查询返回一行)

    练习

    查询与wf的工作地点和性别相同的员工信息

    select * from emp where (gender, workaddress) = (select gender, workaddress from emp where name = 'wf');
    
    • 表子查询

    练习

    1、查询与wf、htf工作地点和性别相同的员工信息

    select * from emp where (gender, workaddress) = (select gender, workaddress from emp where name = 'wf' || name = 'htf');
    

    2、查询入职日期是2000-01-10之后的员工信息,及其部门信息

    select e.*, dept.* from (select * from emp where entrydate > '2000-01-10') e left join dept on e.dept_id = dept.id;
    
  • 多表查询案例

1、查询员工的姓名、年龄、性别、部门信息(隐式内连接)

select e.name, e.age, e.gender, d.name from emp e, dept d where e.dept_id = d.id;

2、查询年龄小于30的员工的姓名、年龄、性别、部门信息(显示内连接)

select e.name, e.age, e.gender, d.name from emp e join dept d on e.dept_id = d.id where e.age < 30;

3、查询拥有员工的部门ID、部门名称

select distinct d.id, d.name from emp e, dept d where e.dpet_id = d.id;-- 使用distinct关键字起到去重的作用

4、查询所有小于40的员工,及其归属部门名称;如果没有分配部门也要展示

select e.*, d.name from emp e left join dept d on e.dept_id = d.id where e.age < 40;-- 使用左外连接,显示包括所有的左表数据

5、查询所有员工表年龄等级

select e.*, a.grade from emp e, agegrade a where e.age >= a.loage && e.age <= a.hiage

-- 或者这样写

select e.*, a.grade from emp e, agegrade a where e.age between a.loage and a.hiage;

6、查询研发部所有员工的信息及年龄等级

select e.*, a.grade from emp e, dept d, agegrade a where e.dept_id = d.id && (e.age between a.loage and a.hiage) && e.name = '研发部';
-- 使用隐式内连接方式,多个条件写在where中,多个条件用与符号相关联

7、查询研发部员工的平均年龄

select avg(e.age) from emp e, dept d where e.dept_id = d.id && d.name =  '研发部';

8、查询年龄比lzl高的员工信息

select * from emp where age > (select age from emp where name = 'lzl');

9、查询比平均年龄高的员工信息

select * from emp where age > (select avg(age) from emp);

10、查询比本部门平均年龄低的员工信息

select * from emp e2 where e2.age < (select avg(e1.age) from emp e1 where e1.dept_id = e2.dept_id);

11、查询所有部门信息,统计部门的员工人数

select * , (select count(*) from emp where emp.dept_id = dept.id) '人数' from dept;

12、查询所有学生的选课情况,展示出学生名称,学号,课程名称

select s.name, s.no, c.name from student s, student_course sc, course c where s.id = sc.studentid && sc.courseid = c.id;

事务

  • 数据准备
create table account(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '姓名',
    money int comment '余额'
) comment '账户表';
insert into account(id, name, money) values (null, 'lzl', 2000), (null, 'xrg', 2000);
  • 事务操作

方法一

查看/设置事务提交方式
select @@autocommit; -- 默认值为1,1为自动提交
set @@autocommit = 0;
-- 程序段 ------------
update account set money = money-100 where name = 'lzl';
程序执行报错...
update account set money = money+100 where name = 'lxc';
---------------------

提交事务
commit;

回滚事务
rollback;

取消自动提交改为手动提交,执行程序段之后表中数据暂时不会改变,此时查看控制台各语句是否正常执行,如果正常执行则执行提交事务,反之则执行回滚事务。

方法二

开启事务
start transactionbegin;

-- 程序段 ------------
update account set money = money-100 where name = 'lzl';
程序执行报错...
update account set money = money+100 where name = 'lxc';
---------------------

提交事务
commit;

回滚事务
rollback;

大致过程与方法一相同,只是将设置事务方式改成了开启事务的语句,执行完程序段之后,查看控制台的语句是否正常执行。如果正常执行则执行提交事务,反之则执行回滚事务。

  • 事务四大特性ACID

1、原子性:事务时不可分割的最小操作单元,要么全部成功,要么全部失败

2、一致性:事务完成时,必须使所有的数据都保持一致状态

3、隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

4、持久性:事务一旦提交或回滚,它对数据库中的数据的改变是永久的

  • 并发事务问题(多个事务在并发的过程当中出现)

脏读:一个事务读到另外一个事务还没有提交的数据

不可重复读:一个事务先后读取同一条记录,单两次读取的数据不同

幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了幻影。

  • 事务隔离级别

在这里插入图片描述

查看事务隔离级别
select @@transaction_isolation;

设置事务隔离级别
set [session global] transaction isolation level {read uncommitted|read committed|repeatable read|serializable};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值