本篇文章主要会在之前那篇数据库系统简单内容汇总的基础上补充期末新的内容作为复习的整理,并且致敬某光性厂商或者A开头厂商一样无耻的推出所谓的“加强版”。
概念部分(八股文)
数据库系统概述
数据库的4个基本概念
数据库的四个基本概念数据、数据库、数据库管理系统和数据库系统:
- 数据:描述事物的符号记录。
- 数据的含义称为数据的语义,数据与其语义是不可分的。
- 数据库:是长期存储在计算机内有组织、可共享的大量数据的集合。
- 数据库中的数据按一定的数据模型组织、描述和存储,具有较小的数据冗余(data redundancy)、较高的数据独立性(data independency)和可扩展性(scalability)。
- 数据库管理系统:位于用户与操作系统之间的数据管理软件,是计算机的基础软件。
- 数据库管理系统的主要功能包括:数据定义功能(数据定义语言(data definition language, DDL));数据组织、存储和管理功能;数据操纵功能;数据库的事务管理和运行管理功能;数据库的建立和维护功能;其它功能;
- 数据库系统:是指由数据库、数据库管理系统(及其应用开发工具)、应用系统和数据库管理员(data administrator, DBA)组成的存储、管理、处理和维护数据的系统。
其中最大的是数据库系统
数据库系统的特点:
- 数据结构化
- 数据的共享度高、冗余度低、易扩充
- 数据独立性高
- 物理独立性是指用户的应用程序与数据库中数据的物理存储是相互独立的
- 逻辑独立性是指用户的应用程序与数据库的逻辑结构是相互独立的
- 数据由数据库管理系统统一管理和控制
数据管理技术的产生和发展
数据管理技术经历了人工管理、文件系统、数据库系统三个阶段。
从文件系统阶段到数据库系统阶段是一个飞跃。
- 人工管理阶段:20世纪50年代中期以前。
- 文件系统阶段:20世纪50年代后期~20世纪60年代中期。
- 数据库系统阶段:20世纪60年代后期以来。
数据库系统阶段的数据具有如下特点:
- 整体数据的结构化
- 数据的共享性强、冗余度低且易于扩充
- 数据的独立性强:数据的物理独立性和数据的逻辑独立性
- 数据由数据库管理系统统一管理和控制:数据的安全性保护、数据的完整性检查、数据的并发性控制、数据库的恢复
数据模型
数据模型也是一种模型,它是对现实世界数据特征的抽象。数据模型是数据库系统的核心和基础。
数据模型可以分为:
- 概念模型
- 逻辑模型&物理模型
概念模型
概念模型用于信息世界的建模。信息世界中的基本概念:
- 实体:客观存在并可相互区别的事物
- 属性:实体所具有的某一特性
- 码:唯一标识实体的属性集
- 实体类型:具有相同属性的实体必然具有共同的特征和性质
- 实体集:同一类型实体的集合称为实体集
- 联系:实体(型)内部的联系和实体(型)之间的联系(实体内部的联系通常是指组成实体的各属性之间的联系,实体之间的联系通常是指不同实体集之间的联系)
实体之间的联系有一对一、一对多、多对多等多种类型。
数据模型的三要素
数据模型通常由数据结构、数据操纵和完整性约束三要素组成:
- 数据结构:描述数据库的组成对象以及对象之间的联系。
- 数据操纵:对数据库中各种对象(型)的实例(值)允许执行的操作的集合,包括操作及有关的操作规则。
- 完整约束性:一组完整性规则。
数据模型可以分为:层次模型(树状结构)、网状模型、关系模型等。
- 层次模型像一颗倒立的树
- 网状模型是网状结构
- 关系模型是一张二维表
层次模型简单但不能解决多对多的关系。
层次模型的数据操纵主要有查询、插入、删除和更新操作。
层次模型的优缺点:
- (优点)层次模型的数据结构比较简单清晰
- (优点)层次数据库的查询效率高
- (优点)层次数据模型提供了良好的完整性约束支持
- (缺点)现实世界中很多联系是非层次性的
- (缺点)如果一个结点具有多个双亲结点,用层次模型表示这类联系就很笨拙
- (缺点)查询子女结点必须通过双亲结点
- (缺点)由于结构严密,层次命令趋于程序化
总之,用层次模型对具有一对多层次联系的部门描述非常自然、直观,容易理解。
网状模型
网状数据库系统采用网状模型作为数据的组织方式,其典型代表是DBTG系统,亦称CODASYL系统。
把满足一下两个条件的基本层次联系集合称为网状模型:
- 允许一个以上的结点无双亲结点
- 一个结点可以有多于一个的双亲结点
网状模型比层次模型更具有普遍性,它去掉了层次模型的两个限制,允许多个结点没有双亲结点,且允许结点有多个双亲结点。
网状模型的优缺点:
- (优点)能够更为直接地描述现实世界
- (优点)具有良好的性能,存取效率较高
- (缺点)结构比较复杂
- (缺点)数据定义语言和数据操场语言比较复杂
- (缺点)用户必须了解系统结构的细节,加重了编写应用程序的负担
关系模型
关系模型是最重要的一种数据模型。
关系模型中的一些术语:
- 关系:对应通常说的一张二维表
- 元祖:表中的一行
- 属性:表中的一列
- 码:又称码键或键,是表中某一个属性或一组属性
- 域:表示某一属性的取值范围
- 分量:元祖中的一个属性值
- 关系模式:对关系的描述
关系模型要求关系必须是规范化的。关系的每一个分量必须是一个不可分的数据项。
不允许表中还有表。
关系模型的数据操纵主要包括查询、插入、删除和更新数据。
关系的完整性约束包括实体完整性、参照完整性和用户定义的完整性三大类。
实体完整性:主码不能为空
参照完整性:外码要么取空值,要么与主码完全相同
用户定义的完整性:根据具体业务需求,设置的一些限制条件,用来约束表中列的值符合特定规则。(比如通常使用的CHECK
或者DEFAULT
)
关系模型的优点:
- 关系模型建立在严格的数学概念基础上。
- 关系模型的概念单一。
- 关系模型的存取路径对用户隐蔽。
数据库的三级模式结构
- 模式(逻辑模式):是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。
- 外模式(子模式或用户模式):是数据库用户能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。
- 内模式(物理模式或存储模式):是数据物理结构的存储方式的描述,是数据在数据库内部的组织方式。
– 外模式和内模式的关系:一对多
– 内模式和模式的关系:一对一
– 模式和外模式的关系:一对多
关系操作
关系模型中常用的关系操作包括查询操作和更新操作两大部分。而更新操作又可分为插入、删除、修改等。
关系的类型有:
- 基本关系(基本表或基表)
- 查询表
- 视图表
关系的完整性
关系模型中有三类完整性约束:实体完整性、参照完整性和用户定义的完整性。
实体完整性约束:若属性A是基本关系R的主属性,则不能取空值。
专门的关系运算包括选择、投影、连接、除等运算。
各种运算可以记为:
- 并:R ∪ S
- 差:R – S
- 交:R ∩ S
- 笛卡尔积:R x S
- 选择:σF(R)
- 投影:ΠA(R)
- 连接:R ⋈ S
- 除:R ÷ S
关系数据库
关系数据库必须满足的最低要求是数据表的每一个分量必须是不可再分的数据项
关系数据语言可分为三类:
- 关系代数语言
- 关系演算语言
- 具有关系代数和关系演算双重特点的语言(SQL)
约束项
能够通过某个字段唯一区分出不同的记录,这个字段被称为主键
。
外键用于建立表与表之间的关联性。它引用另一张表的主键,确保外键字段的值必须在被引用表的主键中存在,以保持数据的完整性。
数据加密
数据加密主要包括存储加密和传输加密。
数据库的不安全因素
- 非授权用户对数据库的恶意存取和破坏
- 数据库中重要或敏感的数据被泄露
- 安全环境的脆弱性
TCSEC/TDI 安全级别划分
安全级别 | 安全指标 |
A1 | 验证设计 |
B3 | 安全域 |
B2 | 结构化保护 |
B1 | 标记安全保护 |
C2 | 受控的存取保护 |
C1 | 自主安全保护 |
D | 最小保护 |
A1
是最高安全级别,D
是最低安全级别。
数据依赖
数据依赖:函数依赖和多值依赖
范式
第一范式(1NF):每一个分量必须是不可分的数据项。
第二范式(2NF):R ∈ 1NF,且每一个非主属性完全函数依赖于任何一个候选项。
第三范式(3NF):每一个非主属性既不传递依赖码,也不部分依赖于码。
数据库设计
数据库设计是指对于一个给定的应用环境,结构优化的数据库逻辑模式和物理结构,并据此建立数据库及其应用系统,使之能够有效地存储和管理数据,满足各种用户的应用需求,包括信息管理要求和数据操作要求。
特点:三分技术,七分管理,十二分基础数据
数据库设计的基本步骤
- 需求分析阶段
- 概念结构设计阶段
- 逻辑结构设计阶段
- 物理结构设计阶段
- 数据库实施阶段
- 数据库运行和维护阶段
数据字典
数据字典是进行详细的数据收集和数据分析所获得的主要成果。它是关于数据库中数据的描述,即元数据,而不是数据本身。数据字典是在需求分析阶段建立,在数据库设计过程中不断修改、充实、完善的。它在数据库设计中占有重要的地位。
数据字典通常包括:数据项、数据结构、数据流、数据存储和处理过程。
ER模型
概念模型的有力工具ER模型
E-R图:
- 实体型用矩形表示
- 属性用椭圆表示
- 联系用棱形表示
查询处理
查询处理分为4个步骤:查询分析、查询检查、查询优化和查询执行
查询优化的优点:
- 不仅在于用户不必考虑如何最好地表达查询以获得较高的效率,而且在于系统可以比用户程序的“优化”做得更好。
- 提高查询效率:避免笛卡尔积、预处理
E-R图
每次期末都有一个声音甜美的小姐姐教我不会的画图题✌️,直接看视频可能学的更快。
画E-R首先需要知道实体型、实体的属性、实体间的联系分别应该怎么去画。
然后这里是将这几个元素拼起来的示例。
多对多关系会形成新的表(即之间的连接关系)(n : m)新的表需增加上实体的主码
假如说n个老师教m个学生,这就是一个多对多的关系,此时中间“授课”的关系就需要新开一个表。
一对多关系在多端(n端)加上连接的属性和1端的主码。(1 : n)
画E-R图和关系模型的例题:
代码部分
SQL语言是非过程化的数据库语言。
主要记录一些基本并且常用的SQL代码,以下代码公式中<>
中的内容是可以根据实际情况进行修改的。
Old School老师教我必须一个命令代码写在一行,所以这里第一次写的时候都是写在了一行,看的时候可能有点费力。
如果只是不太记得下列公式的一些细节,这里先放一个常用公式的大全,想看每个公式详细的说明可以继续往下面看:
-- 创建表
CREATE TABLE <表名> (<字段1> <数据类型> <是否为NULL> <是否为主键>, ...);
-- 创建关联表
CREATE TABLE <表名> (<字段1> <数据类型> PRIMARY KEY, FOREIGN KEY (<当前新创建表的主键名>) REFERENCES <关联表名> (<该关联表的主键>),<字段2> <数据类型> <是否为NULL>, …);
-- 删除表
DROP TABLE <表名>;
-- 修改表的若干操作:
-- 添加列
ALTER TABLE <表名> ADD COLUMN <列名> <数据类型> <主外键>;
-- 修改列
ALTER TABLE <表名> MODIFY COLUMN <列名> <新数据类型> <主外键>;
-- 删除列
ALTER TABLE <表名> DROP COLUMN <列名>;
-- 添加外键或其它约束
ALTER TABLE <表1名> ADD CONSTRAINT <外键名> FOREIGN KEY (<列名>) REFERENCES <表2名>(<列名>);
-- 插入数据(增)
INSERT INTO <表名> (<字段1>, <字段2>, …) VALUES (<值1>, <值2>, …);
-- 删除数据(删)
DELETE FROM <表名> WHERE …;
-- 查询数据(查):
-- 基本查询
SELECT * FROM <表名>;
-- 条件查询
SELECT * FROM <表名> WHERE <条件表达式>;
-- 模糊条件查询
SELECT * FROM <表名> WHERE <字段> LIKE '…%';
-- 排序查询
SELECT <字段1>, <字段2>, … FROM <表名> ORDER BY ;
-- 集合查询
SELECT <列名> FROM <表名> WHERE <列名> IN (<值1>, <值2>, <值3>, …);
-- 多表查询
SELECT <若干字段名> FROM <表名1>, <表名2> WHERE <条件表达式>;
-- 聚合查询
SELECT <聚合函数>(<若干字段>) AS <新的字段名> FROM <表名>;
-- 嵌套查询
SELECT <列名> FROM <表名> WHERE <列名> <运算符> (<子查询>);
-- 更新数据(改)
UPDATE <表名> SET 字段1=值1, 字段2=值2, … WHERE …;
-- 权限相关命令:
-- 给予权限
GRANT <权限列表> ON <对象名> TO <用户名>;
-- 解除权限
REVOKE <权限列表> ON <对象名> FROM <用户名>;
表格操作
创建表
可以通过SQL代码直接创建表格,做法如下:
CREATE TABLE <表名> (<字段1> <数据类型> <是否为NULL> <是否为主键>, ...);
常见的数据类型可以查看本文章末尾的常见数据类型汇总部分。若想将该值设为主键,可以在数据类型后面写上PRIMARY KEY
,若不是主键则可以不写。可以使用NOT NULL
来声明这个字段下的内容不填写时候的情况,比如说INT类型的数据下面,如过设置不为NULL,则会自动填上0而不是NULL。
举例创建一个student表,表中包含学号
,姓名
,性别
列内容:
CREATE TABLE student (学号 BIGINT NOT NULL PRIMARY KEY, 姓名 CHAR(16) NOT NULL, 性别 CHAR(4) NOT NULL);
此外可以使用CHECK()
语句来限制插入表中的内容。
比如下面的代码,限制了性别
这里只能添男
或者女
,否则就会报错。
CREATE TABLE people (学号 INT PRIMARY KEY, 性别 CHAR(4) CHECK(性别 IN ('男', '女')));
再比如下面的代码进一步限制了学号
只能是1~99之间的数字。
CREATE TABLE people_2 (学号 INT PRIMARY KEY CHECK(学号 > 0 AND 学号 < 100), 性别 CHAR(4) CHECK(性别 IN ('男', '女')));
关联表
在了解了主键和外键的定义之后,我们可以再创建一个表,利用REFERENCES
将两个表关联起来(FOREIGN KEY (<当前新创建表的主键名>) REFERENCES <关联表名> (<该关联表的主键>)
):
CREATE TABLE <表名> (<字段1> <数据类型> PRIMARY KEY, FOREIGN KEY (<当前新创建表的主键名>) REFERENCES <关联表名> (<该关联表的主键>),<字段2> <数据类型> <是否为NULL>, ...);
如此我们便可以创建一个新的关联表score,并且两个表中的学号
字段是共享的:
CREATE TABLE score (学号 BIGINT PRIMARY KEY, FOREIGN KEY (学号) REFERENCES student (学号), 数据库 INT NOT NULL, 数据结构 INT NOT NULL);
删除表
创建了表之后,我们如果不想要这个表了,便可以使用DROP
删除表,其用法非常简单:
DROP TABLE <表名>;
需要注意的是,DROP
操作会直接删除表,不可复原,所以请谨慎操作!
修改表
一些简单的修改表可以使用ALTER
来实现。
-- 添加列
ALTER TABLE <表名> ADD COLUMN <列名> <数据类型> <主外键>;
-- 修改列
ALTER TABLE <表名> MODIFY COLUMN <列名> <新数据类型> <主外键>;
-- 删除列
ALTER TABLE <表名> DROP COLUMN <列名>;
-- 添加外键或其它约束
ALTER TABLE <表1名> ADD CONSTRAINT <外键名> FOREIGN KEY (<列名>) REFERENCES <表2名>(<列名>);
示例:在 employees
表中新增一列 age
,数据类型为 INT
。
ALTER TABLE employees ADD COLUMN age INT;
示例:新增一个 salary
列,数据类型为小数且不允许为空。
ALTER TABLE employees ADD COLUMN salary DECIMAL(10,2) NOT NULL;
示例:删除 employees
表中的 age
列。
ALTER TABLE employees DROP COLUMN age;
示例:将 age
列的数据类型修改为 TINYINT
。
ALTER TABLE employees MODIFY COLUMN age TINYINT;
修改表的列除了经常会使用MODIFY
关键字,ALTER COLUMN
也同样适用于上面的修改数据类型。
示例:将 age
列的数据类型修改为 CHAR(10)
。
ALTER TABLE employees ALTER COLUMN age TYPE CHAR(10);
除了修改类型,ALTER COLUMN
还可以修改改列的默认值。
示例:将 salary
列的默认值设为 5000。
ALTER TABLE employees ALTER COLUMN salary SET DEFAULT 5000;
除了加入默认值,ALTER TABLE
还可以删除默认值。
示例:移除 salary
列的默认值。
ALTER TABLE employees ALTER COLUMN salary DROP DEFAULT;
除了上面一些常用的操作以外,ALTER TABLE
还可以通过RENAME COLUMN
来重命名列名。
ALTER TABLE <表名> RENAME COLUMN <列原名> TO <修改后的列名>;
示例:将 age
列重命名为 employee_age
。
ALTER TABLE employees RENAME COLUMN age TO employee_age;
对于ALTER TABLE
的操作其实还有很多衍生,但是哥们的考试基本都不会涉及,所以在这里可以放一些具体的示例作为一个简答的参考即可:
示例:为 employees
表的 employee_id
列设置主键。
ALTER TABLE employees ADD PRIMARY KEY (employee_id);
示例:为 employees
表的 department_id
列添加外键约束,引用 departments
表的 department_id
列。
ALTER TABLE employees ADD CONSTRAINT fk_department FOREIGN KEY (department_id) REFERENCES departments(department_id);
示例:移除表中的约束(只能删除已经定义的主键)。
ALTER TABLE employees DROP PRIMARY KEY;
示例:移除外键约束 fk_department
。
ALTER TABLE employees DROP FOREIGN KEY fk_department;
示例:将表 employees
重命名为 staff
。
ALTER TABLE employees RENAME TO staff;
更多操作可以产考下面GPT老师的这个表格:
插入数据(增)
使用INSERT
在表格中插入数据。INSERT
语句的基本语法是:
INSERT INTO <表名> (<字段1>, <字段2>, ...) VALUES (<值1>, <值2>, ...);
举例我们在刚刚创建的student
表中插入一行数据:
INSERT INTO student (学号, 姓名, 性别) VALUES (2024001, '托比', '男');
另外如果某些列允许为空(NULL
)或有默认值,可以只插入部分列的数据。
如果需要一次性插入多条记录,直接在VALUES
后面继续添加即可。
INSERT INTO student (学号, 姓名, 性别) VALUES (2024001, '托比', '男'), (2024002, '蒂法', '女');
删除数据(删)
可以通过DELETE
来删除表格中的某一行数据:
DELETE FROM <表名> WHERE ...;
比如我们删除刚刚插入的托比数据,WHERE
后面可以写托比这一行的相关条件(学号,姓名,性别任意一项定位即可)即可删除该条数据:
DELETE FROM student WHERE 学号 = 2024001;
DELETE
也可以通过条件删除多条数据,首先利用刚才的方法我们先多创建几行数据:
比如我们想要删除所有性别为男
的数据,可以这样做:
DELETE FROM student WHERE 性别 = '男';
关于DELETE
还需要注意的两点是:
- 如果没有查询到
WHERE
后面符合的条件内容(比如WHERE 学号 = 2023000
),代码是不会报错
的。 - 如果不加
WHERE
限制条件,DELETE
会删除整个表格的所有数据内容(DELETE FROM <表名>
),所以需要特别小心。
查询数据(查)
基本查询
我们可以使用SELECT
来完成对表格中内容的查询:
SELECT * FROM <表名>;
这样我们便可以在代码的输出结果中看到表格当前的内容了。
SELECT * FROM student;
其中SELECT
后面的*
表示的是输出表格中所有的字段,如果我们将*
替换为学号, 姓名
,那么输出的内容就不会包含性别
字段的内容。
SELECT 学号, 姓名 FROM student;
一个比较有意思的是,SELECT
后面不加表格,可以用来做一些简单的计算:
SELECT 100 + 50;
条件查询
与DELETE
一样,SELECT
也可以使用WHERE
来作为条件语句进行查询操作。
SELECT * FROM <表名> WHERE <条件表达式>;
如果条件有多个的时候,我们也可以使用AND
,OR
来连接多个条件。
我们先将刚刚删除的表格再增加一部分数据以保证表格数据的多样性。
SELECT * FROM student WHERE 性别 <> '女' AND 姓名 = '托比';
下面是 @廖雪峰的官方网站 中常用条件表达式子的总结:
模糊条件查询
当我们不完全确定要查询的内容时,我们可以使用LIKE
进行查询。
SELECT * FROM <表名> WHERE <字段> LIKE '...%';
其中我们就可以使用LIKE
去表示我们不确定的字符,例如’托%’将匹配’托比’,’托比大王’。
SELECT * FROM student WHERE 姓名 LIKE '托%';
需要注意的是,不管查询的数据类型是什么,LIKE
关键字后面都必须加单引号''
,否则就会报错!比如下面这里像查找学号是2024开头的,即使这里的学号
是BIGINT
型,但是依旧需要写成'2024%'
。
SELECT * FROM score WHERE 学号 LIKE '2024%';
集合查询
IN
操作符用于检查某个值是否在指定的值集合中。它可以替代多个 OR
条件的写法,使查询更简洁。
IN
的使用公式:
SELECT <列名> FROM <表名> WHERE <列名> IN (<值1>, <值2>, <值3>, …);
比如我们可以使用IN
来查询多个人的信息:
SELECT * FROM student WHERE 姓名 IN ('蒂法', '爱丽丝', '克劳德');
排序查询
一般我们在输出结果的时候,数据的排序都是按照主键也就是这里的学号进行排序的,如果我们需要不同的输出排序方式,便可以使用ORDER BY
语句。
SELECT <字段1>, <字段2>, ... FROM <表名> ORDER BY <FROM前面的其中若干个字段> <DESC>;
ORDER BY
字段后面的DESC
表示倒序排列,ASC
表示正序(可以省略不写)。
如果前一个排序条件有相同,则会按后一个条件再次对相同的内容进行排序。
比如我们想查询student
这个表格,并且按照姓名的倒序和性别的正序排列输出:
SELECT * FROM student ORDER BY 姓名 DESC, 性别;
多表查询
多表查询的逻辑和单表查询是基本一致的,只是在FROM
后面多填了若干个表名。
SELECT <若干字段名> FROM <表名1>, <表名2> WHERE <条件表达式>;
值的注意的一个点是,两个表中说明字段的格式是表名.字段名
。
我们在上面创建的score表中先简单写入数据。
我们可以这样查询各个表中我们需要的信息(这里由于score中的数据没有填完整,所以这里查询的时候,空白的数据就自动填充了):出现下面的原因主要是此处的代码是老式的多表查询写法(逗号分隔表名的方式),它实际执行的是笛卡尔积操作,所以导致出现这样的问题。【Old School老师真的是这么教的】
SELECT student.学号, student.姓名, score.数据库 FROM student, score;
那么此处来说明现在多表查询的方法。根据查询目标的不同,可以分为以下几种方式:内连接、外连接、交叉连接、联合查询等。
内连接
内连接(INNER JOIN
)从两个表中取出满足条件的数据,只有当两个表中都有匹配的记录时,结果才会包含该行。
比如我们此处需要同时查询出student
表中的学号
和score
表中的数据库
和数据结构
信息,可以如下操作。因为是内连接,只有同时满足两个表的匹配才会输出,所以student
和score
换位置不会对结果有影响。另外如果不写后面的条件ON student.学号 = score.学号
,会出现之前上面那种错误的情况(出现一样的名字两次,并且有莫名的分数,推测是什么笛卡尔积)。
SELECT student.姓名, score.数据库, score.数据结构
FROM student
INNER JOIN score ON student.学号 = score.学号;
左连接
下面介绍的几种方式都基本很少用,作为了解即可。
左连接(LEFT JOIN
)取左表的所有数据,以及与右表匹配的数据。如果右表没有匹配的记录,则对应的字段会显示为 NULL
。
SELECT student.学号, student.姓名, score.数据库, score.数据结构
FROM student
LEFT JOIN score ON student.学号 = score.学号;
右连接
右连接(RIGHT JOIN
)与左连接类似,但保留右表的所有数据以及与左表匹配的数据。如果左表没有匹配记录,则对应字段为 NULL
。
全外连接
全外连接(FULL OUTER JOIN)取左右表的所有数据,并显示匹配记录。没有匹配的记录对应字段为 NULL
。
注意: MySQL 不直接支持
FULL OUTER JOIN
,可以通过UNION
模拟。
后面其实还有很多连接,这里都不做涉及了,只掌握INNER JOIN
就行了。
聚合查询
聚合查询可以让我们得到某一列的合计值、平均值、最大值和最小值等。
@廖雪峰的官方网站 中列了以上这几个聚合函数的说明:
看表格的说明我们便可知其用处,SQL提供了专门的聚合函数,使用聚合函数进行查询,就是聚合查询,它可以快速获得结果。
并且使用聚合查询时,我们应该给列名设置一个别名,其主要用法如下:
SELECT <聚合函数>(<若干字段>) AS <新的字段名> FROM <表名>;
这里我们就只以COUNT
作为一个例子来说明:
SELECT COUNT(*) AS num FROM student WHERE 性别 = '女';
嵌套查询
嵌套查询(也称为子查询)是指在一个 SQL 语句中包含另一个 SQL 查询。子查询通常用于在主查询中提供一个结果集,帮助筛选、比较或汇总数据。嵌套查询的公式可以写为:
SELECT <列名> FROM <表名> WHERE <列名> <运算符> (<子查询>);
比如我们想查询student
表中一个人的信息,但是我们不知道他相关的信息,只知道他数据库
的分数是98
,但是这个分数的数据是在score
当中的,所以这个时候我们可以使用嵌套查询进行数据的查找:
SELECT * FROM student WHERE 学号 = (SELECT 学号 FROM score WHERE 数据库 = 98);
更新数据(改)
最后我们使用UPDATE
来修改更新表格当中的数据。其主要语法为:
UPDATE <表名> SET 字段1=值1, 字段2=值2, ... WHERE ...;
WHERE
前面是修改后的内容,WHERE
后面是用于定位数据的条件。
比如我们想把原来student
中托比大王
的性别改成女
,我们便可以像下面这样操作:
UPDATE student SET 性别 = '女' WHERE 姓名 = '托比大王';
这里WHERE
相关的逻辑也是和之前一样的,我们可以一次性更改表中的多个内容。比如我们想把学号
小于等于2024004
的性别
都改成未知
:
UPDATE student SET 性别 = '未知' WHERE 学号 <= 2024004;
权限相关
授权命令
GRANT
命令用于向用户或角色授予权限,允许他们对数据库的对象(如表、视图、序列等)执行特定的操作。通用的授权方式为:
GRANT <权限列表> ON <对象名> TO <用户名>;
权限列表
指的是给予用户的一些权限,常见的主要有:SELECT
、INSERT
、UPDATE
。其余的一些权限可以参考GPT老师列出来的:
对象名
主要指的就是给予用户权限可操作的表,当然也不止仅限于表,其它的还有视图、存储过程、数据库等。
用户名
就是给予权限的用户的名字。
示例:把对表student
查询、删除、插入的权限给予用户zhang
。
GRANT SELECT, INSERT, DELETE ON student TO zhang;
可以使用ALL
关键字给予用户所有的权限,当然一般最好不要把所有权限都交给用户,不然容易出现误删等各种问题。
GRANT ALL ON student TO zhang;
PUBLIC
代表的是所有的用户,如果要给所有用户权限,可以使用:
GRANT ALL ON student TO PUBLIC;
在语句最后加上WITH GRANT OPTION
,允许用户将权限交给别的用户,同时该用户本身依旧拥有原来的权限。
GRANT ALL ON student TO zhang WITH GRANT OPTION;
解权命令
如果需要撤销用户的权限,可以使用REVOKE
命令。
REVOKE <权限列表> ON <对象名> FROM <用户名>;
基本的使用方法可以参考前面的GRANT
命令,需要注意的是REVOKE
里的关键字是FROM
,注意和前面GRANT
的TO
做区分。
示例:解除zhang
对表student
查询、删除的权限。
REVOKE SELECT, DELETE ON student FROM zhang;
值得注意的是,直接使用REVOKE
除了删除用户的基本权限,还会一并删除用户的WITH GRANT OPITION
权限。
如果只想撤销用户的WITH GRANT OPTION
权限:
REVOKE GRANT OPTION FOR SELECT ON student FROM zhang;
SQL中常见数据类型汇总
整数类型
- 迷你整型:
TINYINT
,使用1个字节存储整数,最多存储256个整数(-128~127)
- 短整型:
SMALLINT
,使用2个字节存储整数
- 中整型:
MEDIUMINT
,使用3个字节存储整数
- 标准整型:
INT
,使用4个字节存储整数
- 大整型:
BIGINT
,使用8个字节存储
小数类型
- 单精度:
FLOAT
,使用4个字节存储,精度范围为6-7位有效数字
- 双精度:
DOUBLE
,使用8个字节存储,精度范围为14-15位有效数字
字符串类型
- 定长型:
CHAR(L)
,使用L指定固定长度的存储空间存储字符串
- 变长型:
VARCHAR(L)
,根据实际存储的数据变化存储空间
- 文本字符串:
TEXT
/BLOB
,专门用来存储较长的文本
- 枚举型:
ENUM
, 一种映射存储方式,以较小的空间存储较多的数据
- 集合型:
SET
,一种映射存储方式,以较小的空间存储较多的数据
日期类型
- 年:
YEAR
,MySQL中用来存储年份的类型
- 时间戳:
TIMESTAMP
,基于格林威治时间的时间记录
- 日期:
DATA
,用来记录年月日信息
- 日期时间:
DATATIME
,用来综合存储日期和时间
- 时间:
TIME
,用来记录时间或者时间段