Java Web之MySQL: 约束、数据库设计、多表查询、事务

本文介绍了MySQL中的关键概念,包括表约束(主键、唯一、非空、默认和自动增长),外键约束用于表间关联,以及数据库设计中的表关系(一对一、一对多、多对多)。接着讲解了如何进行多表查询,如内连接、外连接和子查询的使用。最后讨论了事务处理的重要性,展示了事务的四大特性,并通过转账操作的例子说明了事务在确保数据一致性中的作用。
摘要由CSDN通过智能技术生成

这里我们来学习一下MySQL的几个知识点:约束、数据库设计、多表查询、事务

1.约束

在这里插入图片描述

1.1 其他约束

我们来通过实例了解一下约束的用法。由于外键约束较为重要,我们等会单独拿出来说。这里先展示一下其他约束:

DROP TABLE
IF
	EXISTS emp;-- 如果有emp表,先将其删除
-- 创建如下的emp表:	
create table emp (
	id int primary key auto_increment,
	ename varchar(50) not null unique,
	joindate DATE not null,
	salary double(7,2) not null,
	bonus double(7,2) default 0
);
select * from emp;

insert into emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8888,5000);

-- 演示主键约束:非空且唯一
insert into emp(id,ename,joindate,salary,bonus) values(null,'张三','1999-11-11',8888,5000);

insert into emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8888,5000);

-- 演示默认约束
insert into emp(id,ename,joindate,salary) values(2,'李四','1993-10-20',8000);
-- 默认奖金为0,但如果写成null就不行
insert into emp(id,ename,joindate,salary,bonus) values(3,'王五','1993-10-20',8000,null);

-- 演示默认自动增长
insert into emp(ename,joindate,salary,bonus) values('赵六','1993-10-20',8000,null);
insert into emp(id,ename,joindate,salary,bonus) values(null,'赵六2','1993-10-20',8000,null);
insert into emp(id,ename,joindate,salary,bonus) values(null,'赵六3','1993-10-20',8000,null);

如果不按照相应的约束操作数据,就会弹出相应的提醒,并且操作不会成功。

1.2 外键约束

在这里插入图片描述
实例:

-- 1.创建dept部门表
CREATE TABLE dept ( id INT PRIMARY KEY auto_increment, dep_name VARCHAR ( 20 ), addr VARCHAR ( 20 ) );
-- 2.创建emp员工表
CREATE TABLE emp (
id INT PRIMARY KEY auto_increment,
NAME VARCHAR ( 20 ),
age INT,
dep_id INT,
-- 将员工表里的dep_id 作为外键 关联 部门表的id主键(fk_demp_dept为外键名)
CONSTRAINT fk_demp_dept FOREIGN KEY ( dep_id ) REFERENCES dept ( id ) 
);
INSERT INTO dept ( dep_name, addr )
VALUES
	( '研发部', '广州' ),
	( '销售部', '深圳' );
INSERT INTO emp ( NAME, age, dep_id )
VALUES
	( '研1', 20, 1 ),
	( '研2', 20, 2 ),
	( '研3', 20, 1 ),
	( '销1', 20, 2 ),
	( '销2', 20, 2 ),
	( '销3', 20, 2 );
SELECT
	* 
FROM
	dept;
SELECT
	* 
FROM
	demp;
-- 删除外键
ALTER TABLE emp DROP FOREIGN KEY fk_demp_dept;
-- 建完表后!!!!添加外键
ALTER TABLE emp ADD CONSTRAINT fk_demp_dept FOREIGN KEY ( dep_id ) REFERENCES dept ( id );

如下就是建立起外键约束的两个表,中间有线连接:
在这里插入图片描述

2.数据库设计

2.1 数据库设计的概念

在这里插入图片描述

2.2 数据库设计什么?

在这里插入图片描述
有哪些表?、表里有哪些字段?这些是较为容易根据用户需求自己设计的。我们来着重讲一下表与表之间的关系:这是需要我们自己进行逻辑的判断来设计的。

2.3 表与表之间的关系

在这里插入图片描述

2.3.1 一对一

相亲app中的用户表和用户详情表:
在这里插入图片描述

2.3.2 一对多(多对一)

员工表和部门表:
在这里插入图片描述
员工表和部门表我们前面在讲外键约束的时候已经讲过了,这里不在赘述。

2.3.3 多对多

订单表和商品表:
在这里插入图片描述

/*
	多对多:
		* 如:订单 和 商品
		* 一个商品对应多个订单,一个订单包含多个商品

	实现方式:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
*/

-- 删除表
DROP TABLE IF EXISTS tb_orders_goods;
DROP TABLE IF EXISTS tb_orders;
DROP TABLE IF EXISTS tb_goods;


-- 订单表
CREATE TABLE tb_orders(
	id int primary key auto_increment,
	payment double(10,2),
	payment_type TINYINT,
	status TINYINT
);

-- 商品表
CREATE TABLE tb_goods(
	id int primary key auto_increment,
	title varchar(100),
	price double(10,2)
);

-- 订单商品中间表
CREATE TABLE tb_orders_goods(
	id int primary key auto_increment,
	orders_id int,
	goods_id int,
	count int
);

-- 查询表
select * from tb_orders;
select * from tb_goods;
select * from tb_orders_goods;
-- 建完表后,添加外键
alter table tb_orders_goods add constraint fk_orders_id foreign key(orders_id) references tb_orders(id);
alter table tb_orders_goods add constraint fk_goods_id foreign key(goods_id) references tb_goods(id);

我们建立了第三方表: 订单商品中间表。并且添加了两个外键,分别关联商品表和订单表的主键。
在这里插入图片描述

