Skip to content

21.1 数据库概论

关系型数据库基于关系模型,以二维表格存储数据,通过表间关联关系组织、管理与查询数据。

关系型数据库管理系统(Relational Database Management System,RDBMS)通过结构化查询语言(Structured Query Language,SQL)提供数据定义、数据操作和数据控制功能,通过事务机制保证数据的一致性与完整性。

在此基础上,本部分介绍关系型数据库的基本操作与 SQL 语法。

21.1.1 在 UNIX 系统中连接数据库并执行 SQL 脚本

在 UNIX 或类 UNIX 系统中,可通过命令行连接数据库并执行 SQL 脚本。

以下命令连接 MySQL 数据库并执行 SQL 脚本:

sh
# mysql -u root -p          # 以 root 用户登录 MySQL,-u 指定用户名,-p 表示需要密码验证
mysql> source FileName.sql  # 在 MySQL 交互式界面中执行指定的 SQL 文件,source 命令读取文件内容并逐条执行 SQL 语句

21.1.2 建立数据库

在关系型数据库中,数据库是存储相关数据表的容器,每个数据库具有独立的权限控制机制与存储空间。

可通过 SQL 语句创建新的数据库:

sql
create database db_name;
  • db_name:数据库名,用于标识数据库。数据库名在数据库实例中必须唯一。

21.1.3 数据库重命名

sql
rename database old_name to new_name;
  • old_name:旧数据库名,要重命名的数据库的当前名称
  • new_name:新数据库名,重命名后的数据库名称

在 MySQL 中,RENAME DATABASE 存在于早期版本,但在 MySQL 5.1.23 之后已移除,原因是该操作存在安全风险。

现代 MySQL 需要重命名数据库时,应先导出数据,再创建新数据库并导入数据。

21.1.4 查看数据库

sql
show databases;

21.1.5 进入数据库

sql
use db_name;
  • db_name:数据库名

21.1.6 删除数据库

sql
drop database db_name;
  • db_name:数据库名

21.1.7 更改数据库字符集

sql
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 建立表

sql
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 表重命名

sql
alter table old_name rename to new_name;
  • old_name:旧表名
  • new_name:新表名

21.1.11 查看数据库中有哪些表

sql
show tables;

21.1.12 展示表结构

sql
desc table_name;

21.1.13 显示表全部信息(select * from 表名)

sql
select * from table_name;

21.1.14 SQL 语法:注释

单行注释:

sql
-- 这是单行注释:注释不会被执行,用于说明 SQL 语句的用途或注意事项

多行注释:

sql
/*
   这里是多行注释
   可以跨越多行,用于描述复杂的业务逻辑或临时禁用代码块
*/

21.1.15 主键、唯一约束、非空约束与自动编号

sql
create table 表名
(
  -- 主键
  列名 数据类型 primary key,
  -- 唯一
  列名 char(20) unique,
  -- 不允许为空
  列名 数据类型 not null,
  -- 自动编号
  列名 数据类型 auto_increment
);

21.1.16 信息写入表

sql
insert into table_name (col1, col2) values (123, '李明');
  • col1:列名 1
  • col2:列名 2

21.1.17 表新增列

sql
alter table table_name
add column new_col data_type;
  • new_col:新列名
  • data_type:数据类型

21.1.18 表删除列

sql
alter table 表名 drop column 列名;

21.1.19 修改表列数据类型

sql
alter table table_name modify column col_name new_data_type;
  • new_data_type:新数据类型

21.1.20 表添加主键

sql
alter table table_name
add primary key (col_name);
  • col_name:作为主键的列名(通常为已存在的列)

21.1.21 表删除主键

sql
alter table table_name drop primary key;

21.1.22 唯一性约束

21.1.22.1 表添加唯一性约束

sql
alter table table_name
add constraint constraint_name unique (col_name);
  • constraint_name:唯一约束名
  • col_name:列名

21.1.22.2 表删除唯一性约束

sql
alter table table_name
drop index constraint_name;

21.1.23 外键

21.1.23.1 添加外键

sql
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 删除外键

sql
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 父子表和外键示例

sql
-- 创建父表 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 -- 当父表主键更新时,子表外键自动更新
);
  1. 创建父表 customers: 包含列: id:主键,用于唯一标识客户。 name:客户姓名。 email:唯一约束,用于防止重复的电子邮件地址。
  2. 创建子表 orders: order_id:主键,用于唯一标识订单。 order_date:记录订单日期。 customer_id:外键列,用于关联客户。 amount:订单金额。
  3. 设置外键: FOREIGN KEY (customer_id) REFERENCES customers(id) 表示子表的 customer_id 列引用父表的 id 列。 ON DELETE CASCADE 删除父表记录时,子表中引用该记录的行也会被删除。 ON UPDATE CASCADE 更新父表主键时,子表外键列会自动更新。

21.1.24 修改列的数据类型

sql
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 修改表信息、删除行

sql
-- 修改表信息
update 表名
set 列名 = 新值
where 条件;

SET 子句用于指定需要修改的列。如需仅修改部分记录,应通过 WHERE 子句限定条件,以明确修改范围。

sql
-- 删除行
DELETE FROM book_table
WHERE BookNumber < 200;

下面给出几个示例:

sql
update book_table
set Price = Price * 1.2
where Publisher = "人民邮电出版社";

该示例将 book_table 表中 Publisher 值为“人民邮电出版社”的记录的 Price 值统一乘以 1.2,即在原价基础上增加 20%。

sql
DELETE FROM book_table
WHERE BookNumber < 200;

DELETE FROM book_table
WHERE author IN ('王阳', '刘天洋');

21.1.25.1 WHERE 子句

WHERE 子句是 SQL 语句中的重要组成部分,用于指定筛选条件,仅操作符合条件的记录。

sql
...(updatedelete)
where Price < 50;
...(updatedelete)
WHERE author = '王阳' or author = '刘天洋';
...(updatedelete)
WHERE name in ('张三', '李四');
  1. Price 值小于 50,则执行相应操作。
  2. author 值为王阳或刘天洋,则执行相应操作。
  3. 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》
sql
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 子句(结果排序)。

sql
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 降序。

sql
SELECT student_name FROM student_table ORDER BY student_name DESC;

LIMIT a, b 用于限制查询结果的数量,其中 a 表示起始位置(从 0 开始),b 表示返回的记录条数。

sql
SELECT * from `学生表`
ORDER BY `学号` desc
LIMIT 0,3;

21.1.27.2 连接查询

连接查询是关系型数据库的核心功能,可从多个相关联的表中同时获取数据。

21.1.27.2.1 显式连接

sql
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 隐式连接

sql
SELECT name, score
FROM stu_table, score_table
WHERE stu_table.stu_id = score_table.s_id
AND name = 'Jack';

虽然隐式连接语法较为简洁,但实际开发中推荐使用显式连接,可提高可读性和可维护性。