Mysql进阶指南:基础与数据库设计实战

本文深入探讨SQL的注释技巧、数据完整性原则,重点讲解主表与从表的概念及外键的应用,包括严格限制、置空操作和级联操作等三种外键处理方式,并介绍了解决主键冲突的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在数据库管理与开发的广阔领域中,SQL(Structured Query Language)作为与数据库交互的标准语言,其重要性不言而喻。本指南不仅深入解析SQL的基础语法,如注释、数据完整性、表关系与外键操作等,还细致探讨了数据库设计的核心原则与步骤,旨在帮助读者从理论到实践全面掌握SQL与数据库设计的精髓。从基础的SQL注释开始,我们逐步深入到数据完整性、主从表关系、外键操作及其实体间复杂关系的理解,再到数据库设计的规范化与实战例题,每一章节都精心编排,力求让读者在理解理论知识的同时,能够迅速应用于实际开发中。此外,本指南还涵盖了查询语句的高级技巧,如模糊查询、联合查询等,助您轻松应对各种复杂的数据库查询需求。无论您是SQL初学者,还是希望提升数据库设计与查询技能的开发者,本指南都将是您不可或缺的参考资源。

1、SQL注释

  1. 单行注释
    -- 注释说明 或 # 注释说明
  2. 多行注释
    /* */

在这里插入图片描述


2、数据完整性

  1. 实体完整性:
    • 主键约束
    • 唯一约束
    • 标识列
  2. 域完整性:
    • 数据类型约束
    • 非空约束
    • 默认值约束
  3. 引用完整性
    • 主外键约束
  4. 自定义完整性
    • 存储过程
    • 触发器

3、主表和从表

  1. 主表中没有的,从表不允许插入。
  2. 从表中有的,主表中不允许删除。
  3. 删除主表中,先删从表。

4、外键

外键只有在nnodb引擎才能支持外键。外键是从表中的公共字段。

  1. 创建主表:
    在这里插入图片描述

  2. 创建从表:
    在这里插入图片描述
    主表中没有的,从表不允许插入:
    在这里插入图片描述
    先插入主表的数据,再插入从表数据:
    在这里插入图片描述
    从表中有的,主表中不允许删除(要先删从表再删主表):
    在这里插入图片描述
    通过修改表的时候添加外键:
    alter table 从表名 add foreign key(公共字段) references 主表名(公共字段)

    删除外键,通过外键的名字删除外键:
    在这里插入图片描述

4.1 三种外键操作

4.1.1 严格限制

  1. 主表中没有的,从表不允许插入。
  2. 从表中有的,主表中不允许删除。
  3. 删除主表中,先删从表。

4.1.2 置空操作(set null)

如果主表记录删除,或关联字段更新,则从表外键字段被设置为null。

4.1.3 级联操作(cascade)

如果主表记录删除,则从表记录也被删除,主表更新,从表外键字段也更新。
语法: foreign key(外键字段) references 主表名 (关联字段) [主表记录删除时的动作] [主表记录更新时的动作]
一般说删除时置空,更新时级联。

4.1.4 例题与小结

  1. 例题
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    现在来试试主表删除和更新,从表是否也会删除和更新:
    更新:
    在这里插入图片描述
    删除:
    在这里插入图片描述

  2. 小结
    置空级联操作中外键不能是从表的主键。

4.2 解决插入数据时主键冲突

创建表:

create table ct(
	id char(4) primary key,
	name varchar(20)
	) engine=innodb;

在这里插入图片描述

插入数据:

insert into ct values ('ct01', 'jack');

在这里插入图片描述
当再次插入数据:
在这里插入图片描述
如果插入的主键重复就会报错。

  1. 解决方法一:如果插入的主键重复就执行替换。
    语法: replace into 表名 values ()
    在这里插入图片描述
    使用此语法如果数据不存在,可以直接插入:
    在这里插入图片描述
  2. 解决方法二:
    语法:on duplicate key update
    当插入的值与主键或唯一键有冲突执行update的操作:
    在这里插入图片描述
    推荐使用方法二。