总结:三种表关系的实现方式

在这里插入图片描述

3.多表查询

在这里插入图片描述

这里我们已经建好了如下的两张表:
员工表:
在这里插入图片描述
部门表:
在这里插入图片描述
如果我们直接查询两个表 ,

SELECT
	* 
FROM
	emp,
	dept;

会有笛卡尔积个情况 (笛卡尔积:A,B两个集合所有的组合)。
比如这里会出现6*4=24种情况。这就需要我们清除重复数据了:

--  查询emp和dept的数据,清除无效数据: emp.dep_id=dept.did
SELECT
	* 
FROM
	emp,
	dept 
WHERE
	emp.dep_id = dept.did;

3.1 内连接查询

在这里插入图片描述

3.1.1 隐式内连接

我们上面提到的清除重复数据的方法,其实就是隐式内连接:
在这里插入图片描述

3.1.2 显示内连接

-- 显示内连接(一般inner 省略不写)
select * from emp inner join dept on emp.dep_id=dept.did;
select * from emp join dept on emp.dep_id=dept.did;

3.2 外连接查询

在这里插入图片描述

-- 左外连接
-- 查询emp表所有数据和对应的部门信息
SELECT
	* 
FROM
	emp
	LEFT JOIN dept ON emp.dep_id = dept.did;
-- 右外连接
-- 查询dept表所有数据和对应的员工信息
SELECT
	* 
FROM
	emp
	RIGHT JOIN dept ON emp.dep_id = dept.did;
-- 相当于dept表的左外连接
SELECT
	* 
FROM
	dept
LEFT JOIN emp ON emp.dep_id = dept.did;

可以看出左外连接和右外连接的区别不大:不论是左外连接还是右外连接,只要把两个表的位置调换就能实现另一种。因此我们一般习惯用左外连接

3.3 子查询

子查询的含义:
是指在查询中嵌套查询,我们就称嵌套的查询为子查询。
子查询分类:在这里插入图片描述
实例:
这里的表还是我们刚开始讲多表查询时的emp表和dept表。

-- 1.查询猪八戒的工资(一步步查询)
SELECT
	salary 
FROM
	emp 
WHERE
	NAME = '猪八戒';
-- 2.查询工资高于猪八戒的员工信息(一步步查询)
SELECT
	* 
FROM
	emp 
WHERE
	salary > 3600;
-- 嵌套变为子查询:
SELECT
	* 
FROM
	emp 
WHERE
	salary > ( SELECT salary FROM emp WHERE NAME = '猪八戒' );
-- 查询财务部和市场部所有员工的信息
-- 1.(一步步查询)
SELECT
	did 
FROM
	dept 
WHERE
	dname = '财务部' 
	OR dname = '市场部';
-- 2.(一步步查询)
SELECT
	* 
FROM
	emp 
WHERE
	dep_id IN ( 2, 3 );
-- 嵌套变为子查询:
SELECT
	* 
FROM
	emp 
WHERE
	dep_id IN ( SELECT did FROM dept WHERE dname = '财务部' OR dname = '市场部' );
-- 查询入职日期是'2011-11-11'之后的员工信息和部门信息
-- 1.(一步步查询)
SELECT
	* 
FROM
	emp 
WHERE
	join_date > '2011-11-11';
-- 2.(一步步查询)
SELECT
	* 
FROM
	emp,
	dept 
WHERE
	emp.dep_id = dept.did;
-- 嵌套变为子查询:
SELECT
	* 
FROM
	( SELECT * FROM emp WHERE join_date > '2011-11-11' ) t1,
	dept 
WHERE
	t1.dep_id = dept.did;

4.事务

4.1 事务简介及实例

在这里插入图片描述
我们先来创建这样的一张account表:
在这里插入图片描述
我们先让李四给张三转500,但是在李四转钱和张三赚钱之间写个错误(就写:出错了…)

-- 转账操作
-- 1.查询李四的金额
-- 2.李四金额-500
UPDATE account 
SET money = money - 500 
WHERE
	NAME = '李四';
出错了...
-- 3.张三金额+500
UPDATE account 
SET money = money + 500 
WHERE
	NAME = '张三';

这时所有用户查询的都会是:只有李四少了500块钱,而张三没多。
在这里插入图片描述
但是当我们开启了事务之后:

-- 转账操作
-- 开启事务
BEGIN;
-- 1.查询李四的金额
-- 2.李四金额-500
UPDATE account 
SET money = money - 500 
WHERE
	NAME = '李四';
--出错了...-- 3.张三金额+500
UPDATE account 
SET money = money + 500 
WHERE
	NAME = '张三';

开启事务后,修改将变成临时性的。如果不提交或回滚,其他用户查询不到修改。也就是说,如果再出现错误,只有我们这里的查询是这个,并且会为我们提醒来让我们修正错误。
在这里插入图片描述
而其它用户的查询都是这个:
在这里插入图片描述
不会再让李四凭空少500块钱了!!!
了解了事务开启后,我们再来看一下事务的全过程:

-- 转账操作
-- 开启事务(开启事务后,修改将变成临时性的。如果不提交或回滚,其他用户查询不到修改)
BEGIN;
-- 1.查询李四的金额
-- 2.李四金额-500
UPDATE account 
SET money = money - 500 
WHERE
	NAME = '李四';
--出错了...-- 3.张三金额+500
UPDATE account 
SET money = money + 500 
WHERE
	NAME = '张三';
COMMIT;-- 提交事务(确认无误后提交事务)
ROLLBACK;-- 回滚事务(回滚到开启事务的时候)

4.2 事务的四大特征

在这里插入图片描述

4.3 MySQL的事务提交机制

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值