MySQL(二)-基础操作
一、约束
有时候,数据库中数据是有约束的,比如 性别列,你不能填一些奇奇怪怪的数据~
如果靠人为的来对数据进行检索约束的话,肯定是不行的,人肯定会犯错~因此就需要让计算机对插入的数据进行约束要求!
约束的使用语法:
create 表名 (列名 类型 约束);
#在创建表的时候对某一列数据进行约束操作
在mysql中提供了如下约束:
约束 | 说明 |
---|---|
not null | 某一列的数据不能为null值 |
unique | 某一列中的值唯一 |
default | 规定没有给某列赋值时为默认值 |
primary key | not null 和 unique 的结合。记录身份的标识,一般配合自增主键使用 |
foreign key | 保证一个表中的数据匹配另一个表中的值的参照完整性 |
check | 保证列中的值符合指定条件 |
注意:
使用约束的话,一定会数据库的效率有影响!
由于not null、 unique、default、check比较容易,这里就对主键(primary key)和外键(foreign key) 进行解释。
主键primary key
主键可以理解为记录的身份标识,就像身份证一样是我们每个人的身份标识,既不能为空,又不能重复。
一张表里只能有一个主键,毕竟是身份标识嘛,存在多个了,以谁为准???
虽然主键只能有一个,但是主键不一定是一列,可以用多个列共同构成主键(联合主键)。
由于主键具有unique属性,因此我们一般配合mysql中 ”自增主键” 来使用,也就是会自动分配一个逐个增长的值~
语法:
create table 表名 (列名 类型 primary key auto_increment);
如果手动插入一个数据,此时数据库会与主键最高的值进行比较,如果高了就更新,此后自动分配的值也会从这个最高值进行增长!
拓展:
如果是分布式系统,在同一时间插入了一个数据,此时自增主键就会出错,那么如何处理这种并发场景呢?
一般会使用一个公式来形成主键:
分布式主键值 = 时间戳 + 机房编号/主机号 + 随机因子 此处使用的是字符串拼接操作!!!
前面两个可以防止在同一时间不同机器的的主键冲突,后面的随机因子可以防止同一时间同一机器的主键冲突,但是理论上还是有可能存在冲突的~
外键foreign key
案例引入:
现在我们有两张表,一张是学生表,里面有学号、姓名、班级号字段,另一张表示班级表,里面有班级号、班级名字段。
我们细细观察,可以发现,肯定是先有班级表,学生的班级号才能确定,但是现在突然冒出了一个classId 为 300的学生,但是在我们的班级表中不存在这个班级号,为了防止这种情况发生,我们可以使用外键约束~
语法:
create table 表名 (列名 类型, 列名 类型, ......, foreign key (列名) references 主表名(列名));
#我们创建学生表的时候可以这样写:#create table student (id int, name varchar(20), classId int, foreign key (classId) references class(classId));#student表的classId 的所有数据都要出自于class表的classId这一列,
#也就是说如果class表中没有这个班级号,那么我们插入的学生信息将会报错~
使用外键之后,被约束的表就称为子表, 另一张表相对的就是父表,子表中的那一个字段的数据都要出自父表。当然,力的作用是相互的,约束也不例外,当我们想要删除/修改父表的约束子表的那个字段,如果子表已经引用过了,那么我们将会删除/修改失败
注意:
父表中约束子表的字段必须为主键或者unique!!!
二、表的设计
在实际的场景中,有大量的数据,我们需要明确当前要创建几个表,每个表有什么字段,这些表中是否存在一定的联系。
因此根据实际开发就整理出了三大范式~
一对一
例如:一个学生只有一个账号,一个账号只属于一个学生。
此时我们设计两张表,让其中的一张表存储另一张表的唯一属性,这样我们可以通过这个属性就能找到想要的值了。或者也可以将两张表整合,成为一张表。
一对多
例如:一个学生只能属于一个班级,一个班级可以拥有多个学生。
此时我们设计两张表,将那个“一”的表中添加上“多”的表中的唯一的字段。
补充:
如果是redis这种能够支持数组类型的数据库,我们可以不这样设计,可以使用一个数组类型,用来存储多个学生。如下图:
多对多
例如:一个学生可以选多门课程,一个课程可以被多名学生选择。
此时我们需要再创建一张表来描述这两张表之间的关系。
三、查询增强(进阶)
查询操作有很多的花样,但一般实际开发中最最最常使用的还是前面基础的crud操作。
0x 00 聚合查询
之前的表达式查询是对于一条记录上的列与列之间进行运算的,如果要针对行与行之间进行运算呢?这时候就要用到聚合查询了~
首先来了解一些聚合函数:
函数 | 说明 |
---|---|
count() | 返回查询数据的个数 |
sum() | 返回查询数据的总和,不是数字没意义 |
avg() | 返回查询数据的平均值,不是数字没意义 |
max() | 返回查询数据的最大值,不是数字没意义 |
min() | 返回查询数据的最小值,不是数字没意义 |
语法:
select count([distinct]表达式) from 表名;
select sum([distinct]表达式) from 表名;
select avg([distinct]表达式) from 表名;
select max([distinct]表达式) from 表名;
select min([distinct]表达式) from 表名;
#注意:
#count(*) 和 count(列名)的区别,count(*)会把一条为null的数据也统计进去,而count(列名)则不会
#如果计算字符串的值,需要字符串合法,因为mysql会尝试转成double
0x 01 分组查询
分组查询一般会配合聚合查询,因为分组查询会把几行数据看做是一行,如果不使用聚合查询,那么显示的结果为一组中某一个数据。
举例:
求各班的平均成绩:
那么我们的代码得这样写:
select class_id, avg(socre) from class group by class_id;
使用group by的时候,还可以搭配条件。此时我们需要区分该条件是分组前的,还是分组之后的?
如果是分组前,使用where条件查询
如果是分组后,使用having条件查询
举例:
查询各班平均分,但是学生成绩不能超过100
select class_id, avg(socre) from class where socre <= 100 group by class_id;
查询平均分大于100分的班级
select class_id, avg(score) from class group by class_id having avg(score) > 100;
0x 02 联合查询
联合查询也就是多表查询,就是在多张表上进行查询。但是联合查询也会有一些问题......
联合查询会产生笛卡尔积,也就是说表A中的每一条数据都会与表B中每一条数据进行组合,如果A表中的数据个数为100,表B中的数据个数为100,那么最终会产生100*100条数据。但是仔细观察,会发现有一些数据是“非法”的。笛卡尔积是简单的排列组合,穷举所有情况,因此你我们需要筛选数据~
如果要联合n张表进行查询,那么我们需要使用n-1个连接条件,才不会出现笛卡尔积的现象~
此时就出现了笛卡尔积,但是仔细观察,会发现class_id 不同的数据都组合到了一起,因此我们需要一个连接条件。
select student.class_id, student.name, class.socre from student, class where student.class_id = class.class_id;
由于多表查询一般比较复杂,我们可以按照如下的步骤来写:
1、先进行指定哪个几个表,进行笛卡尔积
2、指定连接条件,去除笛卡尔积
3、精简列数据
以上查询都是基于“内连接“的操作,然而mysql还提供了”外连接“(左外连接,右外连接)
案例引入:
现有如下表
此时student的每一条记录都可以在score表中找到对应,每一个score中记录也可以在student表中找到对应。
此时我们使用外内接或者内连接查询的结果是一样。
但是如果不存在记录,那么内连接与外连接就会天差地别~
外连接分为左外连接和右外连接。
左外连接:以左表为基准,保证左侧表的每个数据都会出现在最终的结果集里,如果右表没有与之对应的记录则显示null。
select 列名 from 表名1 left join 表2 on 连接条件
右外连接:以右表为基准,保证右侧表的每个数据都会出现在最终的结果集里,如果左表没有与之对应的记录则显示null。
select 列名 from 表名1 right join 表2 on 连接条件
我们还可以用集合图来表示这些连接的关系:
补充:
以上我们都是针对于两个表进行联合查询的,但我们甚至还可以将一个表当做两个表来进行联合查询,这样我们就能在一张表中进行 行与行的比较~这种连接方式一般被称为“内连接”。
自连接的查询跟上面的联合查询基本没什么区别,需要注意将两张表进行别名操作~
0x 03 子查询
子查询是将多个简单的SQL语句拼成一个复杂的SQL, 也就是说将某一个查询的结果看做是一张表,然后进行操作,但本质是在套娃。因此我们实际也是可以用简单的查询完成子查询的操作的~ (合成2048?合成复杂SQL!)
语法形式:
select 列名 from 表名 where 列名 = (select 列名 from 表名 where 列名 = (套娃下去....));
0x 04 合并查询
合并查询就是将多个sql的查询结果集 合并在一起。合并的两个sql结果集的列,需要匹配,列的个数和类型得是一致的!合并的时候是会进行去重的,如果不想要去重,得使用 union all
select 列名1 列名2 from 表1 union [all] select 列名3 列名4 from 表2;
最终结果:
相关文章:

MySQL(二)-基础操作
一、约束 有时候,数据库中数据是有约束的,比如 性别列,你不能填一些奇奇怪怪的数据~ 如果靠人为的来对数据进行检索约束的话,肯定是不行的,人肯定会犯错~因此就需要让计算机对插入的数据进行约束要求! 约…...

vue3学习使用笔记
1.学习参考资料 vue3菜鸟教程:https://www.runoob.com/vue3/vue3-tutorial.html 官方网站:https://cn.vuejs.org/ 中文文档: https://cn.vuejs.org/guide/introduction.html Webpack 入门教程:https://www.runoob.com/w3cnote/webpack-tutor…...

微信小程序怎么进行页面传参
微信小程序页面传参的方式有多种,每种方式都有其特定的使用场景和优势。以下是几种常见的页面传参方式,以及它们的具体使用方法和示例: URL参数传值 原理:通过在跳转链接中附加参数,在目标页面的onLoad函数中获取参数…...

隆道出席河南ClO社区十周年庆典,助推采购和供应链数字化发展
5月26日,“河南ClO社区十周年庆典”活动在郑州举办,北京隆道网络科技有限公司总裁助理姚锐出席本次活动,并发表主题演讲《数字化采购与供应链:隆道的探索与实践》,分享隆道公司在采购和供应链数字化转型方面的研究成果…...

