Mysql数据库基础知识总复习

2023-10-26

前言

小亭子正在努力的学习编程,接下来将开启javaEE的学习~~

分享的文章都是学习的笔记和感悟,如有不妥之处希望大佬们批评指正~~

同时如果本文对你有帮助的话,烦请点赞关注支持一波, 感激不尽~~

目录

前言

数据库基础知识

数据,数据库,数据库管理系统,数据库系统

数据库的发展阶段

 数据库系统的结构

数据模型

一、概念模型

逻辑结构 

关系模型

关系代数

数据库的分类

配置初始化文件

常用的dos代码

注意:

SQL分类

表设计

一对一

一对多

多对多

常用数据类型

数值类型

字符串类型

日期类型

 范式

第一范式

第二范式

第三范式

数据库的操作

显示当前数据库

语法:

创建数据库

语法:

说明:

示例:

使用数据库

语法:

删除数据库

语法:

说明:

示例:

表的操作

使用数据库

查看表结构

创建表

删除表

表的增删改查(CRUD)

CRUD

新增数据

语法:

示例:

单行数据 +全列插入

多行数据+指定列插入

查询数据

全列查询

指定列查询

查询字段为表达式

设置别名

去重查询

排序查询

where条件查询

分页查询

聚合函数查询

GROUP BY子句

HAVING 子句

联合查询

修改数据

语法

示例

删除数据

语法

示例

数据库约束

索引

事务


先来个语法总结

--显示当前数据库
show databases

-- 使用数据库
use xxx;

--创建数据库
create database [if not exists] 数据库名 

--查询数据库下表
show tables;

-- 显示表
show table;

-- 创建表
create table xxx;

-- 删除表
drop table xxx;

--查看表结构
describe xxx; 或 desc xxx;

--修改表名
alter table <表名> rename <表名>;

--修改表字段信息
alter table 表名 change 字段名   修改后的列名和属性;

--增加表字段信息
alter table 表名 add  字段名及属性

--删除一个表字段
alter table 表名 drop 字段名;

--插入数据
insert into 表名 value(根据表结构插入数据内容 );

--插入数据,指定属性
insert into 表名 (列名) value(根据表结构插入数据内容 );

--修改数据
update 表 set 字段1=value1, 字段2=value2... where 条件

--删除数据
delete from 表 where 条件 

--查看索引
show index from 表名;

--创建索引 对于非主键、非唯一约束、非外键的字段,可以创建普通索引
create index 索引名 on 表名(字段名);

--删除索引
drop index 索引名 on 表名;

--事务
那就让这里两个操作要么同时成功,要么同时失败。这就是事务的逻辑。
(1)开启事务:start transaction;
(2)中间执行多条SQL语句
(3)回滚或提交:rollback/commit;

-- 全列查询
select * from 表

-- 指定列查询
select 字段1,字段2... from 表

-- 查询表达式字段
select 字段1+100,字段2+字段3 from 表

-- 别名
select 字段1 别名1, 字段2 别名2 from 表

-- 去重DISTINCT
select distinct 字段 from 表

-- 排序ORDER BY
select * from 表 order by 排序字段

-- 条件查询where:
(1)比较运算符 (2)BETWEEN ... AND ... (3)IN (4)IS NULL (5)LIKE (6)AND (7)OR(8)NOT
select * from 表 where 条件
>, >=, <, <=,=,<=>(等于),!=, <>
between a and b,IS NULL,IS NOT NULL
IN (option, ...)    如果是 option 中的任意一个,返回 TRUE(1)
LIKE    模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符
逻辑运算符:and,or,not

--分页查询limit--从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
select ... from 表名[where...][order by..] limit s offset n;

--聚合函数
COUNT([DISTINCT] expr)(计数),SUM([DISTINCT] expr),AVG([DISTINCT] expr),MAX([DISTINCT] expr),MIN([DISTINCT] expr)
select role,max(salary),min(salary),avg(salary) from emp group by role;

--group by  分组查询 having 条件过滤
GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用HAVING
显示平均工资低于1500的角色和它的平均工资
select role,max(salary),min(salary),avg(salary) from emp group by role
having avg(salary)<1500;

--联合查询
--内连接
select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;

-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

--自连接,自连接是指在同一张表连接自身进行查询。
select 字段 from 表1 别名1 join 表1 别名2 on 连接条件  join 表2 别名1 on 条件 join 表12别名2 .......and 其他条件;

--子查询
-- 单行子查询
select ... from 表1 where 字段1 = (select ... from ...);

