《JavaWeb篇》01.Mysql看这一篇就够了
目录
一、MySQL基础
陈老老老板
说明:之前系统性的学习java不是很完整,总觉得差些东西,基础不够扎实,所以重新复习一遍,作为马上步入社会的毕业党,在加把劲。
1,数据库相关概念
以前我们做系统,数据持久化的存储采用的是文件存储。存储到文件中可以达到系统关闭数据不会丢失的效果,当然文件存储也有它的弊端。
假设在文件中存储以下的数据:
姓名 年龄 性别 住址
张三 23 男 北京西三旗
李四 24 女 北京西二旗
王五 25 男 西安软件新城
现要修改李四这条数据的性别数据改为男,我们现学习的IO技术可以通过将所有的数据读取到内存中,然后进行修改再存到该文件中。通过这种方式操作存在很大问题,现在只有三条数据,如果文件中存储1T的数据,那么就会发现内存根本就存储不了。
现需要既能持久化存储数据,也要能避免上述问题的技术使用在我们的系统中。数据库就是这样的一门技术。
1.1 数据库
-
存储和管理数据的仓库,数据是有组织的进行存储。
-
数据库英文名是 DataBase,简称DB。
数据库就是将数据存储在硬盘上,可以达到持久化存储的效果。那又是如何解决上述问题的?使用数据库管理系统。
1.2 数据库管理系统
-
管理数据库的大型软件
-
英文:DataBase Management System,简称 DBMS
在电脑上安装了数据库管理系统后,就可以通过数据库管理系统创建数据库来存储数据,也可以通过该系统对数据库中的数据进行数据的增删改查相关的操作。
注:我们平时说的MySQL数据库其实是MySQL数据库管理系统。
通过上面的描述,大家应该已经知道了 数据库管理系统
和 数据库
的关系。那么有有哪些常见的数据库管理系统呢?
1.3 常见的数据库管理系统
接下来对上面列举的数据库管理系统进行简单的介绍:
-
Oracle:收费的大型数据库,Oracle 公司的产品
-
MySQL: 开源免费的中小型数据库。后来 Sun公司收购了 MySQL,而 Sun 公司又被 Oracle 收购
-
SQL Server:MicroSoft 公司收费的中型的数据库。C#、.net 等语言常使用
-
PostgreSQL:开源免费中小型的数据库
-
DB2:IBM 公司的大型收费数据库产品
-
SQLite:嵌入式的微型数据库。如:作为 Android 内置数据库
-
MariaDB:开源免费中小型的数据库
我们课程上学习的是MySQL数据库管理系统,PostgreSQL在一些公司也有使用,此时大家肯定会想以后在公司中如果使用我们没有学习过程的PostgreSQL数据库管理系统怎么办?这点大家大可不必担心,如下图所示:
我们可以通过数据库管理系统操作数据库,对数据库中的数据进行增删改查操作,而怎么样让用户跟数据库管理系统打交道呢?就可以通过一门编程语言(SQL)来实现。
1.4 SQL
-
英文:Structured Query Language,简称 SQL,结构化查询语言
-
操作关系型数据库的编程语言
-
定义操作所有关系型数据库的统一标准,可以使用SQL操作所有的关系型数据库管理系统,以后工作中如果使用到了其他的数据库管理系统,也同样的使用SQL来操作。
2,MySQL
关于Mysql安装的部分可以看我的博客,超级简单:
2.5 MySQL数据模型
关系型数据库:
关系型数据库是建立在关系模型基础上的数据库,简单说,关系型数据库是由多张能互相连接的 二维表 组成的数据库
如下图,订单信息表
和 客户信息表
都是有行有列二维表我们将这样的称为关系型数据库。
接下来看关系型数据库的优点:
-
都是使用表结构,格式一致,易于维护。
-
使用通用的 SQL 语言操作,使用方便,可用于复杂查询。
-
关系型数据库都可以通过SQL进行操作,所以使用方便。
-
复杂查询。现在需要查询001号订单数据,我们可以看到该订单是1号客户的订单,而1号订单是李聪这个客户。以后也可以在一张表中进行统计分析等操作。
-
-
数据存储在磁盘中,安全。
数据模型:
如上图,我们通过客户端可以通过数据库管理系统创建数据库,在数据库中创建表,在表中添加数据。创建的每一个数据库对应到磁盘上都是一个文件夹。比如可以通过SQL语句创建一个数据库(数据库名称为db1),语句如下。该语句咱们后面会学习。
我们可以在数据库安装目录下的data目录下看到多了一个 db1
的文件夹。所以,在MySQL中一个数据库对应到磁盘上的一个文件夹。
而一个数据库下可以创建多张表,我们到MySQL中自带的mysql数据库的文件夹目录下:
而上图中右边的 db.frm
是表文件,db.MYD
是数据文件,通过这两个文件就可以查询到数据展示成二维表的效果。
注:*.frm是描述了表的结构 frm----->frame框架
*.myd保存了表的数据记录 d------>data
*.myi则是表的索引 i------>index
小结:
-
MySQL中可以创建多个数据库,每个数据库对应到磁盘上的一个文件夹
-
在每个数据库中可以创建多个表,每张都对应到磁盘上一个 frm 文件
-
每张表可以存储多条数据,数据会被存储到磁盘中 MYD 文件中
3,SQL概述
了解了数据模型后,接下来我们就学习SQL语句,通过SQL语句对数据库、表、数据进行增删改查操作。
3.1 SQL简介
-
英文:Structured Query Language,简称 SQL
-
结构化查询语言,一门操作关系型数据库的编程语言
-
定义操作所有关系型数据库的统一标准
-
对于同一个需求,每一种数据库操作的方式可能会存在一些不一样的地方,我们称为“方言”
3.2 通用语法
-
SQL 语句可以单行或多行书写,以分号结尾。
-
如上,以分号结尾才是一个完整的sql语句。、
-
MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
同样的一条sql语句写成下图的样子,一样可以运行处结果。
-
注释
-
单行注释: -- 注释内容 或 #注释内容(MySQL 特有)
注意:使用-- 添加单行注释时,--后面一定要加空格,而#没有要求。
注释对命令是没有影响的。
-
多行注释: /* 注释 */
-
3.3 SQL分类
-
DDL(Data Definition Language) : 数据定义语言,用来定义数据库对象:数据库,表,列等
DDL简单理解就是用来操作数据库,表等。
-
-
DML(Data Manipulation Language) 数据操作语言,用来对数据库中表的数据进行增删改
DML简单理解就对表中数据进行增删改。
-
DQL(Data Query Language) 数据查询语言,用来查询数据库中表的记录(数据)
DQL简单理解就是对数据进行查询操作。从数据库表中查询到我们想要的数据。
-
DCL(Data Control Language) 数据控制语言,用来定义数据库的访问权限和安全级别,及创建用户
DML简单理解就是对数据库进行权限控制。比如我让某一个数据库表只能让某一个用户进行操作等。
注意: 以后我们最常操作的是
DML
和DQL
,因为我们开发中最常操作的就是数据。
4,DDL:操作数据库
我们先来学习DDL来操作数据库。而操作数据库主要就是对数据库的增删查操作。
4.1 查询
查询所有的数据库
运行上面语句效果如下:
上述查询到的是的这些数据库是mysql安装好自带的数据库,我们以后不要操作这些数据库。
4.2 创建数据库
-
创建数据库:
运行语句效果如下:
而在创建数据库的时候,我并不知道db1数据库有没有创建,直接再次创建名为db1的数据库就会出现错误。
为了避免上面的错误,在创建数据库的时候先做判断,如果不存在再创建。
-
创建数据库(判断,如果不存在则创建)
运行语句效果如下:
从上面的效果可以看到虽然db1数据库已经存在,再创建db1也没有报错,而创建db2数据库则创建成功。
4.3 删除数据库
-
删除数据库
-
删除数据库(判断,如果存在则删除)
运行语句效果如下:
4.4 使用数据库
数据库创建好了,要在数据库中创建表,得先明确在哪儿个数据库中操作,此时就需要使用数据库。
-
使用数据库
-
查看当前使用的数据库
运行语句效果如下:
5,DDL:操作表
操作表也就是对表进行增(Create)删(Retrieve)改(Update)查(Delete)。
5.1 查询表
-
查询当前数据库下所有表名称
我们创建的数据库中没有任何表,因此我们进入mysql自带的mysql数据库,执行上述语句查看
-
查询表结构
查看mysql数据库中func表的结构,运行语句如下:
5.2 创建表
-
创建表
注意:最后一行末尾,不能加逗号
知道了创建表的语句,那么我们创建创建如下结构的表
运行语句如下:
5.3 数据类型
MySQL 支持多种类型,可以分为三类:
-
数值
tinyint : 小整数型,占一个字节 int : 大整数类型,占四个字节 eg : age int double : 浮点类型 使用格式: 字段名 double(总长度,小数点后保留的位数) eg : score double(5,2)
-
日期
date : 日期值。只包含年月日 eg :birthday date : datetime : 混合日期和时间值。包含年月日时分秒
-
字符串
char : 定长字符串。 优点:存储性能高 缺点:浪费空间 eg : name char(10) 如果存储的数据字符个数不足10个,也会占10个的空间 varchar : 变长字符串。 优点:节约空间 缺点:存储性能底 eg : name varchar(10) 如果存储的数据字符个数不足10个,那就数据字符个数是几就占几个的空间
注意:其他类型参考资料中的《MySQL数据类型].xlsx》
案例:
需求:设计一张学生表,请注重数据类型、长度的合理性
1. 编号
2. 姓名,姓名最长不超过10个汉字
3. 性别,因为取值只有两种可能,因此最多一个汉字
4. 生日,取值为年月日
5. 入学成绩,小数点后保留两位
6. 邮件地址,最大长度不超过 64
7. 家庭联系电话,不一定是手机号码,可能会出现 - 等字符
8. 学生状态(用数字表示,正常、休学、毕业...)
语句设计如下:
5.4 删除表
-
删除表
-
删除表时判断表是否存在
运行语句效果如下:
5.5 修改表
-
修改表名
-
添加一列
-
修改数据类型
-
修改列名和数据类型
-
删除列
6,navicat使用!!!
通过上面的学习,我们发现在命令行中写sql语句特别不方便,尤其是编写创建表的语句,我们只能在记事本上写好后直接复制到命令行进行执行。那么有没有刚好的工具提供给我们进行使用呢? 有。
6.1 navicat概述
-
Navicat for MySQL 是管理和开发 MySQL 或 MariaDB 的理想解决方案。
-
这套全面的前端工具为数据库管理、开发和维护提供了一款直观而强大的图形界面。
-
官网:
6.2 navicat安装
看最上面资源分享位置。
6.3 navicat使用
6.3.1 建立和mysql服务的连接
第一步: 点击连接,选择MySQL
第二步:填写连接数据库必要的信息,点击右下角连接测试。
以上操作没有问题就会出现如下图所示界面:
如果想连接服务器上的数据库可以看我的博客,我当时弄就遇到了很多坑:
6.3.2 操作
连接成功后就能看到如下图界面:
-
修改表结构
通过下图操作修改表结构:
点击了设计表后即出现如下图所示界面,在图中红框中直接修改字段名,类型等信息:
注:双击表,就能查看表中数据。一定要在双击数据库之后,在新建查询,
新建查询,写sql,可以使用Ctrl + R 快捷键运行,也可以选中sql语句进行右键运行,一个查询可以写很多条语句,选中执行就行,不用删除。写完sql可以点击上面美化Sql进行格式化。
-
编写SQL语句并执行
按照如下图所示进行操作即可书写SQL语句并执行sql语句。
7,DML
DML主要是对数据进行增(insert)删(delete)改(update)操作。
7.1 添加数据
-
给指定列添加数据
-
给全部列添加数据
-
批量添加数据
-
练习
为了演示以下的增删改操作是否操作成功,故先将查询所有数据的语句介绍给大家:
7.2 修改数据
-
修改表数据
注意:
修改语句中如果不加条件,则将所有数据都修改!
像上面的语句中的中括号,表示在写sql语句中可以省略这部分
-
练习
-
将张三的性别改为女
-
将张三的生日改为 1999-12-12 分数改为99.99
-
注意:如果update语句没有加where条件,则会将表中所有数据全部修改!
上面语句的执行完后查询到的结果是:
-
7.3 删除数据
-
删除数据
-
练习
8,DQL
下面是黑马程序员展示试题库数据的页面
页面上展示的数据肯定是在数据库中的试题库表中进行存储,而我们需要将数据库中的数据查询出来并展示在页面给用户看。上图中的是最基本的查询效果,那么数据库其实是很多的,不可能在将所有的数据在一页进行全部展示,而页面上会有分页展示的效果,如下:
当然上图中的难度字段当我们点击也可以实现排序查询操作。从这个例子我们就可以看出,对于数据库的查询时灵活多变的,需要根据具体的需求来实现,而数据库查询操作也是最重要的操作,所以此部分需要大家重点掌握。
接下来我们先介绍查询的完整语法:
SELECT
字段列表
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段
HAVING
分组后条件
ORDER BY
排序字段
LIMIT
分页限定
为了给大家演示查询的语句,我们需要先准备表及一些数据:
接下来咱们从最基本的查询语句开始学起。
8.1 基础查询
8.1.1 语法
-
查询多个字段
-
去除重复记录(这个很常用 distinct 关键字)
-
起别名
8.1.2 练习
-
查询name、age两列
-
查询所有列的数据,列名的列表可以使用*替代
上面语句中的*不建议大家使用,因为在这写*不方便我们阅读sql语句。我们写字段列表的话,可以添加注释对每一个字段进行说明,这个是点击上面的美化SQL。
-
而在上课期间为了简约课程的时间,老师很多地方都会写*。
-
-
查询地址信息
执行上面语句结果如下:
从上面的结果我们可以看到有重复的数据,我们也可以使用
distinct
关键字去重重复数据。 -
去除重复记录
-
查询姓名、数学成绩、英语成绩。并通过as给math和english起别名(as关键字可以省略)
8.2 条件查询
8.2.1 语法
-
条件
条件列表可以使用以下运算符
8.2.2 条件查询练习
-
查询年龄大于20岁的学员信息
-
查询年龄大于等于20岁的学员信息
-
查询年龄大于等于20岁 并且 年龄 小于等于 30岁 的学员信息
上面语句中 && 和 and 都表示并且的意思。建议使用 and 。
也可以使用 between ... and 来实现上面需求
-
查询入学日期在'1998-09-01' 到 '1999-09-01' 之间的学员信息
-
查询年龄等于18岁的学员信息
-
查询年龄不等于18岁的学员信息
-
查询年龄等于18岁 或者 年龄等于20岁 或者 年龄等于22岁的学员信息
-
查询英语成绩为 null的学员信息
null值的比较不能使用 = 或者 != 。需要使用 is 或者 is not
8.2.3 模糊查询练习
模糊查询使用like关键字,可以使用通配符进行占位:
(1)_ : 代表单个任意字符
(2)% : 代表任意个数字符
-
查询姓'马'的学员信息
-
查询第二个字是'花'的学员信息
-
查询名字中包含 '德' 的学员信息
8.3 排序查询
8.3.1 语法
上述语句中的排序方式有两种,分别是:
-
ASC : 升序排列 (默认值)
-
DESC : 降序排列
注意:如果有多个排序条件,当前边的条件值一样时,才会根据第二条件进行排序
8.3.2 练习
-
查询学生信息,按照年龄升序排列
-
查询学生信息,按照数学成绩降序排列
-
查询学生信息,按照数学成绩降序排列,如果数学成绩一样,再按照英语成绩升序排列
8.4 聚合函数
8.4.1 概念
将一列数据作为一个整体,进行纵向计算。
如何理解呢?假设有如下表
现有一需求让我们求表中所有数据的数学成绩的总和。这就是对math字段进行纵向求和。
8.4.2 聚合函数分类
函数名 | 功能 |
---|---|
count(列名) | 统计数量(一般选用不为null的列) |
max(列名) | 最大值 |
min(列名) | 最小值 |
sum(列名) | 求和 |
avg(列名) | 平均值 |
8.4.3 聚合函数语法
注意:null 值不参与所有聚合函数运算
8.4.4 练习
-
统计班级一共有多少个学生
上面语句根据某个字段进行统计,如果该字段某一行的值为null的话,将不会被统计。所以可以在count(*) 来实现。* 表示所有字段数据,一行中也不可能所有的数据都为null,所以建议使用 count(*)
-
查询数学成绩的最高分
-
查询数学成绩的最低分
-
查询数学成绩的总分
-
查询数学成绩的平均分
-
查询英语成绩的最低分
8.5 分组查询
8.5.1 语法
注意:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义
8.5.2 练习
-
查询男同学和女同学各自的数学平均分
注意:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义
-
查询男同学和女同学各自的数学平均分,以及各自人数
-
查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组
-
查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组,分组之后人数大于2个的
where 和 having 区别:
-
执行时机不一样:where 是分组之前进行限定,不满足where条件,则不参与分组,而having是分组之后对结果进行过滤。
-
可判断的条件不一样:where 不能对聚合函数进行判断,having 可以。
8.6 分页查询
如下图所示,大家在很多网站都见过类似的效果,如京东、百度、淘宝等。分页查询是将数据一页一页的展示给用户看,用户也可以通过点击查看下一页的数据。
接下来我们先说分页查询的语法。
8.6.1 语法
注意: 上述语句中的起始索引是从0开始
8.6.2 练习
-
从0开始查询,查询3条数据
-
每页显示3条数据,查询第1页数据
-
每页显示3条数据,查询第2页数据
-
每页显示3条数据,查询第3页数据
从上面的练习推导出起始索引计算公式(重中之重):
起始索引 = (当前页码 - 1) * 每页显示的条数
二、MySQL高级
1,约束
上面表中可以看到表中数据存在一些问题:
-
id 列一般是用标示数据的唯一性的,而上述表中的id为1的有三条数据,并且
马花疼
没有id进行标示 -
柳白
这条数据的age列的数据是3000,而人也不可能活到3000岁 -
马运
这条数据的math数学成绩是-5,而数学学得再不好也不可能出现负分 -
柳青
这条数据的english列(英文成绩)值为null,而成绩即使没考也得是0分
针对上述数据问题,我们就可以从数据库层面在添加数据的时候进行限制,这个就是约束。
1.1 概念
-
约束是作用于表中列上的规则,用于限制加入表的数据
例如:我们可以给id列加约束,让其值不能重复,不能为null值。
-
约束的存在保证了数据库中数据的正确性、有效性和完整性
添加约束可以在添加数据的时候就限制不正确的数据,年龄是3000,数学成绩是-5分这样无效的数据,继而保障数据的完整性。
1.2 分类
-
非空约束: 关键字是 NOT NULL
保证列中所有的数据不能有null值。
例如:id列在添加
马花疼
这条数据时就不能添加成功。 -
唯一约束:关键字是 UNIQUE
保证列中所有数据各不相同。
例如:id列中三条数据的值都是1,这样的数据在添加时是绝对不允许的。
-
主键约束: 关键字是 PRIMARY KEY
主键是一行数据的唯一标识,要求非空且唯一。一般我们都会给没张表添加一个主键列用来唯一标识数据。
例如:上图表中id就可以作为主键,来标识每条数据。那么这样就要求数据中id的值不能重复,不能为null值。
-
检查约束: 关键字是 CHECK
保证列中的值满足某一条件。
例如:我们可以给age列添加一个范围,最低年龄可以设置为1,最大年龄就可以设置为300,这样的数据才更合理些。
注意:MySQL不支持检查约束。
这样是不是就没办法保证年龄在指定的范围内了?从数据库层面不能保证,以后可以在java代码中进行限制,一样也可以实现要求。
-
默认约束: 关键字是 DEFAULT
保存数据时,未指定值则采用默认值。
例如:我们在给english列添加该约束,指定默认值是0,这样在添加数据时没有指定具体值时就会采用默认给定的0。
-
外键约束: 关键字是 FOREIGN KEY
外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性。
外键约束现在可能还不太好理解,后面我们会重点进行讲解。
1.3 非空约束
-
概念
非空约束用于保证列中所有数据不能有NULL值
-
语法
-
添加约束
-
删除约束
-
1.4 唯一约束
-
概念
唯一约束用于保证列中所有数据各不相同
-
语法
-
添加约束
-
删除约束
-
1.5 主键约束
-
概念
主键是一行数据的唯一标识,要求非空且唯一
一张表只能有一个主键
-
语法
-
添加约束
-
删除约束
-
1.6 默认约束
-
概念
保存数据时,未指定值则采用默认值
-
语法
-
添加约束
-
删除约束
-
1.7 约束练习
根据需求,为表添加合适的约束
上面一定给出了具体的要求,我们可以根据要求创建这张表,并为每一列添加对应的约束。建表语句如下:
通过上面语句可以创建带有约束的 emp
表,约束能不能发挥作用呢。接下来我们一一进行验证,先添加一条没有问题的数据
-
验证主键约束,非空且唯一
执行结果如下:
从上面的结果可以看到,字段 id
不能为null。那我们重新添加一条数据,如下:
执行结果如下:
从上面结果可以看到,1这个值重复了。所以主键约束是用来限制数据非空且唯一的。那我们再添加一条符合要求的数据
执行结果如下:
-
验证非空约束
执行结果如下:
从上面结果可以看到,ename
字段的非空约束生效了。
-
验证唯一约束
执行结果如下:
从上面结果可以看到,ename
字段的唯一约束生效了。
-
验证默认约束
执行完上面语句后查询表中数据,如下图可以看到王五这条数据的bonus列就有了默认值0。
注意:默认约束只有在不给值时才会采用默认值。如果给了null,那值就是null值。
如下:
执行完上面语句后查询表中数据,如下图可以看到赵六这条数据的bonus列的值是null。
-
验证自动增长: auto_increment 当列是数字类型 并且唯一约束
重新创建 emp
表,并给id列添加自动增长
接下来给emp添加数据,分别验证不给id列添加值以及给id列添加null值,id列的值会不会自动增长:
1.8 外键约束
1.8.1 概述
外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性。
如何理解上面的概念呢?如下图有两张表,员工表和部门表:
员工表中的dep_id字段是部门表的id字段关联,也就是说1号学生张三属于1号部门研发部的员工。现在我要删除1号部门,就会出现错误的数据(员工表中属于1号部门的数据)。而我们上面说的两张表的关系只是我们认为它们有关系,此时需要通过外键让这两张表产生数据库层面的关系,这样你要删除部门表中的1号部门的数据将无法删除。
1.8.2 语法
-
添加外键约束
-
删除外键约束
1.8.3 练习
根据上述语法创建员工表和部门表,并添加上外键约束:
添加数据
此时删除 研发部
这条数据,会发现无法删除。
删除外键
重新添加外键
2,数据库设计
2.1 数据库设计简介
-
软件的研发步骤
-
-
数据库设计概念
-
数据库设计就是根据业务系统的具体需求,结合我们所选用的DBMS,为这个业务系统构造出最优的数据存储模型。
-
建立数据库中的表结构以及表与表之间的关联关系的过程。
-
有哪些表?表里有哪些字段?表和表之间有什么关系?
-
-
数据库设计的步骤
-
需求分析(数据是什么? 数据具有哪些属性? 数据与属性的特点是什么)
-
逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)
如下图就是ER(Entity/Relation)图:
-
-
物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)
-
维护设计(1.对新的需求进行建表;2.表优化)
-
-
表关系
-
一对一
-
如:用户 和 用户详情
-
一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
上图左边是用户的详细信息,而我们真正在展示用户信息时最长用的则是上图右边红框所示,所以我们会将详细信息查分成两周那个表。
-
-
一对多
-
如:部门 和 员工
-
一个部门对应多个员工,一个员工对应一个部门。如下图:
-
-
多对多
-
如:商品 和 订单
-
一个商品对应多个订单,一个订单包含多个商品。如下图:
-
-
2.2 表关系(一对多)
-
一对多
-
如:部门 和 员工
-
一个部门对应多个员工,一个员工对应一个部门。
-
-
实现方式
在多的一方建立外键,指向一的一方的主键
-
案例
我们还是以
员工表
和部门表
举例:经过分析发现,员工表属于多的一方,而部门表属于一的一方,此时我们会在员工表中添加一列(dep_id),指向于部门表的主键(id):
-
建表语句如下:
查看表结构模型图:
-
2.3 表关系(多对多)
-
多对多
-
如:商品 和 订单
-
一个商品对应多个订单,一个订单包含多个商品
-
-
实现方式
建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
-
案例
我们以
订单表
和商品表
举例:经过分析发现,订单表和商品表都属于多的一方,此时需要创建一个中间表,在中间表中添加订单表的外键和商品表的外键指向两张表的主键:
建表语句如下:
查看表结构模型图:
2.4 表关系(一对一)
-
一对一
-
如:用户 和 用户详情
-
一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
-
-
实现方式
在任意一方加入外键,关联另一方主键,并且设置外键为唯一(UNIQUE)
-
案例
我们以
用户表
举例:而在真正使用过程中发现 id、photo、nickname、age、gender 字段比较常用,此时就可以将这张表查分成两张表。
建表语句如下:
查看表结构模型图:
2.5 数据库设计案例
根据下图设计表及表和表之间的关系:
经过分析,我们分为 专辑表
曲目表
短评表
用户表
4张表。
一个专辑可以有多个曲目,一个曲目只能属于某一张专辑,所以专辑表和曲目表的关系是一对多。
一个专辑可以被多个用户进行评论,一个用户可以对多个专辑进行评论,所以专辑表和用户表的关系是 多对多。
一个用户可以发多个短评,一个短评只能是某一个人发的,所以用户表和短评表的关系是 一对多。
3,多表查询
多表查询顾名思义就是从多张表中一次性的查询出我们想要的数据。我们通过具体的sql给他们演示,先准备环境
执行下面的多表查询语句
结果如下:
从上面的结果我们看到有一些无效的数据,如 孙悟空
这个员工属于1号部门,但也同时关联的2、3、4号部门。所以我们要通过限制员工表中的 dep_id
字段的值和部门表 did
字段的值相等来消除这些无效的数据,
执行后结果如下:
上面语句就是连接查询,那么多表查询都有哪些呢?
-
连接查询
-
-
内连接查询 :相当于查询AB交集数据
-
外连接查询
-
左外连接查询 :相当于查询A表所有数据和交集部门数据(左表全显示可以有右表为空的值)
-
右外连接查询 : 相当于查询B表所有数据和交集部分数据(右表全显示可以有左表为空的值)
-
-
-
子查询
3.1 内连接查询
-
语法
内连接相当于查询 A B 交集数据
-
案例
-
隐式内连接
执行上述语句结果如下:
-
查询 emp的 name, gender,dept表的dname
执行语句结果如下:
-
上面语句中使用表名指定字段所属有点麻烦,sql也支持给表指别名,上述语句可以改进为
-
显式内连接
执行结果如下:
-
3.2 外连接查询
-
语法
左外连接:相当于查询A表所有数据和交集部分数据
右外连接:相当于查询B表所有数据和交集部分数据
-
案例
-
查询emp表所有数据和对应的部门信息(左外连接)
执行语句结果如下:
-
结果显示查询到了左表(emp)中所有的数据及两张表能关联的数据。
-
查询dept表所有数据和对应的员工信息(右外连接)
执行语句结果如下:
结果显示查询到了右表(dept)中所有的数据及两张表能关联的数据。
要查询出部门表中所有的数据,也可以通过左外连接实现,只需要将两个表的位置进行互换:
-
3.3 子查询
-
概念
查询中嵌套查询,称嵌套查询为子查询。
什么是查询中嵌套查询呢?我们通过一个例子来看:
需求:查询工资高于猪八戒的员工信息。
来实现这个需求,我们就可以通过二步实现,第一步:先查询出来 猪八戒的工资
第二步:查询工资高于猪八戒的员工信息
第二步中的3600可以通过第一步的sql查询出来,所以将3600用第一步的sql语句进行替换
这就是查询语句中嵌套查询语句。
-
子查询根据查询结果不同,作用不同
-
子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断
-
子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断
-
子查询语句结果是多行多列,子查询语句作为虚拟表
-
-
案例
-
查询 '财务部' 和 '市场部' 所有的员工信息
-
查询入职日期是 '2011-11-11' 之后的员工信息和部门信息
-
3.4 案例
-
环境准备:
-
需求
-
查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
/* 分析: 1. 员工编号,员工姓名,工资 信息在emp 员工表中 2. 职务名称,职务描述 信息在 job 职务表中 3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id */
-
查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
/* 分析: 1. 员工编号,员工姓名,工资 信息在emp 员工表中 2. 职务名称,职务描述 信息在 job 职务表中 3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id 4. 部门名称,部门位置 来自于 部门表 dept 5. dept 和 emp 一对多关系 dept.id = emp.dept_id */
-
查询员工姓名,工资,工资等级
/* 分析: 1. 员工姓名,工资 信息在emp 员工表中 2. 工资等级 信息在 salarygrade 工资等级表中 3. emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary */
-
查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
/* 分析: 1. 员工编号,员工姓名,工资 信息在emp 员工表中 2. 职务名称,职务描述 信息在 job 职务表中 3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id 4. 部门名称,部门位置 来自于 部门表 dept 5. dept 和 emp 一对多关系 dept.id = emp.dept_id 6. 工资等级 信息在 salarygrade 工资等级表中 7. emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary */
-
查询出部门编号、部门名称、部门位置、部门人数
/* 分析: 1. 部门编号、部门名称、部门位置 来自于部门 dept 表 2. 部门人数: 在emp表中 按照dept_id 进行分组,然后count(*)统计数量 3. 使用子查询,让部门表和分组后的表进行内连接 */ -- 根据部门id分组查询每一个部门id和员工数
-
4,事务
4.1 概述
数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。
事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败。
事务是一个不可分割的工作逻辑单元。
这些概念不好理解,接下来举例说明,如下图有一张表:
张三和李四账户中各有100块钱,现李四需要转换500块钱给张三,具体的转账操作为
-
第一步:查询李四账户余额
-
第二步:从李四账户金额 -500
-
第三步:给张三账户金额 +500
现在假设在转账过程中第二步完成后出现了异常第三步没有执行,就会造成李四账户金额少了500,而张三金额并没有多500;这样的系统是有问题的。如果解决呢?使用事务可以解决上述问题:
从上图可以看到在转账前开启事务,如果出现了异常回滚事务,三步正常执行就提交事务,这样就可以完美解决问题。
4.2 语法
-
开启事务
-
提交事务
-
回滚事务
4.3 代码验证
-
环境准备
-
不加事务演示问题
整体执行结果肯定会出问题,我们查询账户表中数据,发现李四账户少了500。
-
-
添加事务sql如下:
上面sql中的执行成功进选择执行提交事务,而出现问题则执行回滚事务的语句。以后我们肯定不可能这样操作,而是在java中进行操作,在java中可以抓取异常,没出现异常提交事务,出现异常回滚事务。
4.4 事务的四大特征
-
原子性(Atomicity): 事务是不可分割的最小操作单位,要么同时成功,要么同时失败
-
一致性(Consistency) :事务完成时,必须使所有的数据都保持一致状态
-
隔离性(Isolation) :多个事务之间,操作的可见性
-
持久性(Durability) :事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
说明:
mysql中事务是自动提交的。
也就是说我们不添加事务执行sql语句,语句执行完毕会自动的提交事务。
可以通过下面语句查询默认提交方式:
SELECT @@autocommit;
查询到的结果是1 则表示自动提交,结果是0表示手动提交。当然也可以通过下面语句修改提交方式
set @@autocommit = 0;
语:
裸体一旦成为艺术,便是最圣洁的。道德一旦沦为虚伪,便是最下流的。
勇敢去做你认为正确的事,不要被世俗的流言蜚语所困扰。
- 点赞
- 收藏
- 关注作者
评论(0)