MySQL数据库 - 基础篇

news2024/12/27 13:23:34

本文文章基于黑马《MySQL》课程所做的笔记

1、基础篇

1.1、MySQL概述

  • 数据库相关概念

    名称全称简介
    数据库存储数据的仓库,数据是有组织的进行存储DataBase(DB)
    数据库管理系统操纵和管理数据库的大型软件DataBase Management System(DBMS)
    SQL操作关系型数据库的编程语言,定义了一套操作关系型数据库的统一标准Structured Query Language(SQL)

    数据模型:

    关系型数据库(RDBMS)

    概念:建立在关系型模型基础上,由多张表相互连接的二维表组成的数据库

1.2、SQL

1.2.1、SQL通用语法

  1. SQL语句可以单行或者多行书写,以分号结尾。
  2. SQL语句可以使用空格缩进来增强语句的可读性。
  3. MySQL数据库SQL语句不区分大小写,关键字建议使用大写。
  4. 注释:
    • 单行注释:-- 注释内容 或 # 注释内容
    • 多行注释:/* 注释内容 */

1.2.2、SQL分类

分类全称说明
DDLData Definition Language数据定义语言,用来定义数据库对象(数据库,表,字段)
DMLData Manipulate Language数据库操作语言,用来对数据库表中的数据进行增删改
DQLData Query Language数据库查询语言,用来查询数据库中表的记录
DCLData Control Language数据库控制语言,用来创建数据库用户,控制数据库的访问权限

1.2.3、DDL

1、DDL-操作数据库
  • 查询

    • 查询所有数据库

      show database;

    • 查询当前处于哪个数据库之中

      select database();

  • 创建

create database [if not exists] 数据库名称 [default charset 字符集][collate 排序规则]
  • 删除
drop database [if exists] 数据库名称;
  • 使用
use 数据库名称;
2、DDL-操作表
  • 查询当前数据库中所有表
show tables;
  • 查询表结构
desc 表名;
  • 查询指定表的建表语句
show create table 表名;
  • 创建表
create table 表名(
	字段1 字段1类型[comment 字段1注释],
  字段2 字段2类型[comment 字段2注释],
  字段3 字段3类型[comment 字段3注释],
  ...
  字段n 字段n类型[comment 字段n注释]
)[comment 表注释];
3、数据类型

在这里插入图片描述

alter

  • 添加字段
alter table 表名 add 字段名 类型(长度) [comment 注释][约束];
-- 为emp表添加一个新的字段:名称为‘nickname’,类型为varchar(20)
alter table emp add nick_name varchar(20) comment '昵称';
  • 修改字段

    • 修改数据类型(modify–调整)

      alter table 表名 modify 字段名 新数据类型(长度);

    • 修改字段名和字段类型(change–改变)

      alter table 表名 change 旧字段名 新字段名 类型(长度) [comment 注释] [约束];

# 将emp表的nickname字段修改为username,类型为varchar(30)
alter table emp change nickname username varchar(30) comment '用户名';
  • 删除字段
alter table 表名 drop 字段名;
# 删除emp表中的username字段
alter table emp drop username;
  • 修改表名
alter table 表名 rename to 新表名;
# 将emp表的表名修改为employee;
alter table emp rename to employee;
  • 删除表
drop table [if exists] 表名;
# 删除employee表
drop table if exists employee;
  • 删除指定表,并重新创建该表(清除表中的所有数据)
truncate table 表名;

1.2.4、DML

(INSERT)|(UPDATE)|(DELETE)

1、DML-添加数据
  • 给指定字段添加数据
insert into 表名(字段1,字段2...) values (1,2...)
  • 给所有字段赋值
insert into 表名 values (1,2...)
  • 批量添加数据
insert into 表名(字段1,字段2...) values (1,2...),(1,2...),(1,2...);

insert into 表名 values (1,2...),(1,2...),(1,2...);
#创建employee表
create table employee(
    id int comment '编号',
    name varchar(10) comment '姓名',
    gender char(1) comment '性别',
    age tinyint comment '年龄',
    id_card char(18) comment '二代身份证18位',
    entrydate date comment '日期'
);

#把年龄字段修改为无符号数
alter table employee change age age tinyint unsigned comment '年龄';

#添加数据
insert into employee (id, name, gender, age, id_card, entrydate)
values (1,'张三','男',18,'123456789012345678','2022-01-01');
#查询数据
select *
from employee;

#测试年龄为负数可不可以插入
# insert into employee (id, name, gender, age, id_card, entrydate)
# values (2,'ww','男',-1,'123456789012345678','2022-01-01');
#不指定字段名
insert into employee values (2,'李四','男',18,'123456789442345678','2022-01-03');