--多行子查询
-- [NOT] IN
select ... from 表1 where 字段1 in (select ... from ...);
-- [NOT] EXISTS
select ... from 表1 where exists (select ... from ... where 条件);

-- 临时表:form子句中的子查询
select ... from 表1, (select ... from ...) as tmp where 条件
在from子句中使用子查询:子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

----在from子句中使用子查询:子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。
-- UNION:去除重复数据(操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。)
select ... from ... where 条件
union
select ... from ... where 条件

-- UNION ALL:不去重(该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行)
select ... from ... where 条件
union all
select ... from ... where 条件
使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致


--数据库约束
NOT NULL - 指示某列不能为空
UNIQUE - 保证某列的每行必须有唯一,不重复的。
DEFAULT - 规定没有给列赋值时的默认值。
PRIMARY KEY - 主键约束,与 NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY - 外键约束,保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句。

数据库基础知识

数据,数据库,数据库管理系统,数据库系统

数据库的发展阶段

 数据库系统的结构

 三级结构

数据库系统的二级映像
1.外模式/模式映像:保证逻辑独立性
2.模式/内模式映像:保证物理独立性
 

数据模型

一、概念模型

1.相关术语

2.实体型之间的联系

1.一对一联系(1:1)
两个方向都是 1:1
例:班级和班主任
2.一对多联系(1:n)
一个方向是 1:1,另一个方向是 1:n
例:学生和班主任
3.多对多联系(m:n)
两个方向都是 1:n
例:学生和课程

3.E-R 图

矩形表示实体;椭圆表示属性;菱形表示联系;无向边;联系类型
例:①班级和班主任;②学生和班主任;③学生和课程

逻辑结构 

1.结构
树型结构

 2.特点
(1)一个模型有且只有一个节点没有双亲节点,这个节点称为根节点
(2)根节点以外的其他节点有且只有一个双亲节点
(3)父子节点之间的联系是一对多联系(1∶ n)

网型结构

 2.特点
(1)允许一个以上的节点没有双亲节点
(2)允许一个节点有多个双亲节点
(3)节点之间存在多种联系(m:n)

关系模型

(一)基本概念
1.关系:二维表
2.属性:列、字段;元数
3.域:值域
4.元组:行、记录
5.分量:属性值
如,(01001,赵乾,女,讲师,计算机, 6000)中“01001”为一个分量
6.关系模式:二维表结构
如, T(TNo, TN, Sex, Prof, Dept, Sal)

 (二)关系的性质
1.每一列是同质的
2.不同列有不同的名字
3.列的顺序可以任意交换
4.行的顺序可任意交换
5.不允许出现完全一样的行
6.不允许出现合并单元格

三)关系模型的完整性约束
有 3 类:实体完整性、参照完整性、用户定义完整性
(一)关系的码

 (二)实体完整性
原则:①有主码(不空)②不同元组的主码不重复

(三)参照完整性
原则: R2 表的外键 X 的取值,参照 R1 表的主键值


(四)用户自定义完整性
原则:事先定义值域
 

关系代数

一) 传统的集合运算
1.并

2 .差

3.交

 4.广义笛卡尔积

 

 二) 专门的代数运算


1.选择 【根据条件得到行】

 选择条件:性别  女

结果:

2.投影 【 根据条件得到列】

投影条件:姓名,系别

投影结果:
3.连接
连接运算是二目运算, 它从两个关系的广义笛卡儿积中选取满足连接条件的
元组, 组成新的关系。
( 1) 等值连接
规则: ①结果(字段-两个关系的字段和) (记录-等值属性值相等, 拼左右)
( 2) 自然连接
规则: ①两表有相同的属性②结果( 字段-相同属性列只保留一列) ( 记录-
相同属性做等值连接)

4.除

 具体算法可以看这篇http://t.csdn.cn/D4vj3


数据库的分类

数据库分为关系型数据库和非关系型数据库

关系型数据库 非关系型数据库
使用SQL 不强制要求,一般不基于SQL实现
事务支持 支持 不支持
复杂操作 支持 不支持
海量读写操作 效率低 效率高
基本结构 基于表和列,结构固定 灵活性比较高
使用场景 业务方面的OLTP系统 用于数据的缓存、或基于统计分析的OLAP系统

配置初始化文件

