21.1 数据库概论
关系型数据库基于关系模型,以二维表格存储数据,通过表间关联关系组织、管理与查询数据。
关系型数据库管理系统(Relational Database Management System,RDBMS)通过结构化查询语言(Structured Query Language,SQL)提供数据定义、数据操作和数据控制功能,通过事务机制保证数据的一致性与完整性。
在此基础上,本部分介绍关系型数据库的基本操作与 SQL 语法。
21.1.1 在 UNIX 系统中连接数据库并执行 SQL 脚本
在 UNIX 或类 UNIX 系统中,可通过命令行连接数据库并执行 SQL 脚本。
以下命令连接 MySQL 数据库并执行 SQL 脚本:
# mysql -u root -p # 以 root 用户登录 MySQL,-u 指定用户名,-p 表示需要密码验证
mysql> source FileName.sql # 在 MySQL 交互式界面中执行指定的 SQL 文件,source 命令读取文件内容并逐条执行 SQL 语句21.1.2 建立数据库
在关系型数据库中,数据库是存储相关数据表的容器,每个数据库具有独立的权限控制机制与存储空间。
可通过 SQL 语句创建新的数据库:
create database db_name;db_name:数据库名,用于标识数据库。数据库名在数据库实例中必须唯一。
21.1.3 数据库重命名
rename database old_name to new_name;old_name:旧数据库名,要重命名的数据库的当前名称new_name:新数据库名,重命名后的数据库名称
在 MySQL 中,RENAME DATABASE 存在于早期版本,但在 MySQL 5.1.23 之后已移除,原因是该操作存在安全风险。
现代 MySQL 需要重命名数据库时,应先导出数据,再创建新数据库并导入数据。
21.1.4 查看数据库
show databases;21.1.5 进入数据库
use db_name;db_name:数据库名
21.1.6 删除数据库
drop database db_name;db_name:数据库名
21.1.7 更改数据库字符集
alter database xxx
default character set utf8mb4;xxx:数据库名utf8mb4:字符集名称,指定数据库的默认字符集
21.1.8 SQL 数据类型
SQL 数据类型定义了表中列可以存储的数据种类和格式。
tinyint(1B)、smallint(2B)、mediumint(3B)、int(4B)、bigint(8B)float(4B)、double(8B)、decimal(整体位数, 小数点后位数)char是字符类型,若需存储字符串,则需使用char(字符数)unsigned + 数据类型可设置为无符号的数据类型
21.1.9 建立表
create table table_name (
column_name data_type,
column_name data_type,
column_name data_type
);table_name:表名column_name:列名data_type:数据类型
21.1.10 表重命名
alter table old_name rename to new_name;old_name:旧表名new_name:新表名
21.1.11 查看数据库中有哪些表
show tables;21.1.12 展示表结构
desc table_name;21.1.13 显示表全部信息(select * from 表名)
select * from table_name;21.1.14 SQL 语法:注释
单行注释:
-- 这是单行注释:注释不会被执行,用于说明 SQL 语句的用途或注意事项多行注释:
/*
这里是多行注释
可以跨越多行,用于描述复杂的业务逻辑或临时禁用代码块
*/21.1.15 主键、唯一约束、非空约束与自动编号
create table 表名
(
-- 主键
列名 数据类型 primary key,
-- 唯一
列名 char(20) unique,
-- 不允许为空
列名 数据类型 not null,
-- 自动编号
列名 数据类型 auto_increment
);21.1.16 信息写入表
insert into table_name (col1, col2) values (123, '李明');col1:列名 1col2:列名 2
21.1.17 表新增列
alter table table_name
add column new_col data_type;new_col:新列名data_type:数据类型
21.1.18 表删除列
alter table 表名 drop column 列名;21.1.19 修改表列数据类型
alter table table_name modify column col_name new_data_type;new_data_type:新数据类型
21.1.20 表添加主键
alter table table_name
add primary key (col_name);col_name:作为主键的列名(通常为已存在的列)
21.1.21 表删除主键
alter table table_name drop primary key;21.1.22 唯一性约束
21.1.22.1 表添加唯一性约束
alter table table_name
add constraint constraint_name unique (col_name);constraint_name:唯一约束名col_name:列名
21.1.22.2 表删除唯一性约束
alter table table_name
drop index constraint_name;21.1.23 外键
21.1.23.1 添加外键
ALTER TABLE table_name
ADD CONSTRAINT fk_column_name
FOREIGN KEY (fk_column)
REFERENCES tstu(sid);fk_column_name:外键名fk_column:子表中的外键列名
21.1.23.2 删除外键
alter table table_name
drop foreign key fk_name;table_name:子表名fk_name:外键名
21.1.23.3 外键的概念
外键用于建立两个表之间的关联关系,由一列或多列组成,指向另一个表的主键或唯一键,确保数据的一致性与完整性。数据库管理系统在外键约束上维护参照完整性,确保子表中的外键值必须存在于父表的主键或唯一键中,或者为 NULL(如果允许)。
子表:包含外键的表,子表中的外键列指向父表的主键或唯一键。例如上文示例中的子表。
父表:外键引用的表,父表中的被引用列通常是主键(PRIMARY KEY)或唯一键(UNIQUE)。例如上文示例中的父表。
21.1.23.4 父表数据删除失败
原因:子表中存在引用该数据的记录,数据库管理系统会阻止删除操作以维护参照完整性。 解决:使用 ON DELETE CASCADE 自动删除子表中的相关记录,或先手动删除子表记录,再删除父表记录。 ON DELETE CASCADE 是外键约束的一个选项,父表记录删除时,数据库自动删除子表中所有引用该记录的行。此机制在“自动维护父表和子表之间的参照完整性”一节中有详细说明。
21.1.23.5 父子表和外键示例
-- 创建父表 customers,包含以下列:
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY, -- 主键,自动编号
name VARCHAR(100) NOT NULL, -- 客户名
email VARCHAR(150) UNIQUE -- 唯一的电子邮件
);
-- 创建子表 orders
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY, -- 主键,订单编号
order_date DATE NOT NULL, -- 订单日期
customer_id INT, -- 外键列,关联客户 ID
amount DECIMAL(10,2), -- 订单金额
FOREIGN KEY (customer_id) REFERENCES customers(id) -- 定义外键
ON DELETE CASCADE -- 当父表记录被删除时,级联删除子表相关记录
ON UPDATE CASCADE -- 当父表主键更新时,子表外键自动更新
);- 创建父表 customers: 包含列: id:主键,用于唯一标识客户。 name:客户姓名。 email:唯一约束,用于防止重复的电子邮件地址。
- 创建子表 orders: order_id:主键,用于唯一标识订单。 order_date:记录订单日期。 customer_id:外键列,用于关联客户。 amount:订单金额。
- 设置外键:
FOREIGN KEY (customer_id) REFERENCES customers(id)表示子表的 customer_id 列引用父表的 id 列。ON DELETE CASCADE删除父表记录时,子表中引用该记录的行也会被删除。ON UPDATE CASCADE更新父表主键时,子表外键列会自动更新。
21.1.24 修改列的数据类型
ALTER TABLE 表名
MODIFY COLUMN 列名 新数据类型;
-- 例如(重设数据类型并不允许为空、设置默认值)
ALTER TABLE book_table
MODIFY COLUMN BookName CHAR(100) NOT NULL DEFAULT '《书名》';
-- 如果修改的列是外键,必须先删除外键约束,然后修改数据类型,最后重新添加外键约束
alter table 子表 drop FOREIGN KEY 外键名;
alter table 子表 modify column 列名 新数据类型;
alter table 子表 add constraint 外键名 FOREIGN KEY (列名) REFERENCES 父表名(父列名);21.1.25 修改表信息、删除行
-- 修改表信息
update 表名
set 列名 = 新值
where 条件;SET 子句用于指定需要修改的列。如需仅修改部分记录,应通过 WHERE 子句限定条件,以明确修改范围。
-- 删除行
DELETE FROM book_table
WHERE BookNumber < 200;下面给出几个示例:
update book_table
set Price = Price * 1.2
where Publisher = "人民邮电出版社";该示例将 book_table 表中 Publisher 值为“人民邮电出版社”的记录的 Price 值统一乘以 1.2,即在原价基础上增加 20%。
DELETE FROM book_table
WHERE BookNumber < 200;
DELETE FROM book_table
WHERE author IN ('王阳', '刘天洋');21.1.25.1 WHERE 子句
WHERE 子句是 SQL 语句中的重要组成部分,用于指定筛选条件,仅操作符合条件的记录。
...(update 或 delete)
where Price < 50;
...(update 或 delete)
WHERE author = '王阳' or author = '刘天洋';
...(update 或 delete)
WHERE name in ('张三', '李四');- 若
Price值小于 50,则执行相应操作。 - 若
author值为王阳或刘天洋,则执行相应操作。 - 若
name值为张三或李四,则执行相应操作。
WHERE 子句指定条件表达式,该表达式计算并返回布尔值。
21.1.25.2 SQL 运算符
运算符是 SQL 语句中用于数据计算和比较的符号,分为算术运算符、比较运算符、逻辑运算符和特殊运算符等几类。
21.1.25.2.1 算术运算符
+加法运算符-减法运算符*乘法运算符/除法运算符%取模运算符
21.1.25.2.2 比较运算符
=等于(在 SQL 中用于比较,而非赋值)!=不等于<小于>大于<=小于等于>=大于等于<=>NULL 安全等于,NULL <=> NULL,返回结果是 TRUE
21.1.25.2.3 逻辑运算符
and两条件都为真时才返回真,否则为假or两条件有一个为真时返回真,全为假时才返回假not反转真假xor仅一个条件为真时才返回真,否则返回假
21.1.25.2.4 特殊运算符
in:“值在列表中”运算符,用于筛选符合条件的记录,并返回布尔结果,供 update 或 delete 语句使用。例如5 in (1, 3, 5)返回真。between范围匹配:例如5 between 1 and 10返回真。like模式匹配:'abc' like 'a%'返回真。百分号在此处功能类似 shell 通配符。IS NULL“判断表项是否为 NULL”:NULL IS NULL返回 TRUE。 示例:查看书名条目是否存在《xxx 设计 yyy》。
select * from book_table
where BookName like '%设计%';
select * from book_table
where BookName like '_____';
-- 五个下划线代表五个字,返回长度为 5 个字的书名。在书籍管理数据库中,使用 LIKE '%设计%' 会返回类似《MySQL 数据库设计》的书名。
21.1.26 自动维护父表和子表之间的参照完整性
参照完整性确保相关表之间数据的一致性。父表数据变化时,子表中的相关数据也需相应调整。
- CASCADE 级联操作:父表记录删除/更新时,子表中相关记录也一并删除/更新。
- SET NULL 将子表中的外键列设置为 NULL(要求外键列允许 NULL)。
- RESTRICT 拒绝操作:不允许删除/更新父表中被引用的记录(立即返回错误)。
- NO ACTION 类似 RESTRICT。在 MySQL 中,二者完全等价,均立即拒绝违反参照完整性的操作。在 SQL 标准中,NO ACTION 在语句结束时检查完整性,而非延迟到事务结束。
- SET DEFAULT 设置为默认值,MySQL 不支持。
21.1.27 SELECT 语句
SELECT 语句是 SQL 中最常用的查询语句,用于从数据库中检索数据。SELECT 关键字后指定要查询的列名,使用 * 表示选择所有列。SELECT 语句的基本语法包括 SELECT 子句(指定要返回的列)、FROM 子句(指定数据源表)、WHERE 子句(指定过滤条件)、GROUP BY 子句(分组聚合)、HAVING 子句(分组过滤)和 ORDER BY 子句(结果排序)。
select * from student_table
where age = (select max(age) from student_table);该查询用于显示 student_table 中年龄等于该表最大年龄值的记录。内部子查询 (select max(age) from student_table) 首先执行,返回表中的最大年龄值;外部查询使用 WHERE 子句过滤出年龄等于该最大值的所有记录。
21.1.27.1 升序输出和降序输出
排序是查询的重要功能,通过 ORDER BY 子句可以指定查询结果的排序方式。
ASC 升序,DESC 降序。
SELECT student_name FROM student_table ORDER BY student_name DESC;LIMIT a, b 用于限制查询结果的数量,其中 a 表示起始位置(从 0 开始),b 表示返回的记录条数。
SELECT * from `学生表`
ORDER BY `学号` desc
LIMIT 0,3;21.1.27.2 连接查询
连接查询是关系型数据库的核心功能,可从多个相关联的表中同时获取数据。
21.1.27.2.1 显式连接
SELECT name, score --name 来自学生表,score 来自分数表
FROM stu_table -- 表一
JOIN score_table -- 表二
ON stu_table.stu_id = score_table.s_id; -- 连接条件
WHERE name = 'Jack' -- 筛选条件,后面还可以接上 AND 或 OR。name 取自 stu_tablescore 取自 score_table
21.1.27.2.2 隐式连接
SELECT name, score
FROM stu_table, score_table
WHERE stu_table.stu_id = score_table.s_id
AND name = 'Jack';虽然隐式连接语法较为简洁,但实际开发中推荐使用显式连接,可提高可读性和可维护性。