NetApp财季报告亮点:全闪存阵列需求强劲,云计算收入增长放缓但AI领域前景乐观
在最新的财季报告中,NetApp的收入因全闪存阵列的强劲需求而显著增长。截至2024年4月26日的2024财年第四季度,NetApp的收入连续第三个季度上升,达到了16.7亿美元,较前一年同期增长6%,超出公司指导中值。净利润为2.91亿美…...

javascript读取本地目录
在JavaScript中,直接读取本地目录的能力受到浏览器安全限制,因为出于隐私和安全考虑,浏览器的JavaScript环境通常不允许直接访问用户的文件系统。然而,随着Web技术的发展,一些现代浏览器引入了File System API或Web Fi…...

Java基础八股
Java基础八股 Java语言Java语言有什么特点Java与C区别Java如何实现跨平台JVMvsJDKvsJRE标识符和关键字的区别是什么自增自减运算符移位运算符continue,break,return的区别是什么final,finally,finalize的区别final关键字的作用时什么 变量 Java语言 Java语言有什么特点 Java是…...
【机器学习300问】102、什么是混淆矩阵?
一、混淆矩阵的定义 混淆矩阵是一种用于评估分类模型性能的评估指标。当模型对数据进行预测并将数据分配到预定义的类别时,混淆矩阵提供了一种直观的方式来总结这些预测与数据实际类别之间的对应关系。具体来说,它是一个表格。 二、分类模型性能评估一级…...

基于SpringBoot3和JDK17,集成H2数据库和jpa
基于SpringBoot3和JDK17,集成H2数据库和jpa 学会用H2数据库,为了快速写出需要处理数据关系的demo。 文章目录 基于SpringBoot3和JDK17,集成H2数据库和jpa工程配置pom.xml文件application.properties文件 练习H2数据库的操作h2数据库的建表自…...

《逆水寒》手游周年庆,热度不减反增引发热议
易采游戏网5月31日最新消息:随着数字娱乐时代的飞速发展,手游市场的竞争愈发激烈。在这样的大背景下,《逆水寒》手游以其独特的古风武侠世界和深度的社交体验,自上线以来便吸引了无数玩家的目光。如今,这款游戏迎来了它…...

Kotlin使用Dagger2但无法生成对应类 Unresolved reference: DaggerMyComponent
最近在使用Dagger2时,遇到这个错误,app/build/generated/source/没有生成对应类,没有生成如下类,网上看了许多博客替换版本,添加dagger2的其他依赖均未成功,最终看到一篇大佬的文章才终于得以解决 解决&am…...

Vue组件通讯⽗组件中通过 provide 来提供变量,然后在⼦组件中通过 inject 来注⼊变量例子
在Vue中,provide 和 inject 主要用于依赖注入,允许祖先组件向其所有子孙组件提供一个依赖,而不论组件层次有多深。这在开发高阶插件/组件库时特别有用。 以下是一个简单的例子,演示了如何在父组件中使用 provide 提供变量&#x…...

教你搞一个比较简单的计时和进度条装饰器
教你搞一个比较简单的计时和进度条装饰器 什么是装饰器为啥要用装饰器呢?上代码!如何使用装饰器效果 什么是装饰器 装饰器的英文是:Decorator。装修的英文是:Decoration。顾名思义就是我们要用装饰器在函数func()上搞点儿事儿&am…...

跑马灯的两种实现方式
方式一:利用元素尺寸变化监听api,计算宽度,得出时间,进行无限次数动画。 优点:能自定义速度(0 - 1)。 <template><div class"box"><i class"iconfont icon-gon…...

OpenAI 的 GPT-4o 是目前最先进的人工智能模型!如何在工作或日常生活中高效利用它?
OpenAI 的 GPT-4o 是目前最先进的人工智能模型!如何在工作或日常生活中高效利用它? 博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大…...