1. 在MySQL根目录下创建初始化文件my.ini,即D:\Tools\mysql-5.7.27-winx64\my.ini。内容
如下:
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port=3306
# 设置mysql的安装目录
basedir=D:/Tools/mysql-5.7.27-winx64
# 设置mysql数据库的数据的存放目录
datadir=D:/Tools/mysql-5.7.27-winx64/data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=innodb

2. 将以上 basedir 和 datadir 后的内容替换成自己的路径。
3. 注意:需要保存为ANSI编码。方法一:使用记事本打开,保存/另
法二:使用Notpad++打开,点击编码->转为ANSI编码->保存。

常用的dos代码

--连接服务器

mysql -u root -p
要求输入密码,没有设置密码则直接回车
进入MySQL命令行以后,可以看到 mysql>
-- 使用mysql数据库
use mysql;
-- 更新用户表的root账户,设置为任意ip都可以访问,密码修改为123456
update user set host="%",authentication_string=password('root') where
user="root";
-- 刷新权限
flush privileges;
--退出

quit;

注意:

  • 注释的写法 在前面加 --
  • sql语句不区分大小写,写大写和小写都行

SQL分类

DDL数据定义语言,用来维护存储数据的结构
代表指令: create, drop, alter
DML数据操纵语言,用来对数据进行操作
代表指令: insert,delete,update
DML中又单独分了一个DQL,数据查询语言,代表指令: select
DCL数据控制语言,主要负责权限管理和事务
代表指令: grant,revoke,commit
 

表设计

一对一

一对多

多对多

常用数据类型

数值类型

分为整型和浮点型

数据类型  大小  说明  对应java类型
BIT[ (M) ] M指定位数,默认为1 二进制数,M范围从164
存储数值范围从
02^M-1
常用Boolean对应BIT,此时默认是1位,即只能存01
TINYINT  1字节  Byte
SMALLINT  2字节  Short
INT  4字节  Integer
BIGINT  8字节  Long
FLOAT(M, D)  4字节  单精度,M指定长度,D指定小数位数。会发生精度丢失  Float
DOUBLE(M,D) 8字节  Double
DECIMAL(M,D) M/D最大值+2 双精度,M指定长度,D表示小数点位数。精确数值  BigDecimal
NUMERIC(M,D) M/D最大值+2  DECIMAL一样  BigDecimal

补充:

  • 数值类型可以指定为无符号(unsigned),表示不取负数
  • 1字节(bytes)= 8bit。
  • 对于整型类型的范围:

1. 有符号范围:-2^(类型字节数*8-1)到2^(类型字节数*8-1)-1,如int是4字节,是-2^31到2^31-1

2. 无符号范围:0到2^(类型字节数*8)-1,如int就是2^32-1

尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型
 

字符串类型

数据类型 大小 说明 对应java类型
VARCHAR (SIZE) 0-65,535字节 可变长度字符串 String
TEXT 0-65,535字节 长文本数据 String
MEDIUMTEXT 0-16 777 215字节 中等长度文本数据 String
BLOB 0-65,535字节 二进制形式的长文本数据 byte[]

说明:varchar 可变长度是指  假设 设置了1000个字符的大小,实际占用了100个,那么就只开辟100个空间。不可变长度就是设置了1000,空间占用就是1000,没用上的就空着但是还是占用了。

日期类型

数据类型
说明 对应java类型
DATETIME 8 字 节 范围从1000到9999年,不会进行时区的
检索及转换。
java.util.Date、
java.sql.Timestamp
TIMESTAMP 4 字 节 范围从1970到2038年,自动检索当前时
区并进行转换。
java.util.Date、
java.sql.Timestamp

补充:时间戳默认1970年1月1日,(时间纪元)有兴趣的自行百度。


 范式

第一范式

第一范式规定表中的每个列都应该是不可分割的最小单元。比如以下表中的 address 字段就不是不可分割的最小单元。(原子不可再分)

不满足的表:address 还可以拆分为国家和城市

满足的表 

第二范式

第二范式是在满足第一范式的基础上,规定表中的非主键列不存在对主键的部分依赖,也就是说每张表只描述一件事情.

以下订单表就不满足第二范式,它可以拆分为两张独立的表:订单表和商品表。

满足的表

第三范式

第三范式是在满足第一范式和第二范式的基础上,规定表中的列不存在对非主键列的传递依赖。

(保证每列都和主键直接相关)

比如以下的订单表中的顾客名称就不符合第三范式,因为它存在了对非主键顾客编号的依赖

满足的表

使用数据库三范式的优势是:表的结构更简单、优雅,表的逻辑和条理性更强,并且使用三范式可以很大程度的减少表中的冗余数据,很好的节省了数据库的存储资源。