#批量添加数据(不指定字段名)
insert into employee
values (3,'王五','男',18,'123456789332345678','2022-01-03'),(4,'red','男',8,'123456780042345678','2022-03-03'),(5,'andy','男',8,'123456789442300678','2022-03-03');
2、DML-修改数据
update 表名 set 字段名1 =1,字段名2 =2,...[where 条件];
#修改数据
#修改id为1的名称为itheima
update employee set name = 'itheima' where id = 1;
#修改id为1的数据,name为jack,gender为女
update employee set name = 'jack', gender = '女' where id = 1;
#将所有员工入职日期修改为2022-01-01
update employee set entrydate = '2022-01-01';
3、DML-删除数据
delete from 表名 [where 条件];

注意:

  • delete语句的条件可有可无,如果没有条件则会删除整张表的所有数据
  • delete语句不能删除某一个字段的值(可以使用update)(比如我们删除一个数据的某个字段比如年龄 我们就使用update语句把这个字段修改为null)
#删除数据
#删除gender为女的数据
delete from employee where gender='女';
-- 删除所有员工
delete
from employee;

1.2.5、DQL❗️

  • 关键字select

  • 语法结构

    select
    	字段列表
    from
    	列表名
    where
    	条件列表
    group by
    	分组字段列表
    having
    	分组后条件列表
    order by
    	排序字段列表
    limit
    	分页参数
    
  1. 基本查询(select)
  2. 条件查询(where)
  3. 聚合函数(count、max、min、avg、sum)
  4. 分组查询(group by)
  5. 排序查询(order by)
  6. 分页查询(limit)
1、DQL-基本查询
  1. 查询多个字段

    select 字段1,字段2,字段3 ... from 表名;
    select * from 表名;
    
  2. 设置别名(as)

    select 字段1[as 别名1],字段2[as 别名2] ... from 表名;
    #别名关键字as或者空一格
    select id as '编号',name '姓名' from employee;
    
  3. 去除重复记录(distinct)

    select distinct 字段列表 from 表名;
    #去重关键字 distinct
    select distinct age from employee;
    
2、DQL-条件查询
  1. 语法

    select 字段列表 from 表名 where 条件列表;
    
  2. 条件

    比较运算符功能
    >大于
    >=大于等于
    <小于
    <=小于等于
    <>或!=不等于
    between…and…在某个范围之内(含最小、最大值)
    in(…)在in之后的列表中的值,多选一
    like 占位符模糊匹配(_匹配单个字符,%匹配任意字符)
    is null是null
    逻辑运算符功能
    and 或 &&并且
    or 或 ||或者
    not 或 !非,不是
  3. 案例

    #查询年龄等于18的员工
    select * from employee where age = 18;
    #查询年龄小于20的员工信息
    select *
    from employee where employee.age < 18;
    #查询没有身份证号的员工信息
    select *
    from employee where id_card is null ;
    #查询有身份证号信息的员工
    select *
    from employee where id_card is not null ;
    #查询年龄不等于88的员工
    select *
    from employee where employee.age <> 88;
    #查询年龄在15到20之间的
    select *
    from employee where employee.age between 15 and 20;
    #查询性别为女且年龄小于25
    select *
    from employee where gender = '男' and employee.age<15;
    #查询年龄等于18或20或40
    select *
    from employee where employee.age = 18 or employee.age = 20 or employee.age = 40;
    
    select *
    from employee where employee.age in (18,20,40);
    #查询姓名为两个字的员工
    select *
    from employee where name like '__';
    #查询姓张的
    select *
    from employee where name like '张%';
    #查询身份证最后一位是X
    select *
    from employee where id_card like '%X';
    
3、DQL-聚合函数
  1. 介绍

    将一列数据作为整体,进行纵向计算

  2. 常见的聚合函数

    函数功能
    count统计数量
    max最大值
    min最小值
    avg平均值
    sum求和
  3. 语法

    select 聚合函数(字段) from 表名;
    

注意:使用聚合函数的时候所有的null值不参与运算

#求总记录数
select count(*)
from employee;

select count(employee.id) from employee;

#统计平均年龄
select avg(age) as '平均年龄' from employee;

#求最大年龄
select max(age) '最大年龄' from employee;
#求最小年龄
select min(age) '最小年龄' from employee;
#统计入职日期为2022-01-03员工的年龄之和
select sum(age) '2022-01-03的年龄之和' from employee where entrydate = '2022-01-03';

4、DQL-分组查询
  1. 语法

    select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
    
  2. where和having区别

    • 执行时机不同,where是在分组前进行过滤(不满足where条件的不参与分组),而having是在分组后的结果进行过滤
    • 判断条件不同:where不能对聚合函数进行判断,而having可以