安卓ANR检测、分析、优化面面谈
前言 一个引发讨论的楔子,以下三种现象有什么区别: App停止运行App暂无响应App闪退 答案: 产生原因不同:停止运行是UNCheckExceptionError暂无响应是ANRDialog闪退是CheckExceptionError 本文讨论的主题是ANR的定义、分类、复现…...

“手撕”链表的九道OJ习题
目录 1. 第一题 2. 第二题 3. 第三题 4. 第四题 5. 第五题 6. 第六题 7. 第七题 8. 第八题 9. 第九题 1. 第一题 删除链表中等于给定值 val 的所有节点。OJ链接 思路如下: 相当于链表的removeAll();制定prev和cur,prev记录前一个节点ÿ…...

解决 Git commit 或 Git merge 跑到 VIM 里面去了
像 git commit 分支名字 或 git merge 分支名字这个命令后面最好加上 -m "消息",如果你不加上 -m "消息"的话,它会打开一个程序让你去加上消息,这个程序还是在控制台里面,只不过是 Linux 里面一个叫做 VIM 的…...

营造科技展厅主题氛围,多媒体应用有哪些新策略?
长久以来,展厅作为线下向公众传递信息的窗口,其设计风格与内容主题紧密相连,展现出千姿百态的面貌。然而,随着数字多媒体技术的日新月异,展厅不再仅仅是传统的信息展示平台,而是成为了引领内容展示潮流的风…...

【UML用户指南】-04-从代码到UML的关键抽象
1、关键抽象 声明了一个名为paint的操作,它的实现调用名为drawString的另一个操作,drawString操作负责在指定的位置上打印“Hello,World!”。在通常的面向对象的方式下,drawString是一个名称为g的参数上的一个操作,g的类型是类Gr…...

(2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
LoRA Learns Less and Forgets Less 公和众和号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0. 摘要 1. 引言 2. 背景 3. 实验设置 3.2 使用编码和数学基准测试来衡量学习(目标域…...

【Java】面向对象的三大特征:封装、继承、多态
封装 什么叫封装? 在我们写代码的时候经常会涉及两种角色: 类的实现者 和 类的调用者。 封装的本质就是让类的调用者不必太多的了解类的实现者是如何实现类的, 只要知道如何使用类就行了,这样就降低了类使用者的学习和使用成本&a…...

请问Java8进阶水平中,常用的设计模式有哪些?
设计模式通常被分为三大类:创建型(Creational)、结构型(Structural)和行为型(Behavioral)。以下是这20个设计模式的分类: 创建型(Creational)设计模式&#…...

力扣--最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2,1,-5,4] 输出:…...

C# 中的字符与字符串
简介 在C#编程语言中,字符和字符串是处理文本数据的基础。字符是单个的字母或符号,而字符串是字符的集合。本篇博客将详细介绍C#中的字符类型 char 和字符串类型 string,以及它们的基本操作。 字符类型 char char 类型在C#中用于表示单个字…...

TPM之VMK密封
本篇文章主要介绍基于TPM的Bitlocker全盘加密时,VMK密钥的密封(Seal)流程,至于TPM、Bitlocker、密钥保护器、VMK密钥等这些东西是什么,这里不做解释,需要自己脑补一下(╮(╯▽╰)╭)…...

Fastjson 反序列化漏洞[1.2.24-rce]
漏洞复现环境搭建请参考 http://t.csdnimg.cn/vSaaw kali切换jdk版本请参考 Kali安装JAVA8和切换JDK版本的详细过程_kali安装jdk8-CSDN博客 漏洞原理 Fastjson提供的com.sun.rowset.JdbcRowSetImpl类下的dataSourceName方法支持传入一个RMI/LDAP源,支持远程调用。…...

【面试宝藏】Go基础面试题其一
探索Go语言:特性、用法与最佳实践 Go语言(Golang)自发布以来迅速成为开发者社区中的热门选择。本文将探讨Go语言的优势、数据类型、包管理、类型转换、并发处理、同步机制、通道特性及其使用中的注意事项等内容,并回答一些常见的…...

python如何安装pyqt4
第一步,下载.whl文件,地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyqt4,这里可以下载不同的python版本对应的包。 第二步,选择一个目录,将下载好的文件放到该目录下,然后cmd下ÿ…...

调用上传文件接口出现格式错误
一、造成这种错误的可能有很多 1.检查一下传递格式 2.检查一下接口要求的格式 二、举个例子 这两个有什么区别? 那就是json、和form-data,一定要看仔细接口 如果还是按照json的方式去传就会报错 三、更改header里Content-Type的类型 json等的heade…...