数据库的操作

显示当前数据库

语法:

show databases

创建数据库

语法:

CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,
create_specification] ...]
create_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name

说明:

  • 大写的表示关键字
  • [] 是可选项
  • CHARACTER SET: 指定数据库采用的字符集
  • COLLATE: 指定数据库字符集的校验规则

示例:

1.创建名为db_test1 的数据库

CREATE DATABASE db_test1

2.如果系统没有 db_test2 的数据库,则创建一个名叫 db_test2 的数据库,如果有则不创建

CREATE DATABASE IF NOT EXISTS db_test2

3.如果系统没有 db_test 的数据库,则创建一个使用utf8mb4字符集的 db_test 数据库,如果有则不创建

CREATE DATABASE IF NOT EXISTS db_test CHARACTER SET utf8mb4;
 

使用数据库

语法:

use 数据库名

删除数据库

语法:

DROP DATABASE [IF EXISTS] db_name

说明:

数据库删除以后,内部看不到对应的数据库,里边的表和数据全部被删除
 

示例:

drop database if exists db_test1
drop database if exists db_test2

表的操作

-- 显示
show table;
-- 创建
create table xxx;
-- 使用
use xxx;
-- 删除
drop table xxx;

--查看表结构

describe xxx; 或 desc xxx;

--查询数据库下表

show tables;

--修改表名

alter table <表名> rename <表名>;

--修改表字段信息

alter table 表名 change 字段名   修改后的列名和属性;

--增加表字段信息

alter table 表名 add  字段名及属性

--删除一个表字段

alter table 表名 drop 字段名;

使用数据库

操作表之前需要先使用该数据库

user 数据库名

查看表结构

desc  表名

示例+说明 

创建表

语法

CREATE TABLE table_name (
field1 datatype,
field2 datatype,
field3 datatype
);

示例

create table stu_test (
id int,
name varchar(20) comment '姓名',
password varchar(50) comment '密码',
age int,
sex varchar(1),
birthday timestamp,
amout decimal(13,2),
resume text
);

删除表

语法

DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ...

示例

-- 删除 stu_test 表
drop table stu_test;
-- 如果存在 stu_test 表,则删除 stu_test 表
drop table if exists stu_test;

表的增删改查(CRUD)

CRUD

CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写

新增数据

语法:

INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
value_list: value, [, value] ...

示例:

-- 创建一张学生表
DROP TABLE IF EXISTS student;
CREATE TABLE student (
id INT,
sn INT comment '学号',
name VARCHAR(20) comment '姓名',
qq_mail VARCHAR(20) comment 'QQ邮箱'
);

单行数据 +全列插入

-- 插入两条记录,value_list 数量必须和定义表的列的数量及顺序一致
INSERT INTO student VALUES (100, 10000, '唐三藏', NULL);
INSERT INTO student VALUES (101, 10001, '孙悟空', '11111');

多行数据+指定列插入

-- 插入两条记录,value_list 数量必须和指定列数量及顺序一致
INSERT INTO student (id, sn, name) VALUES
(102, 20001, '曹孟德'),
(103, 20002, '孙仲谋');

查询数据

语法

SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...

全列查询

--通常情况下 使用 * 进行全列查询

SELECT * FROM exam_result;

指定列查询

--指定列的顺序不需要按定义表的顺序来

SELECT id ,name FROM   exam_result;

查询字段为表达式

-- 表达式不包含字段
SELECT id, name, 10 FROM exam_result;
-- 表达式包含一个字段
SELECT id, name, english + 10 FROM exam_result;
-- 表达式包含多个字段
SELECT id, name, chinese + math + english FROM exam_result;

设置别名

为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称

SELECT column [AS] alias_name [...] FROM table_name;

示例:

-- 结果集中,表头的列名=别名
SELECT id, name, chinese + math + english 总分 FROM exam_result;

去重查询

使用DISTINCT关键字对某列数据进行去重
示例:

SELECT DISTINCT math FROM exam_result;

排序查询

  • ASC 为升序(从小到大)
  •  DESC 为降序(从大到小)
  • 默认为 ASC
  • null数据在排序中,视为最小的值
  • 排序条件可以是表达式或者子查询

SELECT ... FROM table_name [WHERE ...]
ORDER BY column [ASC|DESC], [...];

示例:

-- 查询同学及总分,由高到低
SELECT name, chinese + english + math FROM exam_result
ORDER BY chinese + english + math DESC;
SELECT name, chinese + english + math total FROM exam_result
ORDER BY total DESC;
 