#根据性别分组,统计男性员工和女员工的数量
select gender,count(*) from employee group by gender;
#根据性别分组,统计男和女的平均年龄
select gender, avg(age) from employee group by gender;
#查询年龄小于等于20的员工,并根据入职日期分组,获取员工数量大于等于2的入职日期
select entrydate,count(*) from employee where age<=20 group by entrydate having count(entrydate)>=2

注意:

  • 执行顺序:where -> 聚合函数 -> having
  • 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义!
5、DQL-排序查询
  1. 语法

    select 字段列表 from 表名 order by 字段1 排序方式1,字段2 排序方式2;
    
  2. 排序方式

    • ASC升序(默认)
    • DESC降序

注意:如果是多字段排序,当第一个字段值相同时,才会按照第二个字段进行排序

#根据年龄进行升序排序
select name,age,entrydate from employee order by age;
#根据年龄进行降序排序
select name,age,entrydate from employee order by age desc ;
#根据年龄进行升序排序 当年龄相同时 根据入职日期进行降序排序
select name,age,entrydate from employee order by age,entrydate desc ;
6、DQL-分页查询
  1. 语句

    select
    	字段列表
    from
    	表名列表
    where
    	条件列表
    group by
    	分组字段列表
    having
    	分组后条件列表
    order by
    	排序字段列表
    limit
    	分页参数
    
  2. 语法

    select 字段列表 from 表名 limit 起始索引,查询记录;
    
  3. 注意

    • 起始索引从0开始,起始索引 = (查询页码-1)*每页显示记录数
    • 分页查询是数据库的方言,不同数据库有不同的实现,MySQL中是limit
    • 如果查询的是第一页数据,起始索引可以省略,直接简写为limit 10
#-----------limit------------
select name from employee limit 0,3;
select name from employee limit 3;
select name from employee limit 3,3
7、DQL-练习
#-----------练习------------
#查询年龄分别为8,18,22
select *
from employee where age in (8,18,22);
#查询性别为男,并且年龄在10-40岁以内的姓名为两个字的
select *
from employee where gender = '男' and age between 10 and 40 and name like '__';
#统计员工表中,年龄10-20岁的,男女员工人数
select gender,count(*) from employee where age between 10 and  20 group by gender;
#查询所有年龄小于等于18岁的员工姓名和年龄,并对查询结果进行按照年龄升序排序,如果年龄相同就按照入职日期降序排序
select name,age from employee where age <= 18 order by age,entrydate desc ;
#查询性别为男,且年龄在10-20以内的前2个员工信息,并对查询结果进行按照年龄升序排序,如果年龄相同就按照入职日期降序排序
select *
from employee where gender = '男' and age between 10 and 20 order by age,entrydate desc limit 0,2;
8、DQL-执行顺序

编写顺序:

select
	字段列表
from
	表名列表
where
	条件列表
group by
	分组字段列表
having
	分组后条件列表
order by
	排序字段列表
limit
	分页参数

执行顺序:

from
	表名列表
where
	条件列表
group by
	分组字段列表
having
	分组后条件列表
select
	字段列表
order by
	排序字段列表
limit
	分页参数

1.2.6、DCL

1、DCL-管理用户
  1. 查询用户

    use mysql;
    select * from user;
    
  2. 创建用户

    create user '用户名'@'主机名' identified by '密码';
    
  3. 修改用户

    alter user '用户名'@'主机名' identified with mysql_native_password by '新密码';
    
  4. 删除用户

    drop user '用户名'@'主机名';
    
2、DCL-权限控制
  1. 查询权限

    show grants for '用户名'@'主机名';
    
  2. 授予权限

    grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
    
  3. 撤销权限

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

1.3、函数

函数是指一段可以直接被另一段程序调用的程序或代码

1.3.1、字符串函数

函数功能
concat(s1,s2…sn)字符串拼接,将是s1,s2…sn拼接成一个字符串
lower(str)将字符串str全部转换为小写
upper(str)将字符串str全部转换为大写
lpad(str,n,pad)左填充,用pad对左侧进行填充,使长度达到n
rpad(str,n,pad)右填充,用pad对右侧进行填充,使长度达到n
trim(str)把str的开头和结尾的空格去掉
substring(str,start,len)返回str从start开始的len的长度的字符串
select 函数(参数);

-- 案例
-- 由于企业变更原因,在工号前面需要补零,让工号长度为5
update employee set work_number = lpad(work_number,5,'0');

1.3.2、数值函数

