前言
本文档主要以 CentOS 7 和 MySQL 5.7 作为示例,MySQL 8+ 有许多内容不通用,请注意甄别
1. MySQL 介绍
1.1 数据库与 MySQL
数据库用于存放数据,在软件开发过程中,这种方式更便于管理 、速度快 、效率高
MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
数据库常用的专业术语及含义如下:
- MySQL 服务器 (MySQL Server):安装了 MySQL 程序的计算机,称为 MySQL 服务器
- 数据库 (Database, DB):存储数据表的仓库,一般会为每个应用都创建一个数据库
- 数据表 (Table):存放于数据库中,用于存放每个实体的数据
- 记录 (Record) :即数据表的行
- 字段 (Field) :即数据表的列
- SQL 语句 :对数据库、数据表、数据进行操作的语句,以
;为结尾 - SQL 注释语句 :用于解释 SQL 语句含义的语句,不会被执行,单行注释以
--开头,多行注释使用/*和*/包裹
1.2 SQL
SQL (Structured Query Language: 结构化查询语言) 是用于管理关系数据库管理系统(RDBMS),它通过一系列的语句和命令来执行数据定义、数据查询、数据操作和数据控制等功能,包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制
某些数据库系统要求在每条 SQL 语句的末端使用分号,分号是在数据库系统中分隔每条 SQL 语句的标准方法,这样就可以在对服务器的相同请求中执行一条以上的 SQL 语句
SQL 对大小写不敏感
SQL 语句使用以下符号表示不同的注释:
sql
-- 单行注释
/*
多行注释
*/
/* 行内注释 */
1.3 数据表
表是数据库的最基本的构成对象,是存储数据的基本单位
一张表就是一个关系,由行和列组成,每行代表一条记录 ,每列代表记录的一个字段
一个数据库可以由一张或多张表构成
1.3.1 表的命名
一张表的名字由数据库名 和数据表名两部分构成,如下:
sql
数据库名.数据表名
那么 database 库中的 table 表应表示为 database.table
1.3.2 表的命名规则
数据表的命名应遵循 MySQL 对象命名规则,如下:
- 名称由当前字符集的任意 字母、数字、字符 以及 下划线、美元符 组成
- 名称长度不超过 64 个字符
- 严格区分大小写
1.3.3 字段
即表的列,每一张表都拥有多个字段,为方便识别,每个字段必须拥有一个名称,规则如下:
- 字段名可以包含 中文、字母、数字、下划线、美元符、井号(#)、at符号(@)
- 长度不超过 64 个字符
- 字段名不可重复
1.4 MySQL 数据类型
MySQL 支持多种数据类型,主要有:
- 数值数据类型
- 字符串类型
- 浮点数类型
- 定点数类型
所有数值类型都支持有符号或无符号
1.4.1 整数类型
| 类型 | 存储空间 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| tinyint | 1 Byte | -128 ~ 127 | 0 ~ 255 |
| smallint | 2 Byte | -32768 ~ 32767 | 0 ~ 65535 |
| mediumint | 3 Byte | -8388608 ~ 8388607 | 0 ~ 16777215 |
| int | 4 Byte | -2147483648 ~ 2147483647 | 0 ~ 4294967295 |
| tinyint | 8 Byte | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 |
1.4.2 浮点和定点数类型
| 类型 | 存储空间 | 说明 |
|---|---|---|
| float(m,d) | 4 Byte | 单精度浮点型 |
| double(m,d) / real(m,d) | 8 Byte | 双精度浮点数 |
| decimal(m,d) / numeric(m,d) | 若 p>s 则为 p+2 Byte,否则为 s+2 Byte | 定点数,默认精度为 10,小数点位数为 0 |
p 为精度,即整体位数(含小数点)是多少位,s 表示小数部分占的位数
如 float(5,2) 表示该数值类型一共有 5 位,整数和小数部分分别有 2 位
1.4.3 位类型
| 类型 | 存储空间 | 取值范围 | 说明 |
|---|---|---|---|
| bit(m) | 约 (m+7)/8 Byte | 0 和 1,若 m 省略,默认值为 1 | m 表示每个值的位数,从 1 到 64 |
1.4.4 字符串类型
| 类型说明 | 存储空间 | 说明 |
|---|---|---|
| char(m) | m Byte | 固定长度字符串 |
| binary(m) | m Byte | |
| varchar(m), varbinary(m) | 若字符个数少于 255,则为总长 +1 Byte,否则为总长 +2 Byte | 可变长字符串 |
| tniytext | 总长 +1 Byte | 特殊字符串类型 |
| text | 总长 +2 Byte | |
| mediumtext | 总长 +3 Byte | |
| longtext | 总长 +4 Byte |
1.4.5 日期类型
| 类型 | 存储空间 | 数值范围 | 说明 |
|---|---|---|---|
| date | 3 Byte | 1001-01-01 ~ 9999-12-31 | 存储日期格式:YYYY-MM-DD |
| time | 3 Byte + 小数秒存储 | -838:59:59 ~ -838:59:59 | 存储时间格式:hh:mm:ss |
| datetime | 5 Byte + 小数秒存储 | 1001-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 日期时间格式:YYYY-MM-DD hh:mm:ss |
| timestamp | 4 Byte + 小数秒存储 | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 | 日期时间格式:YYYY-MM-DD hh:mm:ss |
| year | 1 Byte | 1901 ~ 2155 | 表示年,格式 YYYY |
1.5 数据完整性约束
NULL和NOT NULL:分别表示允许空值和不允许空值,在建表时会对字段设定该参数AUTO_INCREMENT:属性值自动增加,初始值为 1,每插入一条记录时基于上一条记录的值 +1PRIMARY KEY:主键,是该表的唯一认证标准,一张表中仅允许有一个主键,值不可重复且不许为空FOREIGN KEY:外键,可以是一列或多列的组合,用于表示两表之间的关系UNIQUE:强制表中一列或多列的唯一性,即输入表中的记录中某列或多列的值不会重复,可以为空但不允许多行连续为空,可以有多个 UNIQUE 约束DEFAULT:即当没有为列指定值时,使用默认值进行自动补充CHECK:对输入的值进行检查,满足条件才有效,否则不允许将值插入到表中,一个 CHECK 约束可用于多列,一列也可以有多个 CHECK 约束
2. MySQL 安装与基本配置
2.1 在 Windows 上安装和配置 MySQL
略
2.2 在 Linux 上安装和配置 MySQL
2.2.1 安装 MySQL
bash
# 1. 获取 mysql 软件包并解压
[root@mysql ~]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar
[root@mysql ~]# mkdir mysqlpack
[root@mysql ~]# tar -xvf mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar -C ./mysqlpack/
# 2. 导入 mysql 软件包
[root@mysql ~]# cd mysqlpack/
[root@mysql mysqlpack]# rpm -ivh \
mysql-community-common-5.7.44-1.el7.x86_64.rpm \
mysql-community-libs-5.7.44-1.el7.x86_64.rpm \
mysql-community-client-5.7.44-1.el7.x86_64.rpm \
mysql-community-server-5.7.44-1.el7.x86_64.rpm
# 3. 更新并安装 mysql
[root@mysql ~]# yum update -y
[root@mysql ~]# yum install -y mysql-community-server
!NOTE
- 如遇到诸如
file /usr/share/mysql/charsets/hp8.xml from install of mysql-community-common-5.7.44-1.el7.x86_64 conflicts with file from package mariadb-libs-1:5.5.68-1.el7.x86_64的报错,需要使用命令rpm -e --nodeps 旧软件包名如rpm -e --nodeps mariadb-libs清理旧版本- 如遇到诸如
错误:依赖检测失败:net-tools 被 mysql-community-server-5.7.44-1.el7.x86_64 需要的报错,则需要手动安装依赖软件包,如yum install net-tools -y
2.2.2 初始化 MySQL
bash
# 1. 将 mysql 目录授予 mysql 用户所有权
[root@mysql ~]# chown -R mysql:mysql /var/lib/mysql/
# 2. 启动并启用 mysql
[root@mysql ~]# systemctl enable mysqld --now
# 3. 初始化 mysql
[root@mysql ~]# mysql_secure_installation
Securing the MySQL server deployment.
Enter password for user root: # 输入 root 密码,MySQL 5.7 及以上版本需使用命令 grep 'temporary password' /var/log/mysqld.log 查看临时密码
The existing password for the user account root has expired. Please set a new password.
New password: # 设置新密码,要求包含:大小写字母、数字、特殊符号
Re-enter new password: # 确认新密码
Change the password for root ? (Press y|Y for Yes, any other key for No) : # 是否修改 root 密码,输入 y/Y 确认,其它任意键取消
... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y # 是否删除匿名用户,输入 y/Y 确认,其它任意键取消
Success.
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y # 是否禁用 root 远程登录,输入 y/Y 确认,其它任意键取消
Success.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y # 是否删除测试数据库,输入 y/Y 确认,其它任意键取消
- Dropping test database...
Success.
- Removing privileges on test database...
Success.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y # 是否立刻重新加载配置,输入 y/Y 确认,其它任意键取消
Success.
All done!
!NOTE
如果觉得严格密码策略不便于学习,可以在
/etc/my.cnf配置文件中进行以下修改
bash[mysqld] validate_password_policy=LOW # 设置密码验证强度等级为 LOW validate_password_length=4 # 设置密码验证长度为 4 位完成后使用命令
systemctl restart mysqld重启服务,在 mysql 命令行使用命令SHOW VARIABLES LIKE 'validate_password%';查看修改是否生效,并使用命令ALTER USER 'root'@'localhost' IDENTIFIED BY 'NEWPASSWORD';修改 root 密码
2.3 图形化数据库管理管理工具
市面上有众多图形化数据库管理工具,这里推荐使用 Navicat 或 DBeaver,前者需要购买正版,后者有免费的社区版
使用教程待更新
3. mysql 基本操作
3.1 登录 mysql
使用 mysql 命令登录数据库,语法如下:
bash
mysql [参数]
# 常用操作:
# -h HOSTNAME: 登录到 HOSTNAME 主机的数据库
# -u USERNAME: 使用 USERNAME 用户登录数据库
# -P PORT: 使用 PORT 端口登录数据库
# -p: 交互式输入密码
示例:
bash
[root@mysql ~]# mysql -u root -p
Enter password: # 输入密码
mysql> # Success!
3.2 退出 mysql
在 mysql 命令行中,输入 exit 命令退出数据库,示例:
bash
mysql> exit
Bye
[root@mysql ~]#
3.3 mysql 基本配置
配置 mysql 数据库设置有两种方式,一种是在 mysql 命令行使用命令修改,另一种则是直接修改数据库配置文件
在 Linux 中,mysql 的配置文件默认路径为 /etc/my.cnf
3.3.1 配置允许 root 远程登录
如果不配置 root 远程登录,则会无法使用 Navicat 等图形化工具通过 root 连接至远程 MySQL 主机
解决方案有两个
- 创建一个数据库账号专用于远程连接的账号,给它有限的权限,这也是生产环境建议使用的方法
- 设置允许 root 远程登录
这里暂时为了学习方便,介绍第二种方法
- 从本地登录到 mysql 中
- 确认权限
sql
mysql> USE mysql;
mysql> SELECT User, Host FROM user;
+---------------+-----------+
| User | Host |
+---------------+-----------+
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost | -- root 仅允许从 localhost 登录
+---------------+-----------+
- 授予 root 远程登录的权限
sql
-- 1. 授予权限
-- ! 注:该语句仅适用于 MySQL 5.7 及以下版本
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '密码' WITH GRANT OPTION;
-- 2. 刷新权限
mysql> FLUSH PRIVILEGES;
-- 3. 确认权限
mysql> SELECT User, Host FROM user;
+---------------+-----------+
| User | Host |
+---------------+-----------+
| root | % | -- root 被允许从任何地址登录
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
3.3.2 设置 mysql 默认字符集
mysql 中与字符集相关的配置有 8 个,查看它们当前设置的命令如下
sql
mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
如果当我们创建数据库、表或者其它类似操作时没有指定字符集和排序方式,则会按照默认的设置执行,这有时会导致与我们的预期不符(如我想要数据库使用 utf8mb4 字符集,但默认 latin1)
此时就需要修改部分默认的配置
以下是配置过程和内容,仅供参考
bash
# 1. 打开配置文件
[root@mysql ~]# vim /etc/my.cnf
# 2. 添加配置
[mysqld]
# 服务器级默认字符集
character-set-server = utf8mb4
# 服务器级默认排序规则
collation-server = utf8mb4_general_ci
# 支持索引长度超过767字节(解决utf8mb4索引长度限制问题)
innodb_large_prefix = ON
innodb_file_format = Barracuda
innodb_file_per_table = ON
[client]
# 客户端连接时的默认字符集
default-character-set = utf8mb4
[mysql]
# MySQL命令行客户端的默认字符集
default-character-set = utf8mb4
# 3. 重启 mysqld 服务
[root@mysql ~]# systemctl restart mysqld
# 4. 验证配置
mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
4. 数据库基本操作
4.1 创建数据库
使用 CREATE DATABASE 命令创建数据库,具体语法如下:
sql
CREATE DATABASE 数据库名 [选项与参数];
/*
* 常用选项与参数:
* CHARACTER SET: 设置数据库使用指定字符集,常用参数为 uft8mb4
*
* COLLATE: 设置数据库使用的排序方式,常用参数为 utf8mb4_general_ci
*/
示例:
sql
mysql> CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.00 sec)
4.2 查看数据库
使用命令 SHOW DATABASES; 查看数据库,示例:
sql
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test_db |
+--------------------+
5 rows in set (0.02 sec)
4.3 删除数据库
使用 DROP DATABASE 命令删除数据库,具体语法如下:
sql
DROP DATABASE 数据库名;
示例:
sql
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test_db | -- test_db 存在
+--------------------+
5 rows in set (0.02 sec)
-- 删除 test_db
mysql> DROP DATABASE test_db;
Query OK, 0 rows affected (0.02 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+ -- test_db 消失
4 rows in set (0.00 sec)
4.4 切换数据库
使用 USE 命令切换到数据库中,语法如下:
sql
USE 数据库名;
示例:
sql
mysql> SHOW TABLES;
ERROR 1046 (3D000): No database selected -- 未选中任何数据库时,查看表操作会报错
mysql> USE mysql;
Database changed
mysql> SHOW TABLES;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| engine_cost |
| event |
| func |
| ... |
+---------------------------+
4.5 数据库导入
使用 SOURCE 命令可以将 sql 文件导入数据库,语法如下:
sql
SOURCE 文件路径;
示例:导入一个学生信息管理系统数据库,这个库也是本篇主要用的数据库
- 准备文件
sql
[root@mysql ~]# vim edu_db.sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for class
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
`clno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程号',
`clname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程名',
`mno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '专业号',
PRIMARY KEY (`clno`) USING BTREE,
INDEX `fk_class_major`(`mno`) USING BTREE,
CONSTRAINT `fk_class_major` FOREIGN KEY (`mno`) REFERENCES `major` (`mno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of class
-- ----------------------------
INSERT INTO `class` VALUES ('13012201', '22计算机科学与技术1班', '1301');
INSERT INTO `class` VALUES ('13012202', '22计算机科学与技术2班', '1301');
INSERT INTO `class` VALUES ('13022201', '22软件工程1班', '1302');
INSERT INTO `class` VALUES ('13022202', '22软件工程2班', '1302');
INSERT INTO `class` VALUES ('13022301', '23软件工程1班', '1302');
INSERT INTO `class` VALUES ('13032301', '23计算机网络1班', '1303');
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`cno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程号',
`cname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程名',
`mno` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '专业号',
PRIMARY KEY (`cno`) USING BTREE,
INDEX `fk_course_major`(`mno`) USING BTREE,
CONSTRAINT `fk_course_major` FOREIGN KEY (`mno`) REFERENCES `major` (`mno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('C01', '离散数学', '1301');
INSERT INTO `course` VALUES ('C02', '计算机基础', '1301');
INSERT INTO `course` VALUES ('C03', '操作系统原理', '1301');
INSERT INTO `course` VALUES ('C04', 'C 语言程序设计', '1301');
INSERT INTO `course` VALUES ('C05', 'Windows Server 操作系统', '1301');
INSERT INTO `course` VALUES ('C06', 'CAD 制图', '1301');
INSERT INTO `course` VALUES ('C07', 'C++ 程序设计', '1302');
INSERT INTO `course` VALUES ('C08', 'Java 语言基础', '1302');
INSERT INTO `course` VALUES ('C09', 'J2EE 程序设计', '1302');
INSERT INTO `course` VALUES ('C10', '软件系统设计', '1302');
INSERT INTO `course` VALUES ('C11', 'Linux 操作系统', '1302');
INSERT INTO `course` VALUES ('C12', 'MySQL 数据库', '1302');
INSERT INTO `course` VALUES ('C13', '计算机网络', '1303');
INSERT INTO `course` VALUES ('C14', '网页设计', '1303');
INSERT INTO `course` VALUES ('C15', '图形设计', '1303');
INSERT INTO `course` VALUES ('C16', 'UI 设计', '1303');
INSERT INTO `course` VALUES ('C17', '动态网页制作', '1303');
INSERT INTO `course` VALUES ('C18', '大数据应用', '1303');
-- ----------------------------
-- Table structure for major
-- ----------------------------
DROP TABLE IF EXISTS `major`;
CREATE TABLE `major` (
`mno` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '专业号码',
`mname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '专业名',
PRIMARY KEY (`mno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of major
-- ----------------------------
INSERT INTO `major` VALUES ('1301', '计算机科学与技术');
INSERT INTO `major` VALUES ('1302', '软件工程');
INSERT INTO `major` VALUES ('1303', '计算机网络');
-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
`sno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学号',
`cno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程号',
`peacetime` decimal(5, 1) NULL DEFAULT NULL COMMENT '平时成绩',
`final` decimal(5, 1) NULL DEFAULT NULL COMMENT '期末成绩',
`total` decimal(5, 1) GENERATED ALWAYS AS (((`peacetime` * 0.4) + (`final` * 0.6))) VIRTUAL NULL,
PRIMARY KEY (`sno`, `cno`) USING BTREE,
INDEX `tk_score_course`(`cno`) USING BTREE,
CONSTRAINT `tk_score_course` FOREIGN KEY (`cno`) REFERENCES `course` (`cno`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `tk_score_student` FOREIGN KEY (`sno`) REFERENCES `student` (`sno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES ('S1301220101', 'C01', 92.0, 95.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220101', 'C02', 85.0, 78.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220101', 'C03', 88.0, 91.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220102', 'C01', 76.0, 88.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220102', 'C02', 90.0, 83.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220102', 'C03', 84.0, 79.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220103', 'C01', 68.0, 48.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220103', 'C02', 72.0, 66.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220103', 'C03', 60.0, 71.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220104', 'C01', 89.0, 93.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220104', 'C02', 67.0, 75.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220104', 'C03', 81.0, 69.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220105', 'C01', 74.0, 62.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220105', 'C02', 78.0, 81.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220105', 'C03', 69.0, 64.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220106', 'C01', 83.0, 59.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220106', 'C02', 86.0, 88.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220106', 'C03', 77.0, 72.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220201', 'C01', 71.0, 67.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220201', 'C02', 65.0, 72.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220201', 'C03', 79.0, 74.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220202', 'C01', 88.0, 94.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220202', 'C02', 82.0, 86.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220202', 'C03', 91.0, 89.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220203', 'C01', 60.0, 52.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220203', 'C02', 68.0, 70.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220203', 'C03', 73.0, 65.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220204', 'C01', 95.0, 97.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220204', 'C02', 87.0, 90.0, DEFAULT);
INSERT INTO `score` VALUES ('S1301220204', 'C03', 84.0, 88.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220101', 'C07', 90.0, 93.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220101', 'C08', 85.0, 89.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220101', 'C09', 78.0, 82.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220101', 'C10', 80.0, 76.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220102', 'C07', 88.0, 54.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220102', 'C08', 82.0, 87.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220102', 'C09', 75.0, 79.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220102', 'C10', 70.0, 73.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220103', 'C07', 67.0, 72.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220103', 'C08', 72.0, 69.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302220103', 'C09', 74.0, 68.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230101', 'C07', 93.0, 96.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230101', 'C08', 89.0, 92.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230101', 'C11', 86.0, 84.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230102', 'C07', 82.0, 85.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230102', 'C08', 75.0, 80.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230102', 'C11', 78.0, 73.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230103', 'C07', 79.0, 58.0, DEFAULT);
INSERT INTO `score` VALUES ('S1302230103', 'C08', 70.0, 66.0, DEFAULT);
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`sno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学号',
`sname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
`ssex` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '男' COMMENT '性别',
`sbirthday` date NULL DEFAULT NULL COMMENT '出生年月',
`sphone` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系方式',
`clno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '班级号',
PRIMARY KEY (`sno`) USING BTREE,
INDEX `fk_student_class`(`clno`) USING BTREE,
CONSTRAINT `fk_student_class` FOREIGN KEY (`clno`) REFERENCES `class` (`clno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('S1301220101', '张伟', '男', '2003-02-10', '1380000001', '13012201');
INSERT INTO `student` VALUES ('S1301220102', '李婷婷', '女', '2003-05-12', '1380000002', '13012201');
INSERT INTO `student` VALUES ('S1301220103', '王子涵', '男', '2003-08-18', '1380000003', '13012201');
INSERT INTO `student` VALUES ('S1301220104', '赵伟', '男', '2003-11-22', '1380000004', '13012201');
INSERT INTO `student` VALUES ('S1301220105', '孙丽丽', '女', '2003-03-15', '1380000005', '13012201');
INSERT INTO `student` VALUES ('S1301220106', '周六', '男', '2003-06-09', '1380000006', '13012201');
INSERT INTO `student` VALUES ('S1301220107', '吴怡', '女', '2003-09-01', '1380000007', '13012201');
INSERT INTO `student` VALUES ('S1301220108', '陈广飞', '男', '2003-12-12', '1380000008', '13012201');
INSERT INTO `student` VALUES ('S1301220109', '王静文', '女', '2003-04-20', '1380000009', '13012201');
INSERT INTO `student` VALUES ('S1301220110', '李强', '男', '2003-07-07', '1380000010', '13012201');
INSERT INTO `student` VALUES ('S1301220111', '陈佳怡', '女', '2003-10-10', '1380000011', '13012201');
INSERT INTO `student` VALUES ('S1301220112', '刘鹏', '男', '2003-01-01', '1380000012', '13012201');
INSERT INTO `student` VALUES ('S1301220201', '陈涛', '男', '2003-03-03', '1380000013', '13012202');
INSERT INTO `student` VALUES ('S1301220202', '李娜', '女', '2003-06-06', '1380000014', '13012202');
INSERT INTO `student` VALUES ('S1301220203', '王刚', '男', '2003-09-09', '1380000015', '13012202');
INSERT INTO `student` VALUES ('S1301220204', '赵思雨', '女', '2003-12-12', '1380000016', '13012202');
INSERT INTO `student` VALUES ('S1301220205', '孙强', '男', '2003-02-02', '1380000017', '13012202');
INSERT INTO `student` VALUES ('S1301220206', '周敏', '女', '2003-05-05', '1380000018', '13012202');
INSERT INTO `student` VALUES ('S1301220207', '刘文轩', '男', '2003-08-08', '1380000019', '13012202');
INSERT INTO `student` VALUES ('S1301220208', '郑子龙', '男', '2003-11-11', '1380000020', '13012202');
INSERT INTO `student` VALUES ('S1301220209', '王诗雨', '女', '2003-04-04', '1380000021', '13012202');
INSERT INTO `student` VALUES ('S1301220210', '李文武', '男', '2003-07-07', '1380000022', '13012202');
INSERT INTO `student` VALUES ('S1302220101', '蒋东宇', '男', '2004-02-01', '1380000023', '13022201');
INSERT INTO `student` VALUES ('S1302220102', '刘娜', '女', '2004-05-03', '1380000024', '13022201');
INSERT INTO `student` VALUES ('S1302220103', '夏刚', '男', '2004-08-05', '1380000025', '13022201');
INSERT INTO `student` VALUES ('S1302220104', '王静怡', '女', '2004-11-07', '1380000026', '13022201');
INSERT INTO `student` VALUES ('S1302220105', '刘大力', '男', '2004-03-09', '1380000027', '13022201');
INSERT INTO `student` VALUES ('S1302220106', '王桂兰', '女', '2004-06-11', '1380000028', '13022201');
INSERT INTO `student` VALUES ('S1302220107', '孙文涛', '男', '2004-09-13', '1380000029', '13022201');
INSERT INTO `student` VALUES ('S1302220108', '丁思蕊', '女', '2004-12-15', '1380000030', '13022201');
INSERT INTO `student` VALUES ('S1302220109', '赵家辉', '男', '2004-04-17', '1380000031', '13022201');
INSERT INTO `student` VALUES ('S1302220110', '吕雨辰', '女', '2004-07-19', '1380000032', '13022201');
INSERT INTO `student` VALUES ('S1302230101', '周天宇', '男', '2002-03-10', '1380000033', '13022301');
INSERT INTO `student` VALUES ('S1302230102', '杨圆圆', '女', '2002-06-15', '1380000034', '13022301');
INSERT INTO `student` VALUES ('S1302230103', '张鹏', '男', '2002-09-20', '1380000035', '13022301');
INSERT INTO `student` VALUES ('S1302230104', '王磊', '男', '2002-12-25', '1380000036', '13022301');
INSERT INTO `student` VALUES ('S1302230105', '刘雨桐', '女', '2002-04-18', '1380000037', '13022301');
INSERT INTO `student` VALUES ('S1302230106', '张伟', '男', '2002-07-22', '1380000038', '13022301');
INSERT INTO `student` VALUES ('S1302230107', '赵丽', '女', '2002-10-30', '1380000039', '13022301');
INSERT INTO `student` VALUES ('S1302230108', '陈玉杰', '男', '2002-01-12', '1380000040', '13022301');
INSERT INTO `student` VALUES ('S1303230101', '张三', '男', '2003-08-20', '1380000041', '13032301');
INSERT INTO `student` VALUES ('S1303230102', '李四', '男', '2003-11-25', '1380000042', '13032301');
INSERT INTO `student` VALUES ('S1303230103', '王五', '男', '2003-09-03', '1380000043', '13032301');
INSERT INTO `student` VALUES ('S1303230104', '赵六', '男', '2004-01-15', '1380000044', '13032301');
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`tno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '教师号',
`tname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '教师姓名',
`tsex` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '男' COMMENT '教师性别',
`tbirthday` date NULL DEFAULT NULL COMMENT '出生日期',
PRIMARY KEY (`tno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('T01', '张伟', '男', '1980-03-15');
INSERT INTO `teacher` VALUES ('T02', '李红梅', '女', '1985-07-22');
INSERT INTO `teacher` VALUES ('T03', '王强', '男', '1978-11-09');
INSERT INTO `teacher` VALUES ('T04', '刘小洋', '男', '1990-01-18');
INSERT INTO `teacher` VALUES ('T05', '王娅', '女', '1987-05-30');
INSERT INTO `teacher` VALUES ('T06', '赵磊', '男', '1982-09-12');
INSERT INTO `teacher` VALUES ('T07', '孙丽丽', '女', '1992-06-25');
INSERT INTO `teacher` VALUES ('T08', '高建国', '男', '1975-12-03');
INSERT INTO `teacher` VALUES ('T09', '吴小敏', '女', '1988-04-17');
INSERT INTO `teacher` VALUES ('T10', '孙涛', '男', '1993-10-08');
INSERT INTO `teacher` VALUES ('T11', '陈岩', '男', '1985-04-29');
-- ----------------------------
-- Table structure for teaplan
-- ----------------------------
DROP TABLE IF EXISTS `teaplan`;
CREATE TABLE `teaplan` (
`tpno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '教学计划编号',
`tno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '教师号',
`clno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '班级号',
`cno` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程号',
`state` tinyint(4) NULL DEFAULT 0 COMMENT '授课进度,0=未开课,1=授课中,2=结课',
PRIMARY KEY (`tpno`) USING BTREE,
INDEX `fk_teaplan_teacher`(`tno`) USING BTREE,
INDEX `fk_teaplan_class`(`clno`) USING BTREE,
INDEX `fk_teaplan_course`(`cno`) USING BTREE,
CONSTRAINT `fk_teaplan_class` FOREIGN KEY (`clno`) REFERENCES `class` (`clno`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_teaplan_course` FOREIGN KEY (`cno`) REFERENCES `course` (`cno`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_teaplan_teacher` FOREIGN KEY (`tno`) REFERENCES `teacher` (`tno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of teaplan
-- ----------------------------
INSERT INTO `teaplan` VALUES ('1', 'T01', '13012201', 'C01', 2);
INSERT INTO `teaplan` VALUES ('10', 'T06', '13022201', 'C07', 2);
INSERT INTO `teaplan` VALUES ('11', 'T07', '13022201', 'C08', 2);
INSERT INTO `teaplan` VALUES ('12', 'T08', '13022201', 'C09', 2);
INSERT INTO `teaplan` VALUES ('13', 'T09', '13022201', 'C10', 2);
INSERT INTO `teaplan` VALUES ('14', 'T10', '13022201', 'C11', 2);
INSERT INTO `teaplan` VALUES ('15', 'T06', '13022202', 'C07', 2);
INSERT INTO `teaplan` VALUES ('16', 'T07', '13022202', 'C08', 2);
INSERT INTO `teaplan` VALUES ('17', 'T08', '13022202', 'C09', 2);
INSERT INTO `teaplan` VALUES ('18', 'T09', '13022202', 'C10', 2);
INSERT INTO `teaplan` VALUES ('19', 'T06', '13022301', 'C07', 2);
INSERT INTO `teaplan` VALUES ('2', 'T02', '13012201', 'C02', 2);
INSERT INTO `teaplan` VALUES ('20', 'T07', '13022301', 'C08', 2);
INSERT INTO `teaplan` VALUES ('21', 'T08', '13022301', 'C11', 2);
INSERT INTO `teaplan` VALUES ('22', 'T09', '13022301', 'C12', 2);
INSERT INTO `teaplan` VALUES ('23', 'T10', '13032301', 'C13', 0);
INSERT INTO `teaplan` VALUES ('24', 'T11', '13032301', 'C14', 0);
INSERT INTO `teaplan` VALUES ('25', 'T01', '13032301', 'C15', 0);
INSERT INTO `teaplan` VALUES ('26', 'T02', '13032301', 'C16', 0);
INSERT INTO `teaplan` VALUES ('27', 'T03', '13032301', 'C17', 0);
INSERT INTO `teaplan` VALUES ('3', 'T03', '13012201', 'C03', 2);
INSERT INTO `teaplan` VALUES ('4', 'T04', '13012201', 'C04', 2);
INSERT INTO `teaplan` VALUES ('5', 'T05', '13012201', 'C05', 2);
INSERT INTO `teaplan` VALUES ('6', 'T01', '13012202', 'C01', 2);
INSERT INTO `teaplan` VALUES ('7', 'T02', '13012202', 'C02', 2);
INSERT INTO `teaplan` VALUES ('8', 'T03', '13012202', 'C03', 2);
INSERT INTO `teaplan` VALUES ('9', 'T04', '13012202', 'C04', 2);
SET FOREIGN_KEY_CHECKS = 1;
- 登入数据库并执行导入命令,导入前请先确保数据库已创建
bash
[root@mysql ~]# pwd
/root
[root@mysql ~]# mysql -u root -p
mysql> CREATE DATABASE edu_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
mysql> use edu_db;
mysql> SOURCE /root/edu_db.sql
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| edu_db | -- <== HERE
| mysql |
| performance_schema |
| sys |
| test_db |
+--------------------+
mysql> USE edu_db;
mysql> SHOW TABLES;
+------------------+
| Tables_in_edu_db |
+------------------+
| class |
| course |
| major |
| score |
| student |
| teacher |
| teaplan |
+------------------+
4.6 数据库导出
导出数据库一般在 Linux 命令行中使用 mysqldump 命令执行,语法如下:
bash
mysqldump -u 用户名 -p -h 数据库主机名 数据库名 > 数据库文件名.sql
# 示例:以 root 身份导出本地主机的 edu_db 数据库到 /root/edu_db.sql
[root@mysql ~]# mysqldump -u root -p edu_db > /root/edu_db.sql
Enter password:
[root@mysql ~]# ls /root/edu_db.sql
/root/edu_db.sql
5. 数据表基本操作
5.1 表操作
5.1.1 查看当前库中的数据表
使用命令 SHOW TABLES; 可以查看当前库中有哪些数据表,示例:
bash
mysql> SHOW TABLES;
+------------------+
| Tables_in_edu_db |
+------------------+
| class |
| course |
| major |
| score |
| student |
| teacher |
| teaplan |
+------------------+
7 rows in set (0.00 sec)
5.1.2 查看表结构
使用命令 DESC 表名; 或 DESCRIBE 表名; 可以查看数据表的结构,示例:
bash
# 查询数据表 class 的结构
mysql> DESC class;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| clno | char(20) | NO | PRI | NULL | |
| clname | varchar(30) | NO | | NULL | |
| mno | char(20) | YES | MUL | NULL | |
+--------+-------------+------+-----+---------+-------+
5.2 单表查询
数据库使用 SELECT 语句实现查询信息的功能
5.2.1 基本查询
查询语句的基本语法如下:
sql
-- 查询所有信息
SELECT * FROM 表名;
-- 指定具体字段查询
SELECT 字段名1, 字段名2, ... FROM 表名;
-- 查询并以别名输出
SELECT 字段名1 AS '别名1', 字段名2 AS '别名2', ... FROM 表名; -- AS 可省略
示例:
sql
-- 1. 查询专业信息表的所有信息
mysql> SELECT * FROM major;
+------+--------------------------+
| mno | mname |
+------+--------------------------+
| 1301 | 计算机科学与技术 |
| 1302 | 软件工程 |
| 1303 | 计算机网络 |
+------+--------------------------+
-- 2. 从班级表中查询班级号和班级名
mysql> SELECT clno, clname FROM class;
+----------+--------------------------------+
| clno | clname |
+----------+--------------------------------+
| 13012201 | 22计算机科学与技术1班 |
| 13012202 | 22计算机科学与技术2班 |
| 13022201 | 22软件工程1班 |
| 13022202 | 22软件工程2班 |
| 13022301 | 23软件工程1班 |
| 13032301 | 23计算机网络1班 |
+----------+--------------------------------+
-- 3. 从班级表中查询班级号和班级名,并使用中文别名输出
mysql> SELECT clno AS '班级号', clname AS '班级名' FROM class;
+-----------+--------------------------------+
| 班级号 | 班级名 |
+-----------+--------------------------------+
| 13012201 | 22计算机科学与技术1班 |
| 13012202 | 22计算机科学与技术2班 |
| 13022201 | 22软件工程1班 |
| 13022202 | 22软件工程2班 |
| 13022301 | 23软件工程1班 |
| 13032301 | 23计算机网络1班 |
+-----------+--------------------------------+
5.2.2 查询并格式化输出
在查询时,可以使用 CONCAT() 函数实现自定义输出的格式,这个函数的主要作用是拼接字符串,语法如下:
sql
SELECT CONCAT("字符串1", 字段名1, "字符串2", 字段名2, ...) FROM 表名;
示例:
sql
-- 查询并输出:学生 XXX,学号 XXX,性别 XXX
mysql> SELECT CONCAT("学生", sname, ",学号", sno, ",性别", ssex) AS "学生信息" FROM student;
+-------------------------------------------------+
| 学生信息 |
+-------------------------------------------------+
| 学生张伟,学号S1301220101,性别男 |
| 学生李婷婷,学号S1301220102,性别女 |
| 学生王子涵,学号S1301220103,性别男 |
| ... |
+-------------------------------------------------+
5.2.3 查询并预处理数据
在查询时可以直接对数据进行预处理,包括且不限于:算术运算、数值替换等操作
1. 算术运算
在查询语句中,可以添加算术运算符组成表达式,对数据进行处理
示例:
sql
-- 手动计算学生的总评成绩
-- 总评成绩 = peacetime * 0.4 + final * 0.6
mysql> SELECT sno AS "学号", cno AS "课程号", (peacetime * 0.4 + final * 0.6) AS "总评成绩" FROM score;
+-------------+-----------+--------------+
| 学号 | 课程号 | 总评成绩 |
+-------------+-----------+--------------+
| S1301220101 | C01 | 86.80 |
| S1301220101 | C02 | 81.20 |
| S1301220101 | C03 | 76.20 |
| S1301220102 | C01 | 91.20 |
| ... | ... | ... |
+-------------+-----------+--------------+
2. 空值替换
在查询语句中,可以通过添加IFNULL()函数对空值数据进行处理,语法如下:
sql
IFNULL(字段名, 替换值)
示例:
sql
-- 手动计算学生的总评成绩,空值使用 0 替换
mysql> SELECT sno AS "学号", cno AS "课程号", IFNULL((peacetime * 0.4 + final * 0.6), 0) AS "总评成绩" FROM score;
+-------------+-----------+--------------+
| 学号 | 课程号 | 总评成绩 |
+-------------+-----------+--------------+
| S1301220101 | C01 | 86.80 |
| S1301220101 | C02 | 81.20 |
| S1301220101 | C03 | 76.20 |
| ... | ... | ... |
| S1303230101 | C14 | 0.00 | -- 原文为 NULL
| S1303230101 | C15 | 0.00 | -- 原文为 NULL
| S1303230101 | C16 | 0.00 | -- 原文为 NULL
| ... | ... | ... |
+-------------+-----------+--------------+
3. 过滤重复值
在查询语句中添加 DISTINCT 关键字可以过滤掉重复的结果
示例:
sql
-- 查询成绩表有记录的学生学号
mysql> SELECT DISTINCT sno AS "学号" FROM score;
+-------------+
| 学号 |
+-------------+
| S1301220101 |
| S1301220102 |
| S1301220103 |
| S1301220104 |
| ... |
+-------------+
5.2.4 带条件查询
在查询数据时,可以使用 WHERE 子句设定查询条件,大致语法如下:
sql
SELECT 字段信息 FROM 表名 WHERE 条件;
条件信息的表示方法有很多种,一下是一些例子:
| 运算符类型 | 运算符 | 用途 / 含义 | 示例代码 | 说明 |
|---|---|---|---|---|
| 比较运算符 | = |
等于 | id = 5 |
不可用于 NULL 比较 |
> |
大于 | score > 60 |
||
< |
小于 | score < 60 |
||
>= |
大于等于 | score >= 60 |
||
<= |
小于等于 | score <= 60 |
||
!= 或 <> |
不等于 | id != 5 或 id <> 5 |
不可用于 NULL 比较 | |
| 空判断运算符 | IS NULL |
为空 | address IS NULL |
不可搭配比较运算符 |
IS NOT NULL |
不为空 | address IS NOT NULL |
不可搭配比较运算符 | |
| 逻辑运算符 | AND |
与运算 | job = 'salesman' AND sal > 5000 |
优先级高于 OR |
OR |
或运算 | job = 'manager' OR sal > 5000 |
||
NOT |
非运算 | NOT(sal > 5000) |
逻辑取反 | |
| 范围运算符 | BETWEEN AND |
在某个范围之间 | score BETWEEN 80 AND 100 |
|
IN |
在某个指定数据列表内 | id IN (10, 11, 12, 13) |
||
NOT IN |
不在某个指定数据列表内 | id NOT IN (10, 11, 12, 13) |
||
| 模糊查询运算符 | LIKE |
模糊查询 | name LIKE '张%' |
需要搭配通配符使用,如 % 匹配任意长度字符,_ 匹配单个字符 |
示例:
sql
-- 1. 查询 13012301 班级的学生信息
mysql> SELECT * FROM student WHERE clno = "13012201";
+-------------+-----------+------+------------+------------+----------+
| sno | sname | ssex | sbirthday | sphone | clno |
+-------------+-----------+------+------------+------------+----------+
| S1301220101 | 张伟 | 男 | 2003-02-10 | 1380000001 | 13012201 |
| S1301220102 | 李婷婷 | 女 | 2003-05-12 | 1380000002 | 13012201 |
| S1301220103 | 王子涵 | 男 | 2003-08-18 | 1380000003 | 13012201 |
| ... | ... | ... | ... | ... | ... |
+-------------+-----------+------+------------+------------+----------+
-- 2. 查询期末成绩小于 60 的学生学号和成绩
mysql> SELECT sno, final FROM score WHERE final < 60;
+-------------+-------+
| sno | final |
+-------------+-------+
| S1301220103 | 48.0 |
| S1301220106 | 59.0 |
| S1301220203 | 52.0 |
| S1302220102 | 54.0 |
| S1302230103 | 58.0 |
+-------------+-------+
-- 3. 查询总评成绩在 70-80 的学生学号和成绩
mysql> SELECT sno, total FROM score WHERE total BETWEEN 70 AND 80;
+-------------+-------+
| sno | total |
+-------------+-------+
| S1301220104 | 71.8 |
| S1301220104 | 73.8 |
| S1301220105 | 79.8 |
| ... | ... |
+-------------+-------+
-- 4. 查询 13012201 班级中王姓同学的学生信息
mysql> SELECT * FROM student WHERE sname LIKE "王%" AND clno = "13012201";
+-------------+-----------+------+------------+------------+----------+
| sno | sname | ssex | sbirthday | sphone | clno |
+-------------+-----------+------+------------+------------+----------+
| S1301220103 | 王子涵 | 男 | 2003-08-18 | 1380000003 | 13012201 |
| S1301220109 | 王静文 | 女 | 2003-04-20 | 1380000009 | 13012201 |
+-------------+-----------+------+------------+------------+----------+
-- 5. 查询考取了 C04, C07, C09 三门课的学生的总评成绩
mysql> SELECT sno, cno, final FROM score WHERE cno IN ("C04", "C07", "C09");
+-------------+-----+-------+
| sno | cno | final |
+-------------+-----+-------+
| S1302220101 | C07 | 93.0 |
| S1302220101 | C09 | 82.0 |
| S1302220102 | C07 | 54.0 |
| ... | ... | ... |
+-------------+-----+-------+
5.2.5 查询并排序
在数据库中,可以在查询语句末尾使用 ORDER BY 关键字设定排序方式,参数 ASC 和 DESC 分别表示升序和降序,默认为升序,语法如下:
sql
SELECT ...
FROM ...
WHERE ...
ORDER BY 字段名1 ASC|DESC, 字段名2 ASC|DESC, ...
示例:
sql
-- 将成绩表按总评成绩由高到低排序,若总评成绩相同,则按学号从低到高排序
mysql> SELECT *
-> FROM score
-> ORDER BY total DESC, sno ASC;
+-------------+-----+-----------+-------+-------+
| sno | cno | peacetime | final | total |
+-------------+-----+-----------+-------+-------+
| S1301220204 | C01 | 95.0 | 97.0 | 96.2 |
| S1302230101 | C07 | 93.0 | 96.0 | 94.8 |
| S1301220101 | C01 | 92.0 | 95.0 | 93.8 |
| S1302220101 | C07 | 90.0 | 93.0 | 91.8 |
| ... | ... | ... | ... | ... |
+-------------+-----+-----------+-------+-------+
5.3 多表查询
顾名思义,多表查询指在多个表中检索并合并查询结果
查询时,可以给表名设置别名以减少 SQL 语句的编辑复杂度
多表查询时,字段名需要通过 表名.字段名 进行精确定位
语法与示例如下:
sql
SELECT 表名1.字段名1 表名2.字段名2, ...
FROM 表名1 别名1, 表名2 别名2, ...
...;
-- 示例
SELECT s.sname, c.cname
FROM Student s, Course c
...;
5.3.1 笛卡尔积多表查询
笛卡尔乘积(Cartesian product)又称直积,是数学中两个集合 X 和 Y 的所有可能有序对组成的集合,表达式为 X×Y ,其中每个有序对的第一个元素来自 X,第二个元素来自 Y
语法:
sql
SELECT ...
FROM 表名1, 表名2, ...
WHERE ...;
示例:
sql
mysql> SELECT s.sname, c.cname
-> FROM student s, course c
-> WHERE c.mno = '1301';
+-----------+-----------------------------+
| sname | cname |
+-----------+-----------------------------+
| 张伟 | 离散数学 |
| 张伟 | 计算机基础 |
| 张伟 | 操作系统原理 |
| 张伟 | C 语言程序设计 |
| 张伟 | Windows Server 操作系统 |
| 张伟 | CAD 制图 |
| 李婷婷 | 离散数学 |
| 李婷婷 | 计算机基础 |
| 李婷婷 | 操作系统原理 |
| 李婷婷 | C 语言程序设计 |
| 李婷婷 | Windows Server 操作系统 |
| 李婷婷 | CAD 制图 |
| ... | ... |
+-----------+-----------------------------+
5.3.2 多表连接多表查询
一般情况下直接查询多个表的所有数据,会生成大量无用的冗余数据,而为了获取有效的信息,在多表查询时一般会指定字段信息 和查询条件
语法如下:
sql
SELECT 表名.字段名1, 表名.字段名2, ...
FROM 表名1, 表名2, ...
WHERE 表名1.字段名1 = 表名2.字段名2
...;
示例:
sql
-- 1. 生成总评成绩表,包含学生名字和课程名
-- - 指定要查询的字段名
SELECT sc.sno AS "学号", st.sname AS "姓名", sc.cno AS "课程号", c.cname AS "课程名", sc.total AS "总评成绩"
-- - 指定要查询的表
FROM student st, score sc, course c
-- - 指定连接条件
WHERE sc.sno = st.sno AND sc.cno = c.cno;
+-------------+-----------+-----------+--------------------+--------------+
| 学号 | 姓名 | 课程号 | 课程名 | 总评成绩 |
+-------------+-----------+-----------+--------------------+--------------+
| S1301220101 | 张伟 | C01 | 离散数学 | 93.8 |
| S1301220101 | 张伟 | C02 | 计算机基础 | 80.8 |
| S1301220101 | 张伟 | C03 | 操作系统原理 | 89.8 |
| S1301220102 | 李婷婷 | C01 | 离散数学 | 83.2 |
| S1301220102 | 李婷婷 | C02 | 计算机基础 | 85.8 |
| ... | ... | ... | ... | ... |
+-------------+-----------+-----------+--------------------+--------------+
-- 2. 查询学生学号、学生姓名、所属班级名、所学课程名、总评成绩、任课教师姓名,并按总评成绩降序排序
mysql> SELECT sc.sno AS "学生学号",
-> st.sname AS "学生姓名",
-> cl.clname AS "班级",
-> c.cname AS "课程",
-> t.tname AS "任课教师",
-> sc.total AS "总评成绩"
-> FROM score sc, student st, class cl, course c, teacher t, teaplan tp
-> WHERE sc.sno = st.sno AND
-> sc.cno = c.cno AND
-> st.clno = cl.clno AND
-> tp.tno = t.tno AND
-> tp.cno = c.cno AND
-> tp.clno = cl.clno;
+--------------+--------------+--------------------------------+--------------------+--------------+--------------+
| 学生学号 | 学生姓名 | 班级 | 课程 | 任课教师 | 总评成绩 |
+--------------+--------------+--------------------------------+--------------------+--------------+--------------+
| S1301220101 | 张伟 | 22计算机科学与技术1班 | 离散数学 | 张伟 | 93.8 |
| S1301220101 | 张伟 | 22计算机科学与技术1班 | 计算机基础 | 李红梅 | 80.8 |
| S1301220101 | 张伟 | 22计算机科学与技术1班 | 操作系统原理 | 王强 | 89.8 |
| S1301220102 | 李婷婷 | 22计算机科学与技术1班 | 离散数学 | 张伟 | 83.2 |
| S1301220102 | 李婷婷 | 22计算机科学与技术1班 | 计算机基础 | 李红梅 | 85.8 |
| S1301220102 | 李婷婷 | 22计算机科学与技术1班 | 操作系统原理 | 王强 | 81.0 |
| ... | ... | ... | ... | ... | ... |
+--------------+--------------+--------------------------------+--------------------+--------------+--------------+
5.4 高级查询
5.4.1 多表连接
按照 SQL99 标准,多表连接的方式分为内连接 和外连接两种
1 内连接
内连接通过在 FROM 子句中添加 INNER JOIN ... ON 关键字连接多个表,语法如下:
sql
SELECT ...
FROM 表名1
INNER JOIN 表名2 ON 连接条件1
INNER JOIN 表名3 ON 连接条件2
...
-- INNER 可省略
示例:
sql
-- 查询学号 S1301220101 学生的姓名和所考试科目的总评成绩
mysql> SELECT st.sname AS "姓名", c.cname AS "科目", sc.total AS "总评成绩"
-> FROM score sc
-> INNER JOIN student st ON sc.sno = st.sno
-> INNER JOIN course c ON sc.cno = c.cno
-> WHERE sc.sno = "S1301220101";
+--------+--------------------+--------------+
| 姓名 | 科目 | 总评成绩 |
+--------+--------------------+--------------+
| 张伟 | 离散数学 | 93.8 |
| 张伟 | 计算机基础 | 80.8 |
| 张伟 | 操作系统原理 | 89.8 |
+--------+--------------------+--------------+
2 外连接
外连接又分为左连接 和右连接,这种连接方式指定了连接方式,保留左表所有记录使用左连接,反之使用右连接
外连接通过在 FROM 子句中添加 LEFT|RIGHT OUTER JOIN ... ON 关键字实现,语法如下:
sql
FROM 表名1
LEFT|RIGHT OUTER JOIN 表名2 ON 连接条件1
LEFT|RIGHT OUTER JOIN 表名3 ON 连接条件2
-- OUTER 可省略
示例:
sql
-- 1. 查询总评成绩 > 90 的学生的姓名、班级和科目信息,使用左连接,并按照降序排序
mysql> SELECT st.sname AS "姓名", cl.clname AS "班级", c.cname AS "科目", sc.total AS "总评成绩"
-> FROM score sc
-> LEFT OUTER JOIN student st ON sc.sno = st.sno
-> LEFT OUTER JOIN class cl ON st.clno = cl.clno
-> LEFT OUTER JOIN course c ON sc.cno = c.cno
-> AND sc.final > 90
-> ORDER BY sc.final DESC;
+-----------+--------------------------------+--------------------+--------------+
| 姓名 | 班级 | 科目 | 总评成绩 |
+-----------+--------------------------------+--------------------+--------------+
| 赵思雨 | 22计算机科学与技术2班 | 离散数学 | 96.2 |
| 周天宇 | 23软件工程1班 | C++ 程序设计 | 94.8 |
| 张伟 | 22计算机科学与技术1班 | 离散数学 | 93.8 |
| 李娜 | 22计算机科学与技术2班 | 离散数学 | 91.6 |
| 赵伟 | 22计算机科学与技术1班 | 离散数学 | 91.4 |
| 蒋东宇 | 22软件工程1班 | C++ 程序设计 | 91.8 |
| 周天宇 | 23软件工程1班 | Java 语言基础 | 90.8 |
| 张伟 | 22计算机科学与技术1班 | 操作系统原理 | 89.8 |
+-----------+--------------------------------+--------------------+--------------+
-- 2. 查询学号 S1301220103 学生目前所需要学习的课程名与任课老师名,使用右连接
mysql> SELECT st.sname AS "姓名", c.cname AS "课程", t.tname AS "任课老师"
-> FROM teaplan tp
-> RIGHT OUTER JOIN class cl ON tp.clno = cl.clno
-> RIGHT OUTER JOIN student st ON cl.clno = st.clno
-> RIGHT OUTER JOIN teacher t ON tp.tno = t.tno
-> RIGHT OUTER JOIN course c ON tp.cno = c.cno
-> WHERE st.sno = "S1301220103";
+-----------+-----------------------------+--------------+
| 姓名 | 课程 | 任课老师 |
+-----------+-----------------------------+--------------+
| 王子涵 | 离散数学 | 张伟 |
| 王子涵 | 计算机基础 | 李红梅 |
| 王子涵 | 操作系统原理 | 王强 |
| 王子涵 | C 语言程序设计 | 刘小洋 |
| 王子涵 | Windows Server 操作系统 | 王娅 |
+-----------+-----------------------------+--------------+
5.4.2 聚合函数
SQL 语句可以在子句中添加聚合函数对查询的数据进行处理,常用的聚合函数有:
| 函数名 | 用途 |
|---|---|
SUM() |
求和 |
AVG() |
求平均数 |
COUNT() |
记录总数量 |
MAX() |
记录最大值 |
MIN() |
记录最小值 |
示例:
sql
-- 1. 计算学号 S1301220101 学生的总评平均分
mysql> SELECT AVG(total) FROM score WHERE sno="S1301220101";
+------------+
| AVG(total) |
+------------+
| 88.13333 |
+------------+
-- 2. 从 student 表计算 13012202 班级有多少学生
mysql> SELECT COUNT(sno) FROM student WHERE clno="13012202";
+------------+
| COUNT(sno) |
+------------+
| 10 |
+------------+
-- 3. 查询 C03 课程期末考试最高分
mysql> SELECT MAX(final) FROM score WHERE cno="C03";
+------------+
| MAX(final) |
+------------+
| 91.0 |
+------------+
5.4.3 分组统计
SQL 语句可以通过 GROUP BY 和 HAVING 关键字将查询信息组合,语法如下:
sql
GROUP BY 字段
HAVING 组合条件
示例:
sql
-- 查询总评平均分数 > 80 的班级号和班级名
mysql> SELECT cl.clno, cl.clname, AVG(sc.total)
-> FROM score sc
-> JOIN student st ON sc.sno = st.sno
-> JOIN class cl ON st.clno = cl.clno
-> GROUP BY cl.clno
-> HAVING AVG(sc.total) > 80;
+----------+--------------------+---------------+
| clno | clname | AVG(sc.total) |
+----------+--------------------+---------------+
| 13022301 | 23软件工程1班 | 80.15000 |
+----------+--------------------+---------------+
5.4.4 子查询
在一个查询语句中嵌套一个查询,称为子查询
子查询语句可以出现在任意位置,但必须被 () 包裹
示例:
sql
-- 1. 查询选修了 C01 课程的学生姓名
mysql> SELECT sname
-> FROM student
-> WHERE sno IN (
-> SELECT sno FROM score WHERE cno = 'C01'
-> );
+-----------+
| sname |
+-----------+
| 张伟 |
| 李婷婷 |
| 王子涵 |
| 赵伟 |
| 孙丽丽 |
| 周六 |
| 陈涛 |
| 李娜 |
| 王刚 |
| 赵思雨 |
+-----------+
-- 2. 查询期末成绩大于全校平均水平的学生及分数,按照降序排序
mysql> SELECT st.sname AS "姓名", AVG(sc.total) AS "平均成绩"
-> FROM score sc
-> JOIN student st ON sc.sno = st.sno
-> GROUP BY sc.sno
-> HAVING AVG(sc.total) > (
-> SELECT AVG(total) FROM score
-> )
-> ORDER BY AVG(sc.total) DESC;
+-----------+--------------+
| 姓名 | 平均成绩 |
+-----------+--------------+
| 赵思雨 | 90.46667 |
| 周天宇 | 90.13333 |
| 李娜 | 88.60000 |
| 张伟 | 88.13333 |
| 蒋东宇 | 84.30000 |
| 李婷婷 | 83.33333 |
| 赵伟 | 79.00000 |
| 杨圆圆 | 78.93333 |
+-----------+--------------+