总结

-- 全列查询
select * from 表
-- 指定列查询
select 字段1,字段2... from 表
-- 查询表达式字段
select 字段1+100,字段2+字段3 from 表
-- 别名
select 字段1 别名1, 字段2 别名2 from 表
-- 去重DISTINCT
select distinct 字段 from 表
-- 排序ORDER BY
select * from 表 order by 排序字段
-- 条件查询WHERE:
-- (1)比较运算符 (2)BETWEEN ... AND ... (3)IN (4)IS NULL (5)LIKE (6)AND (7)OR
(8)NOT
select * from 表 where 条件
 

where条件查询

比较运算符

>, >=, <, <= 大于,大于等于,小于,小于等于
= 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=> 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <> 不等于
BETWEEN a0 AND
a1
范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, ...) 如果是 option 中的任意一个,返回 TRUE(1)
IS NULL 是 NULL
IS NOT NULL 不是 NULL
LIKE 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字

逻辑运算符

运算符 说明
AND 多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR 任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT 条件为 TRUE(1),结果为 FALSE(0)

注意:

1. WHERE条件可以使用表达式,但不能使用别名。
2. AND的优先级高于OR,在同时使用时,需要使用小括号()包裹优先执行的部分

分页查询

用limit关键字

语法:

-- 起始下标为 0
-- 从 0 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
-- 从 s 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;
-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT  s OFFSET n;

示例:

按 id 进行分页,每页 3 条记录,分别显示 第 1、2、3 页
--第 1 页
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 0;
-- 第 2 页
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 3;
-- 第 3 页,如果结果不足 3 个,不会有影响
SELECT id, name, math, english, chinese FROM exam_result ORDER BY id LIMIT 3
OFFSET 6;

示例:

--统计数学成绩总分

ELECT SUM(math) FROM exam_result;
-- 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;

聚合函数查询

聚合函数

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有

函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的 数量
SUM([DISTINCT] expr) 返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr) 返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的 最小值,不是数字没有意义

GROUP BY子句

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:

使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中

select column1, sum(column2), .. from table group by column1,column3;

示例:

准备测试的素材

create table emp(
id int primary key auto_increment,
name varchar(20) not null,
role varchar(20) not null,
salary numeric(11,2)
);
insert into emp(name, role, salary) values
('马云','服务员', 1000.20),
('马化腾','游戏陪玩', 2000.99),
('孙悟空','游戏角色', 999.11),
('猪无能','游戏角色', 333.5),
('沙和尚','游戏角色', 700.33),
('隔壁老王','董事长', 12000.66);

查询示例

查询每个角色的最高工资、最低工资和平均工资
select role,max(salary),min(salary),avg(salary) from emp group by role;

HAVING 子句

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用HAVING

示例:

显示平均工资低于1500的角色和它的平均工资
select role,max(salary),min(salary),avg(salary) from emp group by role
having avg(salary)<1500;

联合查询

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积

准备的测试数据