函数功能
ceil(x)向上取整
floor(x)向下取整
mod(x,y)返回x/y的模
rand()返回0~1内的随机值
round(x,y)返回参数x的四舍五入值,保留y位小数
-- -------------数值函数-------------
/**
|  ceil(x)   |              向上取整              |
| :--------: | :--------------------------------: |
|  floor(x)  |              向下取整              |
|  mod(x,y)  |            返回x/y的模             |
|   rand()   |         返回0~1内的随机值          |
| round(x,y) | 返回参数x的四舍五入值,保留y位小数 |
 */
-- ceil
select ceil(1.5);
-- floor
select floor(1.5);
-- mod(x,y)
select mod(3,4);
select mod(7,4);
-- rand
select rand();
-- round(x,y)
select round(2.345,2);
-- 通过数据库的函数生成一个随机6位的验证码
select lpad(round(rand()*1000000,0),6,0)

1.3.3、日期函数

函数功能
curdate()返回当前日期(current-当前的)
curtime()返回当前时间
now()返回当前日期和时间
year(date)返回指定的date的年
month(date)返回指定的date的月
day(date)返回指定的date的日
date_add(date,interval expr typr)返回一个日期/时间值上加上一个时间间隔expr后的时间值
datediff(date1,date2)返回起始时间date1 和 结束时间date2之间的天数
-- ---------------------date----------------------
/**
|             curdate()             |            返回当前日期(current-当前的)             |
| :-------------------------------: | :-------------------------------------------------: |
|             curtime()             |                    返回当前时间                     |
|               now()               |                 返回当前日期和时间                  |
|            year(date)             |                 返回指定的date的年                  |
|            month(date)            |                 返回指定的date的月                  |
|             day(date)             |                 返回指定的date的日                  |
| date_add(date,interval expr typr) | 返回一个日期/时间值上加上一个时间间隔expr后的时间值 |
|       datediff(date1,date2)       |    返回起始时间date1 和 结束时间date2之间的天数     |
 */
-- curdate
select curdate();
-- curtime
select curtime();
-- now()
select now();
-- year month day
select year(now()),month(now()),day(now());
-- date_add
select date_add(now(),interval 70 day );
select date_add(now(),interval 70 month );
select date_add(now(),interval 70 year );
-- datediff (date1,date2) date1-date2
select datediff('2022-6-1','2022-5-30');

-- 查询员工的入职的天数,并且倒序排序
select name as '姓名',datediff(CURDATE(),entrydate) as '入职时长' from employee order by 入职时长 desc ;

1.3.4、流程函数

函数功能
if(vaule,t,f)如果value为true则返回t,否则返回f
ifnull(value1,value2)如果value不为null,返回value1,否则返回value2
case when [val1] then [res1]… else [default] end如果val1为true,返回res1…,否则返回default默认值
case [expr] when [val1] then [res1]… else [default] end如果expr的值等于val1,返回res1…,否则返回default默认值
-- 流程控制函数
-- if
select if(true,'success','error');
-- ifnull
select ifnull('ok','default');
select ifnull('','default');
select ifnull(null,'default');
-- case when then else end
select name,case entrydate when '2022-01-01' then '元旦' when '2022-01-02' then '元旦下一天' else '其他' end  as '身份信息'
from employee;

select name,score,
       case when score >= 85 then '优秀' when score >= 60 then '及格' else '不及格' end as '成绩' from employee order by score desc ;

1.4、约束

1.4.1、概念

  1. 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。

  2. 目的:保证数据库中数据的正确、有效和完整性

  3. 分类:

    约束描述关键字
    非空约束限制该字段的数据不能为nullnot null
    唯一约束保证该字段的所有数据都是唯一的、不重复的unique
    主键约束主键是一行数据的唯一标识、要求非空且唯一primary key
    默认约束保存数据时,如果未指定该字段的值,则采用默认值default
    检查约束(8.0.16版本之后)保证字段的值满足某一个条件check
    外键约束用来让两张表的数据之间建立联系,保证数据的一致性和完整性foreign key

1.4.2、约束演示

-- -------------------------约束演示------------------------------
-- 删除表
drop table if exists user;
-- 创建表
create table user(
    id int primary key auto_increment comment 'id',
    name varchar(10) not null unique comment '姓名',
    age int check ( age between 0 and 120) comment '年龄',
    status char(1) default 1 comment '状态',
    gender char(1) comment '性别'

) comment '用户表';
-- 修改字段
# alter table user change status status char(1) default 1 comment '状态';
-- 插入数据
insert into user (name, age, status, gender) values ('Red',59,'1','男'),('Andy',29,'0','男');
insert into user (name, age, status, gender) values ('Blue',120,'1','男');
insert into user (name, age,  gender) values ('Black3',20,'女');
-- 查询数据
select *
from user;