5、实体之间的关系

5.1 一对多(1:N)

在这里插入图片描述

5.2 多对一(N:1)

在这里插入图片描述

5.3 一对一(1:1)

在这里插入图片描述

5.4 多对多(N:N)

在这里插入图片描述

5.5 小结

实现一对一:主键和主键建关系;
实现一对多:主键和非主键建关系;
实现多对多:引入第三张关系表;

6、数据库设计

6.1 数据库设计步骤

  1. 收集信息:与该系统有关人员进行交流、充分理解数据库需要完成的任务
  2. 标识对象(实体 - Entity):标识数据库要管理的关键对象或实体
  3. 标识每个实体的属性(Attribute)
  4. 标识对象之间的关系(Relationship)
  5. 将模型转换成数据库
  6. 规范化

6.2 数据规范化

  1. 第一范式:确保每列原则性
    第一范式的目标是确保每列的原子性,一个字段表示一个含义

  2. 第二范式:非键字段必须依赖于键字段
    第二范式在满足第一范式的前提下,要求每个表只描述一件事情

  3. 第三范式:消除传递依赖
    第三范式在满足第二范式的前提下,除了主键以外的其他列消除传递依赖

  4. 反三范式
    范式越高,数据冗余越少,表越来越多,但是效率又是就越底下为了提高运行效率,可以适当让数据冗余。

6.3 例题

需求:
假设某建筑公司要设计一个数据库,公司的业务规则说明如下:

  1. 公司承担多个工程项目,每一项工程有:工程号、工程名称、施工人员等。
  2. 公司有多名职工,每一名职工有:职工号、姓名、性别、职务。
  3. 公司按照工时和小时工资率支付工资,小时工资率由职工的职务决定

标识实体:

  1. 工程;
  2. 职工;
  3. 工时;
  4. 小时工资率;

共有四个表:
在这里插入图片描述

7、查询语句

语法: select [选项] 列名 [from 表名] [where 条件] [group by 分组] [order by 排序] [having 条件] [limit 限制]
测试代码:

create table stutable (
  stuNo char(6) primary key,
  stuName varchar(10) not null,
  stuSex char(2) not null,
  stuAge tinyint not null,
  stuSeat tinyint not null,
  stuAddress varchar(10) not null,
  ch tinyint,
  math tinyint
) charset=gbk;

insert into stutable values ('01','康康', '男', 20,1, '厦门', 90, null);
insert into stutable values ('02','西西', '女', 20,2, '上海', 88, 99);
insert into stutable values ('03','张三', '男', 20,3, '福州', 88, 99);
insert into stutable values ('04','李四', '男', 21,4, '龙岩', 90, 90);
insert into stutable values ('05','王五', '男', 19,5, '北京', 91, 90.5);
insert into stutable values ('06','婷婷', '女', 19,6, '河南', 91.5, 90.3);
insert into stutable values ('07','芳芳', '女', 19,7, '厦门', 99.5, 99.5);
insert into stutable values ('08','赵六', '男', 21,8, '福州', 93.5, 92.5);

在这里插入图片描述
在这里插入图片描述

7.1 字段表达式

可以直接输出内容:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以输出mysql自带的一些函数,例如随机数rand():
在这里插入图片描述
可以通过as给字段去别名:
在这里插入图片描述
在这里插入图片描述

7.2 from子句

from:来自,from后面跟的是数据源。数据源可以有多个,返回笛卡尔积。
插入测试表:
在这里插入图片描述
测试多个数据源:在这里插入图片描述
多个数据源返回笛卡尔积:
在这里插入图片描述

7.3 dual表

dual表是一个伪表,在有些特定情况下,没有具体的表的参与,但是为了包装select语句的完整又必须要一个表名,这时候就使用伪表。
在这里插入图片描述

7.4 where子句

where后面跟的是条件,在数据源中进行筛选。返回条件为真记录。where后面跟着是条件语句,如果为真则返回,例如where 1将会把所有记录返回,where 0 则一条都不会返回。