insert into classes(name, `desc`) values
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');
insert into student(sn, name, qq_mail, classes_id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素贞',null,1),
('00031','许仙','xuxian@qq.com',1),
('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);
insert into course(name) values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想毕业
(81, 5, 1),(37, 5, 5),

-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);

内连接

语法

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

示例

查询所有同学的总成绩,及同学的个人信息
-- 成绩表对学生表是多对1关系,查询总成绩是根据成绩表的同学id来进行分组的
SELECT
stu.sn,
stu.NAME,
stu.qq_mail,
sum( sco.score )
FROM
student stu
JOIN score sco ON stu.id = sco.student_id
GROUP BY
sco.student_id;

外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接

语法

-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

示例

查询所有同学的成绩,及同学的个人信息,如果该同学没有成绩,也需要显示
- “老外学中文”同学 没有考试成绩,也显示出来了
select * from student stu left join score sco on stu.id=sco.student_id;
-- 对应的右外连接为:
select * from score sco right join student stu on stu.id=sco.student_id;
-- 学生表、成绩表、课程表3张表关联查询
SELECT
stu.id,
stu.sn,
stu.NAME,
stu.qq_mail,
sco.score,
sco.course_id,
cou.NAME
FROM
student stu
LEFT JOIN score sco ON stu.id = sco.student_id
LEFT JOIN course cou ON sco.course_id = cou.id
ORDER BY
stu.id;

自连接

自连接是指在同一张表连接自身进行查询。

select 字段 from 表1 别名1 join 表1 别名2 on 连接条件  join 表2 别名1 on 条件 join 表12别名2 .......and 其他条件;
示例:

显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

SELECT
stu.*,
s1.score Java,
s2.score 计算机原理
FROM
score s1   JOIN score s2 ON s1.student_id = s2.student_id     //  自连接   
JOIN student stu ON s1.student_id = stu.id
JOIN course c1 ON s1.course_id = c1.id
JOIN course c2 ON s2.course_id = c2.id
AND s1.score < s2.score
AND c1.NAME = 'Java'
AND c2.NAME = '计算机原理';

拆分上述语句得到一下的分步执行的语句


-- 1.先查询“计算机原理”和“Java”课程的id
select id,name from course where name='Java' or name='计算机原理';


-- 2. 再查询成绩表中,“计算机原理”成绩比“Java”成绩 好的信息
SELECT
s1.*
FROM
score s1,
score s2
WHERE
s1.student_id = s2.student_id

AND s1.score < s2.score
AND s1.course_id = 1
AND s2.course_id = 3;
-- 也可以使用join on 语句来进行自连接查询
SELECT
s1.*
FROM
score s1
JOIN score s2 ON s1.student_id = s2.student_id
AND s1.score < s2.score
AND s1.course_id = 1
AND s2.course_id = 3;

子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询
单行子查询:返回一行记录的子查询

-- 单行子查询
select ... from 表1 where 字段1 = (select ... from ...);

示例

查询与“不想毕业” 同学的同班同学
select * from student where classes_id=(select classes_id from student where
name='不想毕业');

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

-- [NOT] IN
select ... from 表1 where 字段1 in (select ... from ...);
-- [NOT] EXISTS
select ... from 表1 where exists (select ... from ... where 条件);
-- 临时表:form子句中的子查询
select ... from 表1, (select ... from ...) as tmp where 条件

示例

案例:查询“语文”或“英文”课程的成绩信息
. [NOT] IN关键字
--使用IN

select * from score where course_id in (select id from course where
name='语文' or name='英文');
-- 使用 NOT IN
select * from score where course_id not in (select id from course where
name!='语文' and name!='英文');
可以使用多列包含:
-- 插入重复的分数:score, student_id, course_id列重复
insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),
-- 菩提老祖
(60, 2, 1);
-- 查询重复的分数
SELECT
*
FROM
score
WHERE
( score, student_id, course_id ) IN ( SELECT score, student_id,
course_id FROM score GROUP BY score, student_id, course_id HAVING
count( 0 ) > 1 );


[NOT] EXISTS关键字

-- 使用 EXISTS
select * from score sco where exists (select sco.id from course cou
where (name='语文' or name='英文') and cou.id = sco.course_id);
-- 使用 NOT EXISTS
select * from score sco where not exists (select sco.id from course cou
where (name!='语文' and name!='英文') and cou.id = sco.course_id);
 

在from子句中使用子查询:子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

查询所有比“中文系2019级3班”平均分高的成绩信息
-- 获取“中文系2019级3班”的平均分,将其看作临时表
SELECT
avg( sco.score ) score
FROM
score sco
JOIN student stu ON sco.student_id = stu.id
JOIN classes cls ON stu.classes_id = cls.id
WHERE
cls.NAME = '中文系2019级3班';


查询成绩表中,比以上临时表平均分高的成绩
SELECT
*
FROM
score sco,
(
SELECT
avg( sco.score ) score
FROM
score sco
JOIN student stu ON sco.student_id = stu.id
JOIN classes cls ON stu.classes_id = cls.id
WHERE
cls.NAME = '中文系2019级3班'
) tmp
WHERE
sco.score > tmp.score;
 

C

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用

-- UNION:去除重复数据(操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。)
select ... from ... where 条件
union
select ... from ... where 条件


-- UNION ALL:不去重(该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行)
select ... from ... where 条件
union all
select ... from ... where 条件
-- 使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致

示例

UNION
和UNION ALL时,前后查询的结果集中,字段需要一致
案例:查询id小于3,或者名字为“英文”的课程:
select * from course where id<3
union
select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';

union all
案例:查询id小于3,或者名字为“Java”的课程
-- 可以看到结果集中出现重复数据Java
select * from course where id<3
union all
select * from course where name='英文';

修改数据

语法

update 表 set 字段1=value1, 字段2=value2... where 条件

示例