1.4.3、外键约束

创建两张表–员工表和部门表

sql如下:

-- -------------------约束(外键)----------------------
-- 准备数据--创建表
-- 部门表
create table dept(
    id int primary key auto_increment comment 'ID',
    name varchar(50) not null comment '部门名称'
)comment '部门表';

insert into dept (id, name)
values (1,'研发部'),(2,'市场部'),(3,'财务部'),(4,'销售部'),(5,'总经办');

select *
from dept;

-- 员工表
create table emp(
    id int auto_increment comment 'ID' primary key ,
    name varchar(50) not null comment '姓名',
    age int comment '年龄',
    job varchar(20) comment '职位',
    salary int comment '薪水',
    entry_date date comment '入职时间',
    manager_id int comment '直属领导ID',
    dept_id int comment '部门ID'
)comment '员工表';

insert into emp (name, age, job, salary, entry_date, manager_id, dept_id)
values ('金庸',66,'总裁',20000,'2000-01-01',null,5),
       ('张无忌',50,'项目经理',12500,'2005-02-03',1,1),
       ('杨戬',22,'开发',15000,'2022-02-03',2,1),
       ('二郎神',10,'开发',2500,'2022-04-03',3,1),
       ('孙悟空',66,'开发',12500,'2005-02-03',3,1),
       ('猪八戒',70,'运维',12500,'2005-02-03',3,1);

select *
from emp;
  1. 语法:

    添加外键

    create table 表名(
    		字段名 数据类型,
      	...
      	[constraint] [外键名称] foreign key(外键字段名) references 主表(主表列名)
    )comment 'xx表';
    
    alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);
    alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);
    

    删除外键

    alter table 表名 drop foreign key 外键名称;
    alter table emp drop foreign key fk_emp_dept_id;
    

    删除/更新行为

    行为说明
    no action当在父表中删除/更新对应的记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与restrict一致)
    restrict当在父表中删除/更新对应的记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与no action一致)
    cascade当在父表中删除/更新对应的记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在字表中的记录
    set null当在父表中删除对应的记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求外键允许为null)
    set default父表有变更时,字表将外键列设置成一个默认值
    alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名) 
    on update cascade on delete cascade;
    -- 外键更新/删除行为
    alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id)
        on update cascade on delete cascade ;
    

1.5、多表查询

1.5.1、多表关系

  1. 概述

    在项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:

    • 一对多(多对一)
    • 多对多
    • 一对一
  2. 一对多(多对一):

    • 案例:部门 与 员工的关系
    • 关系:一个部门对应多个员工,多个员工对应一个部门
    • 实现:在的一方建立外键,指向的一方的主键
  3. 多对多

    • 案例:学生 与 课程 的关系
    • 关系:一个学生可以选修多门课程,一门课程可以供多个学生选择
    • 实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方的主键
    -- ------------多对多------------
    -- 学生表
    create table student(
        id int primary key auto_increment comment '主键ID',
        name varchar(10) comment '姓名',
        number varchar(10) comment '学号'
    )comment '学生表';
    
    insert into student (id, name, number)
    values (null,'孙悟空','10001'),(null,'猪八戒','10002'),(null,'沙僧','10003'),(null,'白龙马','10004'),(null,'唐僧','10005'),(null,'如来','10006');
    
    -- 课程表
    create table course(
        id int primary key auto_increment comment '主键ID',
        name varchar(10) comment '课程名称'
    )comment '课程表';
    insert into course (id, name)
    values (null,'Java'),(null,'Python'),(null,'MySQL'),(null,'JavaScript');
    
    -- 中间表
    create table student_course(
        id int auto_increment primary key comment '主键',
        student_id int not null comment '学生ID',
        course_id int not null comment '课程ID',
        constraint fk_course_id foreign key (course_id) references course (id),
        constraint fk_student_id foreign key (student_id) references student (id)
    )comment '学生课程中间表';
    
    insert into student_course (id, student_id, course_id)
    values (null,1,1),(null,1,2),(null,1,3),(null,2,1),(null,3,1),(null,4,1),(null,5,1),(null,6,1);
    
    select *
    from student;
    select *
    from course;
    select *
    from student_course;
    
    
  4. 一对一

    • 案例:用户 与 用户详情的关系

    • 关系:一对一关系,用于单表拆分。将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率

    • 实现:在任意一方加入外键,关联另一方的主键,并且设置外键为唯一的(unique)

      -- -------------一对一-------------
      create table tb_user(
          id int primary key auto_increment comment '主键ID',
          name varchar(10) comment '姓名',
          age int comment '年龄',
          gender char(1) comment '1:男,2:女',
          phone char(11) comment '手机号'
      )comment '用户基本信息';
      
      create table tb_user_edu(
          id int primary key auto_increment comment '主键ID',
          degree varchar(20) comment '学历',
          major varchar(50) comment '专业',
          primaryschool varchar(50) comment '小学',
          middleschool varchar(50) comment '中学',
          university varchar(50) comment '大学',
          userid int unique comment '用户ID',
          constraint fk_userid foreign key (userid) references tb_user (id)
      
      )comment '用户教育信息';
      
      
      insert into tb_user (id, name, age, gender, phone)
      values (null,'1',20,'男','18888888888'),
             (null,'2',21,'男','18888888877'),
             (null,'3',22,'女','18888888866'),
             (null,'4',23,'男','18888888855');
      insert into tb_user_edu (degree, major, primaryschool, middleschool, university, userid)
      values ('本科','舞蹈','北京第一小学','北京第一中学','北京舞蹈学院',1),
             ('本科','舞蹈','上海第一小学','上海第一中学','北京舞蹈学院',2),
             ('本科','舞蹈','江苏第一小学','江苏第一中学','北京舞蹈学院',3),
             ('本科','舞蹈','杭州第一小学','杭州第一中学','北京舞蹈学院',4);
      
      select *
      from tb_user_edu;
      