MySQL支持的运算符含义

| 大于
< | 小于
= | 大于等于
<= | 小于等于
= | 等于
!= | 不等于
and | 与
or | 或
not | 非
in 、not in | (不在)在
between and 、 not between and | (不)在什么的什么之间
is null 、 is not null | (不)是为空
例题:

  1. 查找语文成绩高于90的学生:
    在这里插入图片描述
  2. 查找语文和数学都高于90的:
    在这里插入图片描述
  3. 查询语文或数学低于90分的同学:
    在这里插入图片描述
  4. 查找厦门的学生(sql语句不区分大小写):
    在这里插入图片描述
    通过in:
    在这里插入图片描述
  5. 查找不是厦门的学生(sql语句不区分大小写):
    在这里插入图片描述
    在这里插入图片描述
  6. 查找年龄在19 - 20之间的学生:
    在这里插入图片描述
    利用between and:
    在这里插入图片描述
  7. 查找年龄不在19 - 20之间的学生:
    在这里插入图片描述
  8. 查找缺考的学生:
    在这里插入图片描述

7.5 聚合函数和分组查询(group by)

将查询的结果分组,分组查询目的在于统计数据。

7.5.1 聚合函数

  1. sum() 求和
  2. avg() 求平均数
  3. max() 求最大值
  4. min() 求最小值
  5. count() 求记录数

例题:
1、求语文总分:
在这里插入图片描述
2、求数学最大值:
在这里插入图片描述
3、语文平均分:
在这里插入图片描述

7.5.2 分组查询

语法:select 分组字段,取值函数 as 别名 from 表名 group by 分组字段;
1、查询男生和女生的各自语文平均分:
在这里插入图片描述
2、查询男生和女生各自多少人:
在这里插入图片描述
3、查询每个地区有多少人:
在这里插入图片描述
4、每个地区的数学平均分:
在这里插入图片描述
5、如果分组字段中放普通字段:
在这里插入图片描述
可以发现只会返回第一项查询到的数据。
总结:

  1. 如果是分组查询,查询字段必须是分组字段和聚合函数。
  2. 查询字段是普通字段,只取第一个值。

可以通过group_concat()函数将同一组的值连接起来显示:
在这里插入图片描述
6、多列数组
在这里插入图片描述

7.6 排序(order by)

asc:升序(默认)
desc:降序
1、按照年龄排序:
在这里插入图片描述
降序:
在这里插入图片描述
2、按年龄降序,如果年龄一样的按照语文成绩进行降序:
在这里插入图片描述

7.7 having条件

having条件就是在结果集上继续进行筛选。
例题:
在这里插入图片描述
在这里插入图片描述
如上图having报错的原因在于,第一次查询了stuname,而having在stuname的基础去查询stusex,stuname肯定没有stusex所以报错了。

where和having的区别:
where是对原始数据进行筛选,having是对记录集进行筛选。

7.8 limit

语法:limit 起始位置, 显示长度
在这里插入图片描述
1、找出语文和数学成绩总分前三名:
在这里插入图片描述
2、找出总分成绩后三名同学数学成绩加2分:
在这里插入图片描述

7.9 查询语句中的选项

查询语句中的选项有两个:
1、all:显示所有数据(默认)
2、distinct:去除结果集中重复的数据
例:
在这里插入图片描述
在这里插入图片描述

8、模糊查询

8.1 通配符

1、_[下划线] 表示任意一个字符
2、% 表示任意字符

8.2 模糊查询(like)

在这里插入图片描述

8.3 联合(union)

将多个表的数据组合到一起
语法: select 语句 from 表1名 union [选项] select 语句 from 表2名 union [选项] select 语句

union的选项也有两个:
1、all:显示所有数据
2、distinct: 去除重复的数据【默认】

union的注意事项:
1、union两边的select语句的字段个数必须是一致的。
2、union两边的select语句的字段名可以不一致,最终按第一个select语句的字段名。
3、union两边的select语句中的数据类型可以不一致。

在学习的MySQL的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你华还是你华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值