MySQL增删查改(进阶)

目录

数据库约束

表的设计 

查询操作的进阶

查询搭配插入使用

聚合查询

1>count(*)

2>sum(*)

3>avg(*)

4>max(*)

5>min(*)

group by分组分别进行聚合查询

联合查询 / 多表查询[重点]

外连接

自连接

子查询

合并查询

小结: 


数据库约束

有时候对数据库的数据有一定要求, 相对于计算机来说, 人不靠谱, 数据库自动对数据的合法性进行校验检查的一系列机制, 目的是为了保证数据库中避免被插入/修改一些非法数据

MySQL中提供了一下约束:

NOT NULL : 指定某列不能存储NULL值

UNIQUE: 保证某列的每行必须有唯一的值

DEFAULT: 规定没有给列赋值时的默认值

PRIMARY KEY: NOT NULL 和 UNIQUE 的结合, 唯一标识

FOREIGN KEY: 保证一个表中的数据匹配另一个表中的值的参照完整性

CHECK: 保证列中的值符合指定的条件(了解)

举个例子:创建一个数据库, 和一个学生表

NOT NULL : 指定某列不能存储NULL值

这时可以加入null这个数据

现在删除这个表加入约束条件 NOT NULL, 重新进行上述操作

添加失败, 不但插入不能加入NULL数据, 修改也不行.

显示修改失败.

UNIQUE: 保证某列的每行必须有唯一的值

如图:重新创建一个学生表

然后里面可以有重复的数据, 现在创建一个加入约束条件的表,  重复上述操作.

这时一个数据只能进行一次插入, 同样" 修改 " 操作也会限制. 

unique 约束, 会让后续插入/ 修改数据的时候都会触发一次查询操作, 通过这个查询来确定这个记录是否已经存在, 数据引入约束后, 执行效率就会受到影响, 可能降低很多. 这就意味着数据库是比较慢的系统, 成为一整个系统的" 性能瓶颈 ".

DEFAULT: 规定没有给列赋值时的默认值

在第五列, 默认的默认值的值时null通过default约束修改默认值

这是修改过后的值.

后续插入数据的时候, default 就会在没有显式指定插入的值时生效了.如图:

上述设置约束都是先删除表再重新创建表, 也能不删除表直接设置约束, 但比较麻烦.

一个数据可以有多个约束

PRIMARY KEY: NOT NULL 和 UNIQUE 的结合, 唯一标识(最重要的约束)

一张表里面只能有一个 primary key , 一张表里的纪录只能有一个作为身份标识的数据, 否则会报错.

虽然只能有一个主键, 但是主键不一定只是一个列, 也可以用多个列构成主键, (联合主键), 这个了解即可.

对于带有主键的表来说, 每次插入数据 / 修改数据, 也会涉及到进行先查询的操作.mysql 会把带有unique和primary key的列自动生成索引, 从而加快查询速度.

如何保证主键唯一呢?

mysql提供了 " 自增主键 "的机制

主键经常使用int / bigint 作为主键

插入数据时数据库服务器分配一个主键, 从1开始, 自己也可以指定

这时插入一个记录, 自动从一开始.我们指定一个10id插入后, 再次输入空值后, 选择最大的数值开始继续往后分配.

此处id的自动分配有局限性, 如果是单个MySQL服务器没问题, 如果时分布式系统(就是多台机器),多个MySQL服务器构成的集群, 依靠自主增键就不行了, 分布式系统中生成唯一 id 的算法有很多, 公式: id = 时间戳 + 机房编号/主机编号 + 随机因子

FOREIGN KEY: 保证一个表中的数据匹配另一个表中的值的参照完整性

创建班级表, id和name, 其中id为主键, 创建学生表, id, name和 classId, 一个学生对应一个班级, 一个班级对应多个学生,  id为主键, classId为外键 其中class表称为父表. student表 称为子表

其中froeign key(classId) 中的classId为当前表中的, 后面的值class表中的

针对这个插入操作, 会触发对class表的查询, 看插入的数据在class中是否存在,修改操作同样如此

注意:

1>对父表进行修改/删除操作, 如果当前被修改/删除的值, 已经被子表引用了, 这样的操作也会失败, 外键约束要始终保持

2>如果想要删除父表, 需要先删除子表

3>指定外键约束的时候, 要求父表被关联的这一列得是主键或者 unique

表的设计 

两个要点:

1> 梳理清楚需求中的" 实体 "  

2> 确定好实体之间的关系

实体就是对象, 每个实体一个表, 表的列对应实体的属性

实体之间的关系三种, 一对一, 一对多, 多对多

1> 一对一 : 一个学生拥有一个账号, 一个账号只能被一个学生拥有

2> 一对多: 一个班级拥有多个学生, 一个学生只能拥有一个班级

3> 多对多: 一个学生拥有多个课程, 一个课程拥有多个学生

查询操作的进阶

查询搭配插入使用

把一个查询语句的查询结果插入

如图: 创建s1和s2然后把s的值放入s2中,刚开始为空

插入之后:

注意: 要求查询出来的结果集合, 列数/类型要和插入的表匹配;

聚合查询

表达式查询是针对 列 和 列 之间进行运算的

聚合查询相当于在 行 和 行 之间进行运算的

MySQL提供一些聚合函数进行运算

举个例子: 先创建一个表, 如图:

1>count(*)

获取行数, 先执行select *在针对结果几个进行统计

注意:

1) 如果当前列里面有null就不同了

2) 指定具体列可以去重

如图:

name那一列有null显示查出了7行

数学那一列有两个98, 使用 distinct 指定这一列时会去重

2>sum(*)

把这一列算数相加

sum(列)

sum(表达式)

3>avg(*)

4>max(*)

5>min(*)

group by分组分别进行聚合查询

针对指定的列进行分组, 把这一列中, 值相同的行, 分到一组中, 得到若干个组, 针对这些组分别使用聚合函数.

举个例子:如图

如果针对所有人算薪资的平均值是不准的, 应该让每个职位的人分组后在计算

往往进行分组要和聚合函数搭配使用. 

注意:

使用group by的时候, 还可以搭配条件, 需要区分清楚, 该条件是分组之前的条件还是分组之后的条件

例子:

1> 查询每个岗位的平均工资, 但是排除张三  (分组条件值之前)

直接使用where即可, where 字句写在group by之前

2> 查询每个岗位的平均薪资, 但是排除平均薪资超过2W的结果 (分组条件之后)

使用 having 描述条件, having 字句写在group by后面

3> 在group by , 可以一个sql同时完成这两类条件的筛选

查询每个岗位的平均薪资, 不算张三, 并且保留 平均值 < 2W的结果

联合查询 / 多表查询[重点]

前面的查询针对一个表, 有些查询需要从多个表中进行查询

关键思路在于" 笛卡尔积 "工作过程

举例:

第一组: A  B  C

第二组: 1  2  3

计算笛卡尔积就是他们的排列组合: A1, A2, A3, B1, B2, B3, C1, C2, C3

笛卡尔积通过排列组合得到更大的表, 笛卡尔积的列数就是两个表的列数相加, 笛卡尔积的行数就是两个表的行数相乘.(其中有的数据是无意义的, 需要通过一个条件(连接条件)把有意义的数据筛选出来)

举个例子:如图,共4张表, 学生, 班级, 课程, 分数(学生和课程之间的关联表)

1> 查询许仙的成绩

先进行笛卡尔积(对学生和分数)

然后筛选学生表的ID和分数表的同学ID相同的行数

选择不同表中的列尽量加上两个表的名称.列名


然后筛选出许仙同学的行

最后针对所需要的信息进行精简

2>查询所有同学的总成绩, 以及同学的个人信息(多表查询和聚合查询综合运用)

先进行笛卡尔积

然后指定连接条件

先精简列

针对上述结果, 再进行 group by 聚合查询

3>列出每个同学, 每门课程课程名字和分数

先进行笛卡尔积

然后指定连接条件

然后精简列

可以使用别名如下图:

外连接

上述操作时" 内连接 ", MySQL进行多表查询, 还可以使用" 外连接 " (左外连接, 右外连接)

如果两个表里面的记录都是存在对应关系, 内连接和外连接的结果是一致的, 如果存在不对应的记录, 内连接和外连接就会出现差别.

这种情况内连接和外连接一样

这种情况两者不一样

使用内连接情况一样

使用左外连接 left join, 保证左侧表的每个数据都会出现在最终结果里

使用右连接 right join, 保证右侧表的每个数据都会出现在最终结果里

自连接

一张表自己和自己进行笛卡尔积

有时候需要去进行行和行之间的比较, 而MySQL只能进行列和列的比较, 使用自连接把行的关系转换成列的关系

举个例子: 显示所有计算机原理比java成绩好的成绩信息

首先进行自连接, 这时需要将score改变为别名, 否则会报错

指定连接条件

精简

子查询

本质上实在" 套娃 ",把多个简单的MySQL拼成一个复杂的MySQL

单行子查询, 返回结果是一行记录

举个例子, 找到不想毕业同学的同班同学

分两步完成

现在一步完成

二者结果一致

多行子查询: 返回多行记录的子查询

举个例子: 查询 " 语文 " 或 " 英文 " 课程的成绩信息

使用联合查询可以解决

使用子查询完成

分两步走

合并查询

把多个sql查询的结果集合, 合并到一起. union关键字

查询id小于3, 或者名字为 " 英文 "的课程

两种的结果一样.后者允许把两个不同的表, 查询结果合并在一起. 但是两个合并的sql的结果集(列的个数和类型) 要一样;(名字不用管)

合并的时候是会去重的, 但是使用union all就不会去重

小结: 

1>  约束中, 主键约束 和外键约束 更难一点, 重点关注, 其他的也要动手敲一下

2> 表的设计(一对一, 一对多, 多对多)

3> 聚合查询 , 熟悉语法

4> 联合查询, 熟悉语法

加油, 很繁琐, 静下心来学.

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值