-- 将孙悟空同学的数学成绩变更为 80 分
UPDATE exam_result SET math = 80 WHERE name = '孙悟空';
-- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
-- 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
UPDATE exam_result SET math = math + 30 ORDER BY chinese + math + english LIMIT
3;
-- 将所有同学的语文成绩更新为原来的 2 倍
UPDATE exam_result SET chinese = chinese * 2;

删除数据

语法

delete from 表 where 条件

示例

-- 删除孙悟空同学的考试成绩
DELETE FROM exam_result WHERE name = '孙悟空';
-- 删除整张表数据
-- 准备测试表
DROP TABLE IF EXISTS for_delete;
CREATE TABLE for_delete (
id INT,
name VARCHAR(20)
);
-- 插入测试数据
INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
-- 删除整表数据
DELETE FROM for_delete;

数据库约束

  • NOT NULL - 指示某列不能为空
  • UNIQUE - 保证某列的每行必须有唯一,不重复的。
  • DEFAULT - 规定没有给列赋值时的默认值。
  • PRIMARY KEY - 主键约束,与 NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
  • FOREIGN KEY - 外键约束,保证一个表中的数据匹配另一个表中的值的参照完整性。
  • CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句。

索引

索引,相当于目录,它是一种特殊的文件包含着对数据表里所有记录的引用指针。可以帮助我们快速定位,检索数据。

注意:创建索引会占用额外的磁盘空间,插入或修改操作效率不高,通常建议使用在需要大量进行查询的场合。

 使用方法:

创建主键约束(PRIMARY KEY)、唯一约束(UNIQUE)、外键约束(FOREIGN KEY)时,会自动创建对应列的索引。

查看索引

show index from 表名;

示例:

查看学生表已有的索引
show index from student;

创建索引

对于非主键、非唯一约束、非外键的字段,可以创建普通索引

create index 索引名 on 表名(字段名);

示例

创建班级表中,name字段的索引

create index idx_classes_name on classes(name);

删除索引

drop index 索引名 on 表名;

示例

删除班级表中name字段的索引

drop index idx_classes_name on classes;

事务

试想一下,当你妈妈给你打生活费的时候,她给你转账但是数据库挂掉了,那边显示转账成功了,金额减少了2000,但是你的账户并没有增加2000。这个时候是不是就很难受,那么这个问题该怎么解决呢?

那就让这里两个操作要么同时成功,要么同时失败。这就是事务的逻辑。

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。

使用

  • (1)开启事务:start transaction;
  • (2)执行多条SQL语句
  • (3)回滚或提交:rollback/commit;

说明:rollback即是全部失败,commit即是全部成功。

示例:

start transaction;
-- 阿里巴巴账户减少2000
update accout set money=money-2000 where name = '阿里巴巴';
-- 四十大盗账户增加2000
update accout set money=money+2000 where name = '四十大盗';
commit;

【以上就是本文分享的全部内容,下一篇JDBC编程,敬请期待~~】

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql数据库基础知识总复习 的相关文章