1.5.2、多表查询概述

  1. 概述:

    指从多张表中查询数据

  2. 笛卡尔积:

    指的是在数学中,两个集合A集合和B集合的所有组合情况(在多表查询的时候,要消除无效的笛卡尔积)

  3. 多表查询分类

    • 连接查询
      • 内连接:相当于查询A、B交集部分数据
      • 外连接:
        • 左外连接:查询左表所有数据,以及两张表交集部分数据
        • 右外连接:查询右表所有数据,以及两张表交集部分数据
      • 自连接:查询表与自身的连接查询,自连接必须使用表别名

1.5.3、内连接(查询交集部分)

  • 隐式内连接

    select 字段列表 from1,2 where 条件...;
    -- 隐式内连接
    select emp.name,dept.name from emp,dept where dept_id = dept.id;
    
  • 显式内连接(join)

    select 字段列表 from1 [inner] join2 on 连接条件...;
    -- 显式内连接
    select e.name,d.name from emp e join dept d on e.dept_id = d.id;
    

给表起了别名之后将不能使用原表名字,因为执行顺序先执行from

1.5.4、外连接

  • 左外连接(左表数据+交集部分)
#左外连接
SELECT 字段列表 FROM1 LEFT [OUTER] JOIN2 ON 条件...;

#查询emp表的所有数据,和对应的部门信息(左外连接)
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id;
  • 右外连接(交集部分+右表数据)
#右外连接
SELECT 字段列表 FROM1 RIGHT [OUTER] JOIN2 ON 条件...;

#查询dept表的所有数据,和对应的员工信息(右外连接)
SELECT d.*,e.* FROM emp e RIGHT OUTER JOIN dept d ON e.dept_id = d.id;

1.5.5、自连接

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件...;

#查询员工及其直属领导的名字
SELECT e1.name 员工,e2.name 领导 FROM emp e1 JOIN emp e2 ON e1.managerid = e2.id;

#查询所有员工emp及其领导的名字emp,如果没有领导也要查询出来
SELECT e1.*,e2.name 领导 FROM emp e1 LEFT JOIN emp e2 ON e1.managerid = e2.id;

1.5.6 联合查询

对于UNION查询,就是把多次查询的结果合并起来,形成一个新的查询结果集

语法:

SELECT 字段列表 FROM 表A ...
UNION [ALL]
SELECT 字段列表 FROM 表B ...;

实例:

#将薪资低于5000的员工,和年龄大于50岁的员工都查询出来。
SELECT * FROM emp WHERE salary < 5000 UNION SELECT * FROM emp WHERE age > 50 ORDER BY id ASC;
  • 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致
  • UNION ALL会直接将两个结果集合并,而UNION会进行去重

1.5.7、子查询

概念:SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询

语法:

SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);

根据子查询结果不同,分为:

  • 标量子查询(结果为单个值)
  • 列子查询(结果为一列)
  • 行子查询(结果为一行)
  • 表子查询(结果为多行多列)

1.6 事务

事务四大特性(ACID)

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

并发事务问题

