JavaWeb企业级开发---MySQL

记录在听黑马课的时候的笔记以及课堂上练习的代码,文章图源于我在听课的时候所截的屏,所以有些不清晰,请见谅。下面是课程链接,可点击自行跳转。

【黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖Spring+MyBatis+SpringMVC+SpringBoot等)】 https://www.bilibili.com/video/BV1m84y1w7Tb/?share_source=copy_web&vd_source=d521b664e1113402904fa9336bd1d0ac


目录

介绍

安装

数据模型&SQL简介

DDL

数据库操作

图形化工具

表结构操作

创建

数据类型

创建案例

查询&修改&删除

DML

添加数据insert

修改数据update

删除数据delete

DQL

基本查询

条件查询

聚合函数

分组查询

排序查询

分页查询

案例

按照需求完成员工管理的条件分页查询

完成员工信息的统计

多表设计

一对多

一对多外键约束

一对一

多对多

案例

关系分析

表结构

分类管理

[方式 1:直接勾选 "唯一"(适用于单个字段唯一)](#方式 1:直接勾选 “唯一”(适用于单个字段唯一))

[方式 2:通过 "索引" 标签手动创建唯一索引(更灵活,支持多字段联合唯一)](#方式 2:通过 “索引” 标签手动创建唯一索引(更灵活,支持多字段联合唯一))

菜品管理

套餐管理

菜品-套餐表

多表查询

概述

内连接

外连接

子查询

标量子查询&列子查询

行子查询&表子查询

案例

事务

介绍与操作

四大特性

索引

介绍

结构

语法


介绍

安装

对于MySQL连接报错,则可能是没打开MySQL服务

数据模型&SQL简介

DDL

数据库操作

图形化工具

表结构操作

创建

增加了约束之后:

数据类型

数值类型:

|------|-----------|----------|-------------------------------------------------------|----------------------------------------------------------|-----------|------------------------------------|
| 分类 | 类型 | 大小(byte) | 有符号(SIGNED)范围 | 无符号(UNSIGNED)范围 | 描述 | 备注 |
| 数值类型 | tinyint | 1 | (-128, 127) | (0, 255) | 小整数值 | |
| 数值类型 | smallint | 2 | (-32768, 32767) | (0, 65535) | 大整数值 | |
| 数值类型 | mediumint | 3 | (-8388608, 8388607) | (0, 16777215) | 大整数值 | |
| 数值类型 | int | 4 | (-2147483648, 2147483647) | (0, 4294967295) | 大整数值 | |
| 数值类型 | bigint | 8 | (-263, 263-1) | (0, 2^64-1) | 极大整数值 | |
| 数值类型 | float | 4 | (-3.402823466 E+38, 3.402823466351 E+38) | 0 和 (1.175494351 E-38, 3.402823466 E+38) | 单精度浮点数值 | float(5,2): 5表示整个数字长度, 2 表示小数位个数 |
| 数值类型 | double | 8 | (-1.7976931348623157 E+308, 1.7976931348623157 E+308) | 0 和 (2.2250738585072014 E-308, 1.7976931348623157 E+308) | 双精度浮点数值 | double(5,2): 5表示整个数字长度, 2 表示小数位个数 |
| 数值类型 | decimal | | | | 小数值(精度更高) | decimal(5,2): 5表示整个数字长度, 2 表示小数位个数 |

字符串类型:

|-------|------------|-----------------------|-----------------|
| 分类 | 类型 | 大小 | 描述 |
| 字符串类型 | char | 0-255 bytes | 定长字符串 |
| 字符串类型 | varchar | 0-65535 bytes | 变长字符串 |
| 字符串类型 | tinyblob | 0-255 bytes | 不超过255个字符的二进制数据 |
| 字符串类型 | tinytext | 0-255 bytes | 短文本字符串 |
| 字符串类型 | blob | 0-65 535 bytes | 二进制形式的长文本数据 |
| 字符串类型 | text | 0-65 535 bytes | 长文本数据 |
| 字符串类型 | mediumblob | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 |
| 字符串类型 | mediumtext | 0-16 777 215 bytes | 中等长度文本数据 |
| 字符串类型 | longblob | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 |
| 字符串类型 | longtext | 0-4 294 967 295 bytes | 极大文本数据 |

|------------------------------------------|-----|-----|------|
| 类型描述 | 示例 | 性能 | 空间 |
| char(10): 最多只能存10个字符,不足10个字符,占用10个字符空间 | AB | 性能高 | 费空间 |
| varchar(10): 最多只能存10个字符,不足10个字符,按照实际长度存储 | ABC | 性能低 | 节省空间 |

日期时间类型:

|------|-----------|----------|-------------------------------------------|---------------------|--------------|
| 分类 | 类型 | 大小(byte) | 范围 | 格式 | 描述 |
| 日期类型 | date | 3 | 1000-01-01 至 9999-12-31 | YYYY-MM-DD | 日期值 |
| 日期类型 | time | 3 | -838:59:59 至 838:59:59 | HH:MM:SS | 时间值或持续时间 |
| 日期类型 | year | 1 | 1901 至 2155 | YYYY | 年份值 |
| 日期类型 | datetime | 8 | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
| 日期类型 | timestamp | 4 | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |

创建案例

查询&修改&删除

DML

添加数据insert

sql 复制代码
-- DML :数据操作语言
-- DML :插入数据 - insert
-- 1. 为 tb_emp 表的 username, name, gender 字段插入值
insert into tb_emp(username,name,gender,create_time,update_time) values ('wuji','张无忌',1,now(),now());

-- 2. 为 tb_emp 表的 所有字段插入值
insert into tb_emp(id, username, password, name, gender, image, job, entrydate, create_time, update_time)
values (null,'zhiruo','123','周芷若',2,'1.jpg',1,'2010-01-01',now(),now());

insert into tb_emp values (null,'zhiruo2','123','周芷若',2,'1.jpg',1,'2010-01-01',now(),now());

-- 3. 批量为 为 tb_emp 表的 username , name , gender 字段插入数据
insert into tb_emp(username,name,gender,create_time,update_time) values
('weifuwang','韦一笑',1,now(),now()),('xieshiwang','谢逊',1,now(),now());

修改数据update

sql 复制代码
-- DML :更新数据 - update
-- 1. 将 tb_emp 表的ID为1员工 姓名name字段更新为 '张三'
update tb_emp set name = '张三' , update_time = now() where id = 1;

-- 2. 将 tb_emp 表的所有员工的入职日期更新为 '2010-01-01'
update tb_emp set entrydate = '2010-01-01', update_time = now();

删除数据delete

sql 复制代码
-- DML :删除数据 - delete
-- 1. 删除 tb_emp 表中 ID为1的员工
delete from tb_emp where id = 1;

-- 2. 删除 tb_emp 表中的所有员工
delete from tb_emp;

DQL

基本查询

sql 复制代码
-- 批量插入多条员工数据
INSERT INTO tb_emp (username, password, name, gender, image, job, entrydate, create_time, update_time)
VALUES 
('zhangSan', '654321', '张三', 1, 'avatar/zs.jpg', 1, '2023-03-10', NOW(), NOW()),
('liSi', 'abc123', '李四', 1, 'avatar/lisi.png', 2, '2023-05-15', NOW(), NOW()),
('wangWu', '888888', '王五', 2, 'avatar/ww.jpg', 3, '2022-11-01', NOW(), NOW()),
('zhaoLiu', 'xyz789', '赵六', 2, 'avatar/zl.png', 4, '2024-01-20', NOW(), NOW()),
('qianQi', 'qwe123', '钱七', 1, 'avatar/qq.jpg', 2, '2023-09-05', NOW(), NOW()),
('sunBa', 'sun888', '孙八', 2, 'avatar/sb.png', 1, '2022-07-18', NOW(), NOW()),
('zhouJiu', 'zhou999', '周九', 1, 'avatar/zj.jpg', 3, '2024-02-28', NOW(), NOW()),
('wuShi', 'wu1010', '吴十', 2, 'avatar/ws.png', 4, '2023-06-30', NOW(), NOW());
sql 复制代码
-- ========== DQL: 基本查询 ==========
-- 1. 查询指定字段 name,entrydate 并返回
select name,entrydate from tb_emp;

-- 2. 查询返回所有字段
-- 推荐
select id, username, password, name, gender, image, job, entrydate, create_time, update_time from tb_emp;
-- 不推荐(不直观,性能低)
select * from tb_emp;

-- 3. 查询所有员工的 name,entrydate, 并起别名(姓名、入职日期)
select name as 姓名,entrydate as 入职日期 from tb_emp;
select name '姓 名',entrydate 入职日期 from tb_emp;

-- 4. 查询已有的员工关联了哪几种职位(不要重复)
select distinct job from tb_emp;

条件查询

sql 复制代码
-- ===================== DQL:条件查询 =====================
-- 1. 查询 姓名 为 张三 的员工
select * from tb_emp where name = '张三';

-- 2. 查询 id小于等于5 的员工信息
select * from tb_emp where id <= 5;

-- 3. 查询 没有分配职位(job为null) 的员工信息
select * from tb_emp where job is null;

-- 4. 查询 有职位(job不为null) 的员工信息
select * from tb_emp where job is not null;

-- 5. 查询 密码不等于 '123456' 的员工信息
select * from tb_emp where password != '123456';

-- 6. 查询 入职日期 在 '2022-01-01'(包含)到 '2025-01-01'(包含)之间的员工信息
select * from tb_emp where entrydate between '2022-01-01' and '2025-01-01';

-- 7. 查询 入职时间 在 '2022-01-01'(包含)到 '2025-01-01'(包含)之间 且 性别为女(gender=2) 的员工信息
select * from tb_emp where entrydate between '2022-01-01' and '2025-01-01' and gender = 2;

-- 8. 查询 职位是 2(讲师)、3(学工主管)、4(教研主管) 的员工信息
select * from tb_emp where job in (2, 3, 4);

-- 9. 查询 姓名 为两个字的员工信息
select * from tb_emp where name like '__';

-- 10. 查询 姓 '张' 的员工信息
select * from tb_emp where name like '张%';

聚合函数

sql 复制代码
-- DQL分组查询
-- 聚合函数
-- 1.统计该企业员工数量
-- count(字段) 需要count一个非空字段
SELECT COUNT(id) FROM tb_emp;
SELECT COUNT(username) FROM tb_emp;
-- count(常量)
SELECT COUNT(0) FROM tb_emp;
-- count(*) 推荐
SELECT COUNT(*) FROM tb_emp;
-- 统计该企业最早入职的员工
SELECT MIN(entrydate) FROM tb_emp;
-- 统计该企业最迟入职的员工
SELECT MAX(entrydate) FROM tb_emp;
-- 统计该企业id的平均值
SELECT AVG(id) FROM tb_emp;
-- 统计该企业id的和
SELECT SUM(id) FROM tb_emp;

分组查询

sql 复制代码
-- 分组
-- 1. 根据性别分组 ,统计女性和男性员工的数量 - count(*)
SELECT gender,COUNT(*) FROM tb_emp GROUP BY gender;
-- 2. 先查询入职时间在 '2015-01-01'(包含)以前的员工 ,并对结果根据职位分组 ,获取员工数量大于等于2的职位
SELECT job,COUNT(*) FROM tb_emp WHERE entrydate <= '2025-01-01' GROUP BY job HAVING COUNT(*) >= 2;

排序查询

sql 复制代码
-- ===================== 排序查询 =====================
-- 1. 根据入职时间,对员工进行升序排序 ASC 为默认值,不写也OK
SELECT * FROM tb_emp ORDER BY entrydate ASC;
SELECT * FROM tb_emp ORDER BY entrydate;
-- 2. 根据入职时间,对员工进行降序排序
SELECT * FROM tb_emp ORDER BY entrydate DESC;
-- 3. 根据 入职时间 对公司的员工进行 升序排序, 入职时间相同,再按照 更新时间 进行降序排序
SELECT * FROM tb_emp ORDER BY entrydate,update_time DESC;

分页查询

sql 复制代码
-- ===================== 分页查询 =====================
-- 起始索引 = (页码 - 1) * 每页展示的记录数
-- 1. 从 起始索引0 开始查询员工数据,每页展示5条记录
SELECT * FROM tb_emp LIMIT 0,5;
-- 2. 查询 第1页 员工数据,每页展示5条记录
SELECT * FROM tb_emp LIMIT 0,5;
-- 3. 查询 第2页 员工数据,每页展示5条记录
SELECT * FROM tb_emp LIMIT 5,5;
-- 4. 查询 第3页 员工数据,每页展示5条记录
SELECT * FROM tb_emp LIMIT 10,5;

案例

按照需求完成员工管理的条件分页查询

1.查询员工

1.1根据输入的 员工姓名、员工性别、入职时间 搜索满足条件的员工信息。

1.2其中 员工姓名,支持模糊匹配;性别 进行精确查询;入职时间 进行范围查询。

1.3支持分页查询。

1.4并对查询的结果,根据最后修改时间进行倒序排序。

sql 复制代码
-- 案例1 :按需求完成员工管理的条件分页查询 - 根据输入条件,查询第一页数据,每页展示10条记录
-- 输入条件:
-- 姓名:张
-- 性别:男
-- 入职时间:2000-01-01  2015-12-31
SELECT
	* 
FROM
	tb_emp 
WHERE
	NAME LIKE '%张%' 
	AND gender = 1 
	AND entrydate BETWEEN "2000-01-01" 
	AND "2025-12-31";

完成员工信息的统计

sql 复制代码
-- 案例2-1 :根据需求,完成员工性别信息的统计
-- if (条件表达式,true 取值,false 取值)
SELECT IF(gender=1,"男","女") 性别,COUNT(*) FROM tb_emp GROUP BY gender;
-- 案例2-2 :根据需求,完成员工职位信息的统计
-- case 表达式 when 值 1 then 结果 1 when 值 2 then 结果 2 ... else ... end
SELECT
(CASE
		job 
		WHEN 1 THEN
		"班主任" 
		WHEN 2 THEN
		"讲师" 
		WHEN 3 THEN
		"学工主管" 
		WHEN 4 THEN
		"教研主管" ELSE "还未设置职位" 
	END) 职位
,
COUNT(*) 
FROM
	tb_emp 
GROUP BY
	job;

多表设计

一对多

部门管理-需求说明

部门管理页面,管理员可以对部门信息进行管理,包括新增、修改、删除部门信息等。

页面开发规则

1.部门查询

1.1 查询全部数据(由于部门数据比较少,不考虑分页)。

2.新增部门

1.1 点击新增部门,会打开新增部门的页面。

1.2 部门名称,必填,唯一,长度为2-10位。

删除部门

弹出确认框,提示"您确定要删除该部门的信息吗?"如果选择确定,则删除该部门,删除成功后,重新刷新列表页面。 如果选择了 取消

sql 复制代码
-- 员工
create table tb_emp (
    id int unsigned primary key auto_increment comment 'ID',
    username varchar(20) not null unique comment '用户名',
    password varchar(32) default '123456' comment '密码',
    name varchar(10) not null comment '姓名',
    gender tinyint unsigned not null comment '性别,说明:1 男, 2 女',
    image varchar(300) comment '图像',
    job tinyint unsigned comment '职位,说明:1 班主任,2 讲师, 3 学工主管, 4 教研主管',
    entrydate date comment '入职时间',
    dept_id int unsigned comment '归属的部门ID',
    create_time datetime not null comment '创建时间',
    update_time datetime not null comment '修改时间'
) comment '员工表';

-- 部门
create table tb_dept (
    id int unsigned primary key auto_increment comment 'ID',
    name varchar(10) not null unique comment '部门名称',
    create_time datetime not null comment '创建时间',
    update_time datetime not null comment '修改时间'
) comment '部门表';

一对多外键约束

sql 复制代码
create table tb_emp
(
    id          int auto_increment comment 'ID',
    username    varchar(20)                  null comment '用户名',
    password    varchar(32) default '123456' null comment '密码,初始密码为123456',
    name        varchar(10)                  null comment '姓名',
    gender      tinyint unsigned             null comment '性别 1 男 2 女',
    image       varchar(300)                 null comment '图像url',
    job         tinyint unsigned             null comment '职位 1 班主任,2讲师,3学工主管,4教研主管',
    entrydate   date                         null comment '入职日期',
    create_time datetime                     not null comment '创建时间',
    update_time datetime                     not null comment '修改时间',
    dept_id     int unsigned                 not null comment '外键连接部门id',
    primary key (id, dept_id),
    constraint username
        unique (username) comment '用户名唯一',
    constraint tb_emp_ibfk_1
        foreign key (dept_id) references tb_dept (id)
);

create index dept_id
    on tb_emp (dept_id);

一对一

sql 复制代码
-- 用户信息表(tb_user)
create table tb_user(
                        id int unsigned primary key auto_increment comment 'ID',
                        name varchar(10) not null comment '姓名',
                        gender tinyint unsigned not null comment '性别, 1 男  2 女',
                        phone char(11) comment '手机号',
                        degree varchar(10) comment '学历'
) comment '用户信息表';

insert into tb_user values
                        (1,'白眉鹰王',1,'18812340001','初中'),
                        (2,'青翼蝠王',1,'18812340002','大专'),
                        (3,'金毛狮王',1,'18812340003','初中'),
                        (4,'紫衫龙王',2,'18812340004','硕士');

-- 用户身份证信息表(tb_user_card)
create table tb_user_card(
                             id int unsigned primary key auto_increment comment 'ID',
                             nationality varchar(10) not null comment '民族',
                             birthday date not null comment '生日',
                             idcard char(18) not null comment '身份证号',
                             issued varchar(20) not null comment '签发机关',
                             expire_begin date not null comment '有效期限-开始',
                             expire_end date comment '有效期限-结束',
                             user_id int unsigned not null unique comment '用户ID',
                             constraint fk_user_id foreign key (user_id) references tb_user(id)
) comment '用户身份证信息表';

insert into tb_user_card values
                             (1,'汉','1960-11-06','100000100000100001','朝阳区公安局','2000-06-10',null,1),
                             (2,'汉','1971-11-06','100000100000100002','静安区公安局','2005-06-10','2025-06-10',2),
                             (3,'汉','1963-11-06','100000100000100003','昌平区公安局','2006-06-10',null,3),
                             (4,'回','1980-11-06','100000100000100004','海淀区公安局','2008-06-10','2028-06-10',4);

多对多

sql 复制代码
-- 学生表(tb_student)
create table tb_student(
                           id int auto_increment primary key comment '主键ID',
                           name varchar(10) comment '姓名',
                           no varchar(10) comment '学号'
) comment '学生表';

insert into tb_student(name, no) values
                                     ('黛绮丝', '2000100101'),
                                     ('谢逊', '2000100102'),
                                     ('殷天正', '2000100103'),
                                     ('韦一笑', '2000100104');

-- 课程表(tb_course)
create table tb_course(
                          id int auto_increment primary key comment '主键ID',
                          name varchar(10) comment '课程名称'
) comment '课程表';

insert into tb_course (name) values
                                 ('Java'),
                                 ('PHP'),
                                 ('MySQL'),
                                 ('Hadoop');

-- 学生课程中间表(tb_student_course)
create table tb_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_courseid foreign key (course_id) references tb_course (id),
                                  constraint fk_studentid foreign key (student_id) references tb_student (id)
) comment '学生课程中间表';

insert into tb_student_course(student_id, course_id) values
                                                         (1,1),
                                                         (1,2),
                                                         (1,3),
                                                         (2,2),
                                                         (2,3),
                                                         (3,4);

案例

关系分析

表结构

分类管理

1.2.3 新增菜品/套餐名称:

限制字符范围:2-20字符 不符合限制提示,"分类名称输入不符,请输入2-20个字符"

1.2.4 排序不能为空, 内容限制:0-99整数数字 不符合限制提示:"排序只能输入整数类型" 排序为空提示:"排序不能为空"

1.2.5 新增菜品/套餐分类,状态默认为 停用。

Navicat设置字段唯一

方式 1:直接勾选 "唯一"(适用于单个字段唯一)
  • name 字段所在行,找到 "索引" 列(或 "唯一" 列,不同 Navicat 版本可能显示不同),勾选 "唯一" 选项。勾选后,该字段会自动创建一个唯一索引,确保值不重复。
方式 2:通过 "索引" 标签手动创建唯一索引(更灵活,支持多字段联合唯一)
  1. 点击设计界面上方的 "索引" 标签(通常在 "字段" 标签旁边)。
  2. 点击 "添加索引" 按钮(或 "+" 号)。
  3. 在右侧设置:
    • 索引名称 :自定义一个有意义的名称(如 uk_nameuk 表示 unique key)。
    • 类型 :选择 "UNIQUE"(唯一索引)。
    • 字段 :在下拉框中选择 name 字段。最后点击 "确定" 保存索引。
菜品管理

|------|-------|------|-------|---------------------------------------------------------|-------|---------------------------------------|
| 字段名称 | 必填/选填 | 类型 | 长度限制 | 输入限制 | 是否可重复 | 提示话术 |
| 菜品名称 | 必填 | 输入框 | 2-20 | 汉字、字母大小写、阿拉伯数字 | 不可重复 | 不符合限制提示,"菜品名称输入不符" 菜品重复提示"菜品名称重复,请调整" |
| 菜品分类 | 必填 | 下拉框 | - | 数据来源分类管理的菜品分类,根据分类顺序正序排列。 | - | - |
| 口味选择 | 选填 | 多选框 | - | 最多不超过4个口味 | - | - |
| 价格 | 必填 | 输入框 | 1-8 | 数字,可以有小数点后2位小数 | - | 不符合限制提示"菜品价格格式有误,请输入大于零且最多保留两位小数的金额" |
| 图片 | 必填 | 图片上传 | 2M | 图片大小不超过2M 仅能上传PNG JPG JPEG类型图片 建议上传200200或300300尺寸的图片 | - | 图片过大,上传失败 格式错误,上传失败 |
| 菜品描述 | 选填 | 输入框 | 0-200 | 汉字、字母大小写、阿拉伯数字 | - | 不符合限制提示,"菜品描述输入不符,请输入少于200个字"; |

套餐管理

|------|-------|------|-------|---------------------------------------------------------|-------|---------------------------------------|
| 字段名称 | 必填/选填 | 类型 | 长度限制 | 输入限制 | 是否可重复 | 提示话术 |
| 套餐名称 | 必填 | 输入框 | 2-20 | 汉字、字母大小写、阿拉伯数字 | 不可重复 | 不符合限制提示,"套餐名称输入不符" 套餐重复提示"套餐名称重复,请调整" |
| 套餐分类 | 必填 | 下拉框 | - | 数据来源分类管理的套餐分类,根据分类顺序正序排列。 | - | - |
| 价格 | 必填 | 输入框 | 1-8 | 数字,可以有小数点后2位小数 | - | 不符合限制提示"套餐价格格式有误,请输入大于零且最多保留两位小数的金额" |
| 套餐菜品 | 必填 | 多选框 | - | - | - | - |
| 图片 | 必填 | 图片上传 | 2M | 图片大小不超过2M 仅能上传PNG JPG JPEG类型图片 建议上传200200或300300尺寸的图片 | - | 图片过大,上传失败 格式错误,上传失败 |
| 套餐描述 | 选填 | 输入框 | 0-200 | 汉字、字母大小写、阿拉伯数字 | - | 不符合限制提示,"套餐描述输入不符,请输入少于200个字"; |

菜品-套餐表

多表查询

概述

复制代码
SELECT * FROM tb_emp,tb_dept WHERE tb_emp.dept_id = tb_dept.id;

内连接

表名过长可以起别名来代替。

sql 复制代码
-- ====================== 内连接 ======================
-- A. 查询员工的姓名,及所属的部门名称(隐式内连接实现)
SELECT tb_emp.`name`,tb_dept.`name` FROM tb_emp,tb_dept WHERE tb_emp.dept_id = tb_dept.id;
SELECT e.`name`,d.`name` FROM tb_emp e,tb_dept d WHERE e.dept_id = d.id;
-- B. 查询员工的姓名,及所属的部门名称(显式内连接实现)
SELECT tb_emp.`name`,tb_dept.`name` FROM tb_emp INNER JOIN tb_dept ON tb_emp.dept_id = tb_dept.id;

外连接

左表为表1,右表为表2。

以左表为基准,会完全包含左表的数据,也包含两张表交集部分的数据,而右外连接就是以右表为基准,完全包含右表的数据,以及两张表交集部分的数据。

sql 复制代码
-- ================================== 外连接 ==================================
-- A. 查询员工表 所有 员工的姓名,和对应的部门名称(左外连接)
SELECT e.`name`,d.`name` FROM tb_emp e LEFT JOIN tb_dept d ON e.dept_id = d.id; 
-- B. 查询部门表 所有 部门的名称,和对应的员工名称(右外连接)
SELECT e.`name`,d.`name` FROM tb_emp e RIGHT JOIN tb_dept d ON e.dept_id = d.id; 
-- 也可转化为左外连接 查询部门表 所有 部门的名称,和对应的员工名称
SELECT e.`name`,d.`name` FROM tb_dept d LEFT JOIN tb_emp e ON e.dept_id = d.id; 

子查询

标量子查询&列子查询

sql 复制代码
-- ================================== 子查询 ==================================
-- 标量子查询
-- A. 查询 "教研部" 的所有员工信息
-- a. 查询 教研部 的部门ID - tb_dept
select id from tb_dept where name = '教研部';
-- b. 再查询该部门ID下的员工信息 - tb_emp
SELECT * FROM tb_emp WHERE dept_id = 2;
SELECT * FROM tb_emp WHERE dept_id = (select id from tb_dept where name = '教研部');
-- B. 查询在 "方东白" 入职之后的员工信息
-- a. 查询"方东白"的入职时间
SELECT entrydate FROM tb_emp WHERE `name` = "方东白";
-- b. 查询在该入职时间之后的所有员工信息,即小于该入职时间
SELECT * FROM tb_emp WHERE entrydate > "2012-11-01";
SELECT * FROM tb_emp WHERE entrydate > (SELECT entrydate FROM tb_emp WHERE `name` = "方东白");
-- 列子查询
-- A. 查询 "教研部" 和 "咨询部" 的所有员工信息
-- a. 查询 "教研部" 和 "咨询部" 的部门ID
SELECT id FROM tb_dept WHERE `name` =  "教研部" OR `name`="咨询部";
-- b. 根据部门ID,查询该部门下的员工信息
SELECT * FROM tb_emp WHERE dept_id IN (2,3);
SELECT * FROM tb_emp WHERE dept_id IN (SELECT id FROM tb_dept WHERE `name` =  "教研部" OR `name`="咨询部");

行子查询&表子查询

子查询

行子查询

子查询返回的结果是一行(可以是多列).

用的操作符:=,<>,in,no

表子查询

子查询返回的结果是多行多列,常作为临时表

常用的操作符:in

sql 复制代码
-- 行子查询
-- A. 查询与 "韦一笑" 的入职日期 及 职位都相同的员工信息;
-- a. 查询 "韦一笑" 的入职日期 及 职位
select entrydate,job from tb_emp where name = '韦一笑';
-- b. 查询与其入职日期 及 职位都相同的员工信息;
SELECT * FROM tb_emp WHERE  entrydate = '2007-01-01' AND job = 2;
SELECT * FROM tb_emp WHERE  entrydate = (select entrydate from tb_emp where name = '韦一笑') AND job = (select job from tb_emp where name = '韦一笑');
SELECT * FROM tb_emp WHERE  (entrydate,job) = ('2007-01-01',2);
SELECT * FROM tb_emp WHERE  (entrydate,job) = (select entrydate,job from tb_emp where name = '韦一笑');
-- 表子查询
-- A. 查询入职日期是 "2006-01-01" 之后的员工信息,及其部门名称
-- a. 查询入职日期是 "2006-01-01" 之后的员工信息
select * from tb_emp where entrydate > '2006-01-01';
-- b. 查询这部分员工信息及其部门名称 - tb_dept
SELECT e.*,d.`name` FROM (select * from tb_emp where entrydate > '2006-01-01') e ,tb_dept d WHERE e.dept_id = d.id;

案例

sql 复制代码
-- 需求:
-- 1. 查询价格低于 10元 的菜品的名称、价格 及其 菜品的分类名称 .
-- 表:dish category
-- SQL: 默认使用隐式内连接
SELECT d.`name`,d.price,c.`name` FROM dish d,category c WHERE d.category_id = c.id AND d.price < 10;
-- 2. 查询所有价格在 10元(含)到50元(含)之间 且 状态为'起售'的菜品,展示出菜品的名称、价格 及其 菜品的分类名称 (即使菜品没有分类,也需要将菜品查询出来)
-- 表:
-- SQL:

-- 3. 查询每个分类下最贵的菜品,展示出分类的名称、最贵的菜品的价格 .
-- 表:dish category
-- SQL:
SELECT c.`name`,MAX(d.price) FROM dish d, category c WHERE d.category_id = c.id GROUP BY c.`name`;
-- 4. 查询各个分类下 菜品状态为 '起售',并且 该分类下菜品总数量大于等于3 的 分类名称 .
-- 表:dish category
-- SQL:
SELECT
	c.`name`,
	COUNT(*) 
FROM
	dish d,
	category c 
WHERE
	d.category_id = c.id 
	AND d.`status` = 1
GROUP BY
	c.`name` 
HAVING
	COUNT(*)>= 3;
-- 5. 查询出 "商务套餐A" 中包含了哪些菜品 (展示出套餐名称、价格,包含的菜品名称、价格、份数) .
-- 表:dish setmeal setmeal_dish
-- SQL:
SELECT s.`name`,s.price,d.`name`,d.price,sd.copies FROM dish d,setmeal s,setmeal_dish sd WHERE s.id = sd.setmeal_id AND sd.dish_id = d.id AND s.`name`="商务套餐A";
-- 6. 查询出低于菜品平均价格的菜品信息 (展示出菜品名称、菜品价格) .
-- 表:dish
-- SQL:
-- 计算平均价格
SELECT AVG(dish.price) FROM dish;
-- 判断低于该平均价格的菜品信息
SELECT * FROM dish d WHERE d.price < (SELECT AVG(dish.price) FROM dish);

事务

介绍与操作

sql 复制代码
-- ================================== 事务 ==================================
-- 开启事务
start transaction ;

-- 删除部门
delete from tb_dept where id = 3;

-- 删除部门下的员工 语句正确
delete from tb_emp where dept_id = 3;

-- 提交事务
commit;

-- 回滚事务
rollback ;

-- ================================== 事务 ==================================
-- 开启事务
start transaction ;

-- 删除部门
delete from tb_dept where id = 2;

-- 删除部门下的员工 语句错误,不能正常删除
delete from tb_emp where dept_id == 2;

-- 提交事务
commit;

-- 回滚事务
rollback ;

select * from tb_dept;
select * from tb_emp;

一旦出现异常之后,我们直接通过roll back,就可以将删除掉的数据呢再恢复回来,从而保证在操作前后数据是一致的,那这就是事物一组操作要么同时成功,要么同时失败。

四大特性

索引

介绍

sql 复制代码
-- ================================== 索引 ==================================
select * from tb_sku where sn = '100000003145003'; -- 13s

select count(*) from tb_sku; -- 6000000

create index idx_sku_sn on tb_sku(sn);

select * from tb_sku where sn = '100000003145003'; -- 6ms

结构

B+Tree(多路平衡搜索树)重要特点归纳

  1. 多路特性
  • 每个节点可存储多个键(key),有( n )个键就对应( n )个指针,指向子节点(磁盘块/页)
  • 与二叉树不同,二叉树一个节点仅存1个键,而B+Tree的"多路"体现为单个节点可拥有多个子节点,大幅减少树的高度,提升查询效率。
  1. 节点功能区分
  • 非叶子节点 :仅用于索引、引导数据查找,不存储具体数据
  • 叶子节点 :存储所有键和对应的数据 ,且所有键都会在叶子节点中出现(如根节点的键会在叶子节点重复出现)。
  1. 叶子节点的有序性与链表结构
  • 叶子节点中的元素按从小到大的顺序排序
  • 叶子节点之间形成双向链表,可通过上一个元素找到下一个元素,便于范围查询。
  1. 磁盘管理关联
  • 数据库中,节点对应"页(磁盘块)",页是磁盘管理的最小单位,大小为16KB。

语法

sql 复制代码
-- 创建:为tb_emp表的name字段建立一个索引.
create index idx_emp_name on tb_emp(name);

-- 查询:查询 tb_emp 表的索引信息.
show index from tb_emp;

-- 删除:删除 tb_emp 表中name字段的索引.
drop index idx_emp_name on tb_emp;

这篇文章就先更到这里,接下来的内容可查看我的下一篇博客,感谢观看,希望对你有帮助。

相关推荐
C雨后彩虹2 小时前
二维伞的雨滴效应
java·数据结构·算法·华为·面试
一路往蓝-Anbo2 小时前
C语言从句柄到对象 (八) —— 当对象会说话:观察者模式与事件链表
c语言·开发语言·数据结构·stm32·单片机·观察者模式·链表
polarislove02142 小时前
9.5 [定时器]输入捕获-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
oMcLin2 小时前
Ubuntu 22.04 Docker 容器启动失败:解决 Overlay2 存储驱动冲突
java·ubuntu·docker
童话名剑2 小时前
Inception网络(吴恩达深度学习笔记)
网络·笔记·深度学习
GIOTTO情2 小时前
舆情监测核心模块实战:从基础采集到智能优化
开发语言·python
思成Codes2 小时前
Golang并发编程——CSP模型
开发语言·后端·golang
代码不停2 小时前
MySQL索引和视图
数据库·mysql
郑泰科技2 小时前
SpringBoot项目实践:之前war部署到服务器好用,重新打包部署到服务器报404
服务器·spring boot·后端