随机推荐

  • C++ - if 、else、else_if 语句

    C 中的 if else if else 是非常基础的东西 这里需要知道一个东西 大括号 一定要是成对出现 格式为 if 判断语句 如果判断语句成立 运行 如果判断语句不成立 跳过 if 语句 else 如果判断语句不成立 运行 如果判断语
  • 渗透测试-SQL注入之宽字节注入

    SQL注入之宽字节注入 文章目录 SQL注入之宽字节注入 前言 一 什么是宽字节注入 二 宽字节注入获取数据库信息 1 宽字节注入方法 2 宽字节注入防御方法 总结 前言 一 什么是宽字节注入 宽字节是相对于ascII这样单字节而言的 像
  • 信息管理毕业设计 SSM的小区车位出租管理系统(源码+论文)

    文章目录 1 前言 2 实现效果 3 设计方案 4 最后 1 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的java web缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉学长自己做的java web管理系
  • python中pandas库查看数据分布的基本用法

    1 最大值 最小值 平均值 如何在Python中查看pandas dataframe对象列的最大值 最小值 平均值 标准差 中值等 PandasDataFrame 中位数 Python统计大文本行数
  • 设置VLC播放器进行RTSP推流视频

    设置VLC播放器进行RTSP推流视频 一 推流与拉流概念 二 设置推流端 三 设置拉流端 播放端 VLC官网 https www videolan org 一 推流与拉流概念 首先 做几个名词解释 推流 指的是把采集阶段封包好的内容传输到服
  • Easyexcel 3.1.1版本动态表头样式

    需求 动态生成的表头 key value的形式 List
  • Qt中的表格控件QTableWidget是一个非常常用的UI组件

    Qt中的表格控件QTableWidget是一个非常常用的UI组件 它可以用于展示表格数据 并且还有一些便捷的API以及信号槽机制 非常适合初学者入手 本篇文章将会对QTableWidget的使用进行详细介绍 一 如何创建QTableWidg
  • QT 在Window下驱动HID设备

    QT使用HID设备 QT 在Window下驱动HID设备 准备源码 1 下载HID源码 2 解压 拷贝解压目录下的 3 拷贝解压目录下的 4 打开QT建立新工程 把刚准备的window目录的三个文件 5 在QT 配置 pro文件中的SOUR
  • (四)调整PID控制器参数的指南

    一 控制系统设计快速入门和环境 首先确定一下控制任务 快速 精准地控制 必要的稳定性 时域 上升时间 超调等 频域 带宽 阻尼比 然后明白控制系统特点 类积分器 开环稳定性 高度非线性 非最小相位 1 选择一个控制框架 比如说PID 当然也
  • Windows Server2012常见版本

    目录 常见版本 授权方式 常用功能模块介绍 Windows Server 2012这是Windows 8的服务器版本 并且是Windows Server 2008 R2的继任者 该操作系统已经在2012年8月1日完成编译RTM版 并且在20
  • IntelliJ IDEA:新建文件无法识别类型

    参考 https blog csdn net iningwei article details 106115169 总结 File gt Settings gt Editor gt File Types 右侧 Text 然后下面的窗口往下滑
  • C将两个有序的数组合并成一个有序数组

    编写程序 分别输入两个按从小到大排序的数组 a 和 b 将这两个有序数组合并 使合并后的数组仍是从小到大有序的 合并两个有序数组的方法 有两个有序数组a和b 其中数组a的末尾有足够的空间容纳数组b 将数组b容纳到数组a中 创建一个新数组c
  • MyBatis 多表联合查询及优化

    关于优化 对于优化嘛 我这里简单的提几点 大家可以考虑一下 首先 就是对表的设计 在设计表初期 不仅仅要考虑到数据库的规范性 还好考虑到所谓的业务 以及对性能的影响 比如 如果从规范性角度考虑的话 可能就会分多个表 但是如果从性能角度来考虑
  • 如何实现精致扫雷游戏(可扩散可标记)---保姆级教程

    目录 思路 main函数内容 创建 双子 数组 初始化数组 打印棋盘 布置雷 排查雷 初阶 大致过程 如何统计周围雷的个数 判断是否赢得游戏 进阶 可扩散可标记 1 排雷 2 标记 标记要更改的时show数组 呈现给玩家标记信息 3 取消标
  • Bugku-兔年大吉2

    兔年大吉2
  • 逆向基础:32位软件逆向技术

    在编写win32应用程序时 都必须在源码里实现一个WinMain函数 但windows程序的执行并不是从WinMain函数开始的 首先被执行的是启动函数的相关代码 这段代码是由编译器生成的 启动源代码 crt src wincmdln c中
  • 【leveldb】整体架构

    LevelDb本质上是一套存储系统以及在这套存储系统上提供的一些操作接口 为了便于理解整个系统及其处理流程 我们可以从两个不同的角度来看待 LevleDb 静态角度和动态角度 从静态角度 可以假想整个系统正在运行过程中 不断插入删除读取数据
  • 【鼠标事件 MouseEvent】clientX clientY offsetX offsetX pageX screenX screenY

    鼠标事件 MouseEvent 对象 下clientX clientY offsetX offsetX pageX screenX screenY 定义转自 MDNMouseEvent MouseEvent clientX 只读 鼠标指针在
  • C程序设计实现高内聚低耦合

    要做到高内聚低耦合 重点并不是代码的编写 而是整体程序的设计阶段 程序设计时 要先将要实现的功能列出来 然后设计模块 模块设计后 再进行代码实现 要做到高内聚低耦合 设计模块时需要做到 1 各个模块之间的功能必须明确 2 各个功能模块间实现
  • Mysql数据库基础知识总复习

    前言 小亭子正在努力的学习编程 接下来将开启javaEE的学习 分享的文章都是学习的笔记和感悟 如有不妥之处希望大佬们批评指正 同时如果本文对你有帮助的话 烦请点赞关注支持一波 感激不尽 目录 前言 数据库基础知识 数据 数据库 数据库管理