问题说明
脏读一个事务读到另一个事务还没有提交的数据
不可重复读一个事务先后读取同一条记录,但两次读取出来的数据不同,称为不可重复读
幻读一个事务按照条件查询数据时,没有对应的数据行,但是在插入时,又发现这行数据已经存在了,好像出现了“幻觉”

事务隔离级别(安全性)

隔离级别脏读不可重复读幻读
Read Uncommitted 读未提交
Read Committed 读已提交(Orcal默认)×
Repeatable Read 可重复读(MySQL默认)××
Serializable 串行化×××
#查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;

#设置事务隔离级别
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

Read Committed 隔离级别下解决了脏读问题,也就是另一事务将执行的数据提交之后,才可以看到修改后的数据。

Repeatable Read 隔离级别下解决了不可重复读的问题,也就是同一事务在整个阶段内读到的数据全部一致,其他事务修改数据并不影响该事务的查询结果。

Serializable 隔离级别下一个事务在提交阶段另一事务无法修改数据。(只允许一个事务操作)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/420874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ijkplayer 编译增加支持更多的音视频格式

ijkplayer是B站开源的一款基于ffmpeg的移动端播放器。但为了减少播放器的体积&#xff0c;很多音视频的格式播放默认都是不支持的&#xff0c;需要自己下载ijkplayer源码进行编译。这里以mac环境下android为例&#xff0c;简述ijkplayer的编译过程&#xff0c;以及为了支持更多…

最新版本 Stable Diffusion 开源 AI 绘画工具之图生图进阶篇

✨ 目录&#x1f388; 图生图基本参数&#x1f388; 图生图&#xff08;img2img&#xff09;&#x1f388; 涂鸦绘制&#xff08;Sketch&#xff09;&#x1f388; 局部绘制&#xff08;Inpaint&#xff09;&#x1f388; 涂鸦蒙版&#xff08;Inpaint sketch&#xff09;&…

Adams2020软件安装教程

目录 一、软件简介 二、软件下载 三、软件安装 一、软件简介 Adams是一款多领域仿真软件&#xff0c;可以对机械、电子、流体、化学等系统进行建模、仿真和分析。Adams具有强大的动力学分析功能&#xff0c;可以模拟多种复杂系统的运动、力学、热力学和控制行为&#xff0c;包…

点云目标检测:open3d多窗口联动可视化

多个模型之间的对比除了指标之外,还需要可以直观的对比可视化结果,这次介绍一下如何使用open3d同时打开两个窗口分别加载两个模型的结果,同时实现两个窗口的联动,也就是当一个窗口拖动或者缩放时另外一个窗口也跟着做同样的变换。 点云可视化:使用open3d实现点云连续播放这…

nginx虚拟主机

一、基于域名的nginx虚拟主机 1、基于域名的nginx虚拟主机的操作步骤 1.1 为虚拟主机提供域名和IP的映射(也可以使用DNS正向解析) echo "192.168.2.66 www.xkq.com www.wy.com" >> /etc/hosts1.2 为虚拟主机准备网页文档 mkdir -p /var/www/html/ly/ mkdir…

第一章 深度学习入门之流程初体验

效果图 文章中采用的是棋盘格数据&#xff0c;这张图里面用的是开源的模型&#xff0c;可以用于测试&#xff0c;此图为最终效果&#xff0c;加载mp4视频&#xff0c;通过opencv读取图像&#xff0c;传递到infer接口&#xff0c;进行推理识别&#xff0c;利用opencv显示出来 …

比较好的文档翻译软件-哪个翻译软件最精准

免费语言翻译软件可以帮助用户快速准确地翻译语言&#xff0c;其主要作用如下&#xff1a; 辅助语言学习&#xff1a;语言翻译软件可以帮助用户学习语言&#xff0c;让用户更好地理解在不同语言之间的差异&#xff0c;从而使语言学习更加高效。 翻译外语内容&#xff1a;语言翻…

Java中常见的几种分布式锁介绍及实战应用

文章目录什么是锁&#xff1f;场景描述代码示例总结Java中单体应用锁的局限性&分布式锁前言互联网系统架构的演进单体应用锁的局限性什么是分布式锁分布式锁的设计思路目前存在的分布式的方案Java中锁的解决方案前言乐观锁 与 悲观锁公平锁 与 非公平锁总结分布式锁设计如何…

Python基础教程:__call__用法

人生苦短&#xff0c;我用python python 安装包资料:点击此处跳转文末名片获取 __call__可以使得方法变成可被调用对象&#xff1b; (PS&#xff1a;python中的方法和普通函数有点区别&#xff1a; 方法的第一个参数是类实例) 允许一个类的实例像函数一样被调用。 实质上说…

相机雷达时间同步(基于ROS)

文章目录运行环境&#xff1a;思路&#xff1a;同步前和同步后效果对比1.1创建工作空间1.2创建功能包2.1编写源文件2.2编写头文件2.3编写可执行文件2.4配置文件3.1编译运行4.1录制时间同步后的rosbag4.2rviz可视化rosbag运行环境&#xff1a; ubuntu20.04 noetic usb_cam 速腾R…

小黑子—Java从入门到入土过程:第七章

Java零基础入门7.0Java系列第七章1. 游戏打包exe2. API2.1 Math2.2 练习2.2.1 判断质数2.2.2 判断水仙花数&#xff08;自幂数&#xff09;2.3 System2.4 Runtime2.5 Object2.5.1 Object 的成员方法(1) toString(2) equals 比较两个对象是否相等(3) clone方法&#xff08;Objec…

投放视频广告时,如何快速与第三方播放器兼容?

新媒体时代&#xff0c;广告样式越来越丰富。相较于传统的图文信息&#xff0c;视频类广告更具有直观性&#xff0c;能够让消费者在了解产品知识和功能的同时加深对产品的印象。 因此在各类网站或App上投放视频类广告是个很好的宣传方式&#xff0c;但广告商们如果想在网站上展…

1.14 从0开始学习Unity游戏开发--物理引擎

上一篇文章我们讲了如何动态创建物体&#xff0c;以及如何用Prefab机制复用我们制作好的物体和逻辑&#xff0c;那么本篇我们将会讲解如何利用这些功能&#xff0c;结合Unity自带的物理引擎&#xff0c;实现一个简单的FPS游戏的效果。 物理组件 首先我们需要先了解如何使用Un…

Linux基础(超级无敌认真好用,万字收藏篇!!!!)

文章目录Linux基础1 Linux概述1.1 Linux特点1.2 Linux和Window区别2 Linux安装2.1 什么是虚拟化2.2 安装虚拟机2.3 配置网络环境3 Linux文件目录4 Linux常用命令4.1 文件与目录操作4.2 查看文件内容4.3 文本内容处理4.4 查询操作4.5 网络相关4.6 其他命令4.7 解压缩命令5 VI/VI…

今天面了个腾讯拿 38K 出来的,让我见识到了基础的天花板

今天上班开早会就是新人见面仪式&#xff0c;听说来了个很厉害的大佬&#xff0c;年纪还不大&#xff0c;是上家公司离职过来的&#xff0c;薪资已经达到中高等水平&#xff0c;很多人都好奇不已&#xff0c;能拿到这个薪资应该人不简单&#xff0c;果然&#xff0c;自我介绍的…

0102加权quick_union和路径压缩-union-find-动态连通性-算法研究

3 union-find算法 3.5 加权quick-union算法 3.5.1 算法实现 quick-union出现最坏情况&#xff0c;因为我们是随意将一棵树链接到另外一棵树上&#xff0c;修改如下&#xff1a; 添加一个数组和一些代码记录树中节点数&#xff1b;链接时将节点数较小的树链接到较大的树上&a…

基础算法-双指针,滑动窗口,位运算,区间离散化

双指针 两种类型 for(int i0,j0;i<n;i) {while(i<j&&check(i,j)) j;// 每道题目具体逻辑}双指针最核心的性质 可以优化 输入一个字符串 把每个单词输出出来 i找到单词开头 j找到空格 vector<string> rs; for(int i0,j0;i<s.size();i) {ji;while(j&…

.Net Forms Resize 12 Crack

.Net Forms Resize 12 Crack 添加了对Microsoft Visual Studio 2022(v17.5.3)及更高版本的支持。 增加了对Microsoft Windows Server 2019和2022的支持。 改进并调整引擎大小(大约快20%)。 更新与受支持的第三方控件的新版本的兼容性。 添加了新的Microsoft Framework 4.8.1库。…

in、not in、between and、基本查询数据库实验三 单表查询(一)(头歌实践教学平台)

文章目的初衷是希望学习笔记分享给更多的伙伴&#xff0c;并无盈利目的&#xff0c;尊重版权&#xff0c;如有侵犯&#xff0c;请官方工作人员联系博主谢谢。 目录 第1关&#xff1a;基本查询语句 任务描述 相关知识 查询数据表中指定字段的内容 查询数据表中的所有内容 …

Ucore lab2

练习一&#xff1a;实现first-fit 连续物理内存分配算法 根据实验指导书中的实验执行流程概述&#xff0c;先了解分析ucore如何对物理内存进行管理&#xff0c;再完成实验练习。 在对物理内存进行管理之前&#xff0c;需要先进行物理内存布局的探测&#xff0c;探测得到的内存…