一、基础概念
1. 什么是数据库?数据库的功能是什么?
- 存储数据的仓库 DB (DataBase)
- 数据库管理系统 DBMS
- 对数据进行增、删、改、查
- 数据 (data) : 对客观事务的记录,数字、文字、图形、符号、声音、视频…
- 信息 (info) : 进过加工后的数据
\2. 数据库的分类?
- 模型:
- 关系模型
- 非关系模型
- 部署:
- 本地
- 云
- 用途:
- OLTP: 在线事务处理
- OLAP: 在线分析处理
- HTAP:混合
- 架构:
-
- 集中式
- 分布式
- 云原生
- 介质:
-
- 磁盘
- 内存
\3. 关系型数据库和非关系型数据库的区别?
- 结构化数据:例如:表格由行和列构成,每一列都要固定的格式和类型。
- 半结构数据:例如:html、xml、json、yaml
- 非结构化数据:聊天记录、评论… •
- 关系型数据库RDBMS:结构化存储、SQL语句 ◦ Oracle、MySQL、Microsoft SQL Server、PostgreSQL、Snowflake、IBM Db2、SQLite
- 非关系型数据库NoSQL:非结构化存储、半结构化存储 ◦
-
- MongoDB:文档数据库、适合存储JSON数据。 ◦
- Redis:内存型数据库,适合做缓存 ◦
- Elasticsearch:适合全文搜索
\4. 了解数据库 top10?国产信创数据库有哪些?
1.Oracle 甲骨文公司,收费的大型数据库,银行、金融、民航、电力…
2.MySQL 是一个C/S关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品,目前依旧开源免费。MariaDB是MySQL的开源分支,是由原作者重新开源的产品。在互联网公司使用极为普遍。
3.Microsoft SQL Server 在Windows Server使用的数据库,常用于财务管理系统、餐饮管理系统等。
4.PostgreSQL 世界上最** 先进 **的开源关系数据库。诞生在加州大学伯克利分校。
5.MongoDB 文档 数据库、适合存储JSON数据。
6.Snowflake 数据库是一款基于云的高性能数据仓库,具有独特的架构和强大的功能。
7.Redis 开源的基于内存型、key-value结构的数据库,用于数据缓存,实现高并发。
8.IBM Db2 和IBM服务器绑定使用。
9.Elasticsearch 搜索引擎,适合全文搜索、 日志 分析等功能。
10.SQLiet 微型关系数据库,以文件的方式存储数据,支持SQL,嵌入式设备、手机、App后台数据存储。
国产信创数据库
* 达梦数据库
* 金仓数据库
* OceanBase
* openGauss
5.SQL 是什么?
SQL:(Structured Query Language) 结构化查询语言,用于操作关系型数据的语言。
二:二进制安装MySQL
企业一般使用 MySQL 二进制包安装 MySQL8.0
另外还有 yum/apt、源码、Shell 一键安装、容器化安装 (Docker 一键安装) 安装方式
- 1.安装依赖环境
yum install -y libaio libaio-devel ncurses ncurses-devel openssl openssl-devel
- 2.下载二进制包
# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
wget http://192.168.56.200/Software/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
- 3.设置安装路径与权限
# 解压
tar -xvf mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
# 将mysql文件夹,剪切并改名mv mysql-8.0.20-linux-glibc2.12-x86_64 /usr/local/mysql#创建 mysql 用户useradd mysql -M -s /sbin/nologin#创建数据库数据目录mkdir /usr/local/mysql/data#更改 mysql 目录权限chown mysql:mysql -R /usr/local/mysql
- 4.修改配置与初始化
1 # 修改 MySQL 配置文件
2 cat <<EOF> /etc/my.cnf
3 [mysqld]
4 port = 3306
5 basedir = /usr/local/mysql
6 datadir = /usr/local/mysql/data
7 log-error = /usr/local/mysql/data/error.log
8 pid-file = /usr/local/mysql/data/mysql.pid
9 socket = /tmp/mysql.sock
10 character-set-server=utf8mb4
11 collation-server=utf8mb4_unicode_ci
12 default-storage-engine=InnoDB
13 default-authentication-plugin=mysql_native_password
14 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
15 EOF17 # 执行初始化
18 /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
19
20 cat /usr/local/mysql/data/error.log
21 2025-08-01T01:59:17.918526Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
22 2025-08-01T01:59:17.918080Z 0 [System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.20) initializing of server in progress as process 1361
23 2025-08-01T01:59:17.955395Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
24 2025-08-01T01:59:18.606916Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
25 2025-08-01T01:59:19.405704Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 5wp7=Y3<TZp;
26
27 #初始化成功后,启动MySQL
28 /usr/local/mysql/support-files/mysql.server start
29 Starting MySQL.. SUCCESS!
30
31 netstat -lnutp|grep 3306
32 tcp6 0 0 :::33060 :::* LISTEN 1672/mysqld
33 tcp6 0 0 :::3306 :::* LISTEN 1672/mysqld
- 5.设置环境变量(为了让系统可以识别二进制)
# 修改系统环境变量
# 想要在任意目录执行 mysql 的命令需要修改 /etc/profile# PATH: 可执行命令的目录路径vim /etc/profile# 最后一行添加
export PATH=$PATH:/usr/local/mysql/bin
# 重新加载source /etc/profile
- 6.修改密码
# 使用你的初始密码登录 MySQLmysql -uroot -p'5wp7=Y3<TZp;'# 修改密码alter user 'root'@'localhost' identified by 'root123';
- 7.设置开机启动
# 将启动脚本复制到 /etc/init.d/ 目录,这是启动脚本的默认目录。cp -a /usr/local/mysql/support-files/mysql.server/etc/init.d/mysqld# 配置 mysqld 开机启动后,可以使用 systemctl 管理 mysqldsystemctl enable mysqldsystemctl restart mysqldsystemctl status mysqld
- 8.设置远程登录
# 服务端本地登录MySQL
mysql -uroot -proot123# 创建远程登录账号
mysql> create user 'root'@'%' identified with mysql_native_password by 'root123';
Query OK, 0 rows affected (0.01 sec)# 设置开放权限
mysql> grant all on *.* to 'root'@'%';
Query OK, 0 rows affected (0.00 sec)# 刷新使权限生效
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)# 客户端-命令行
# mysql:官方的客户端
yum install mariadb
apt install mysql-client
mysql -uroot -proot123 -h192.168.8.20# mycli:Python实现的mysql客户端,拥有关键字提示功能。
apt install mycli
mycli -uroot -proot123 -h"192.168.8.20"# CentOS7上安装mycli
yum install python3-pip
pip3 install mycli==1.10
pip3 install pymysql==0.8
# 客户端-图形化
phpmyadmin
Navicat
SQLyou
Workbench
三、SQL基础语法
- SQL的分类:DML、DDL、DQL、DCL
- SQL的关键字
- 创建库、创建表
- SQL 的分类:
- DDL:(数据定义语言)(Data Definition Language)对库和表进行操作
- create 创建库、表、索引、视图、用户
- alter 修改库字符集、表结构、索引、视图、用户、密码
- drop 删除各种结构、库、表、视图、索引、用户
-
DML:(数据操纵语言)(Data Manipulation Language)对表中的数据进行添加、修改、删除
- insert 在表中插入、添加数据
- update 修改表中的内容
- delete 删除表中的内容
-
DQL:数据查询语言
-
DCL:(数据控制语言)(Data Control Language)对数据库进行权限管理、用户管理、事务管理
- use 切换数据库
- grant 权限设置
- revoke 移除权限
-
DTL:(事务控制语言)(Data Transaction Language)
- commit 事务提交
- rollback 回滚
-
SQL 的关键字
-
库操作
- 查看所有库:show databases;
- 创建库:create database 库名charset utf8mb4;
- 删除库:drop database 库名; -- 当删除库时,库中所有的内容都会被删除
- 修改库的字符集:alter database test charset utf8mb4;
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT ENCRYPTION='N' 关键字 / 语法片段 作用说明 CREATE DATABASE SQL 语句的核心指令,用于创建数据库,明确操作类型是 “新建数据库” test 数据库的名称,实际使用时需替换为你想要创建的数据库名(自定义标识符,需符合命名规范) DEFAULT CHARACTER SET 设置数据库的默认字符集,utf8mb4 是常用的通用字符集,支持几乎所有 Unicode 字符(含 emoji 等) utf8mb4 具体的字符集类型,utf8mb4 比传统 utf8 更完善,支持完整 Unicode 范围 COLLATE 用于指定排序规则,决定字符比较、排序的逻辑 utf8mb4_unicode_ci 基于 utf8mb4 字符集的排序规则,_ci 表示不区分大小写(Case Insensitive )排序 DEFAULT ENCRYPTION='N' 设置数据库是否默认加密,'N' 表示不加密(若需加密可改为 'Y' ,依赖数据库版本 / 支持) 简单来说,这条语句的作用是:创建一个名为 test 的数据库,指定用 utf8mb4 字符集存储数据,用 utf8mb4_unicode_ci 规则排序,且默认不加密 。-
表操作:
-
mysql -u root -p 进入mysql
-
use test 进入test
-
desc user; 打开名为user的表格
-
查看表:
-
- 查看库中所有的表:show tables;
- 查看表的结构
-
创建表
31 32 * Field 字段 (列名) : 字母、数字、下划线、不要和 mysql 关键字冲突,不要有特殊符号和空格。 33 * Type 数据类型:数字类型、字符类型、日期时间类型、二进制数据、json 等... 34 * Null 是否可为空: YSE 可为空,NO 不能为空,Not Null 35 * Key 键:主键、外键、唯一 36 * Default 默认值:在 insert 时,没有设置内容时,自动添加的内容 37 * Extra: 扩展,例如: auto_increment (自动增长,一般用于序号自动 + 1)- 修改表结构 alter
alter table(修改表) user_info(被修改的表名) add(新增) age(新家内容名称) tinyint(数据类型) UNSIGNED;(表示无符号整数0-255) # 简单说:这条 SQL 是给 user_info 表新增一个无符号 tinyint 类型的字段 age ,用于存储年龄等小范围整数值。- 删除表: drop table 表名;
-
数据类型
- 作用:对数据进行分类,对相同类型的数据给予相同大小的存储空间。
整数、浮点数、字符串、时间日期
\1. 整数类型
-
- 整数型
类型 字节 范围(有符号) 范围(无符号) TINYINT(m) 1 (-128,127) (0,255) SMALLINT(m) 2 (-32768,32767) (0,65535) MEDIUMINT(m) 3 (-8388608,8388607) (0,16777215) INT(m) 4 (-2147483 648,2147483647) (0,4294967295) BIGINT(m) 8 (-9223372036854775808,9223372036854775807) (0,18446744073709551615)
2.浮点数和定点数
- float 4字节 (小数位过多时不精确,会自动四舍五入)
- double 8字节 相对floaat精确一些
- decimal(M总长度,D小数长度)M>D decimal(6.2)相当于1000.00(总共6位,两位小数)
- decimal是以字符串方式存储的数字。
3.日期时间
-
类型 字节 范围 格式 用途 DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值 TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间 YEAR 1 1901/2155 YYYY 年份值 DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值 TIMESTAMP 4 1970-01-01 00:00:00/2038 结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYYMMDD HHMMSS 混合日期和时间值,时间戳
4.字符类型
- char(n) 0~255字节 定长字符串,适合手机号,身份证号,有可能浪费空间,但查询效率高
- varchar(n),0~65535字符,变长字符串,姓名,密码,地址,简介,标题,短文
- blob 0~65535字节 二进制字符
- text 0~65535字节 普通文本,评论,简介,短文
- longtext 0 - 4294967295字节 超长的文本,例如:一本书、
常用词汇★★★
table 表 drop删除 like复制 on索引 show查看表库 desc查看表结构
add 添加 modify 替换 distinct 去重 order by 升序降序 limit提取数据
tadabase数据库 group 分组 truncate 清空表内数据
use school;#切换库SELECT * FROM student; #查看表中所有信息SHOW DATABASES; #查看所有库SHOW TABLES; #查看库里的所有表DESC student; # 查看表结构SELECT * FROM students WHERE name LIKE '%张%';
# 模糊查询,查询所有带张的DROP DATABASE IF EXISTS test; # 删数据库
DROP TABLE IF EXISTS student;
# 删除表 student
ALTER TABLE student DROP COLUMN name;
#删除 student 表的 name 字段DELETE FROM student WHERE age < 18;得儿雷特 from student where #删除 student 表中年龄小于 18 的行DROP INDEX idx_name ON student;
#删除 `student` 表上名为 `idx_name` 的索引
DROP VIEW IF EXISTS v_student;# 删除 v_student 视图DROP PROCEDURE IF EXISTS proc_student;# 删除存储过程 proc_studentINSERT INTO student(id,name,gender,password,phone) VALUE(1,'武大郎','男','123''321'); #添加内容,多加的话后面加括号,(),()
ALTER TABLE student ADD birthday DATE; # 给student添加birthday字段ALTER TABLE student MODIFY age TINYINT; #修改`student`表的`age`字段为`TINYINT`
CREATE TABLE student_backup LIKE student;#复制`student`表结构到`student_backup#查询索引方法
SHOW INDEX FROM zhang;
1. 主键约束(PRIMARY KEY)
- 作用:唯一标识表中的每条记录,确保记录不重复且非空。
- 特点:一个表只能有一个主键,主键字段的值不能为 NULL,也不能重复。
- 示例:
CREATE TABLE students (id INT PRIMARY KEY, -- id作为主键name VARCHAR(50)
);
2. 非空约束(NOT NULL)
- 作用:强制列不能存储 NULL 值,确保该字段必须有值。
- 示例:
CREATE TABLE users (id INT PRIMARY KEY,username VARCHAR(50) NOT NULL -- 用户名不能为空
);
3. 唯一约束(UNIQUE)
- 作用:确保列中所有值都是唯一的(不重复),但允许 NULL(最多一个 NULL )。
- 示例:
CREATE TABLE emails (id INT PRIMARY KEY,email VARCHAR(100) UNIQUE -- 邮箱地址不能重复
);
4. 默认约束(DEFAULT)
- 作用:当插入数据时未指定该列的值,自动使用默认值填充。
- 示例:
CREATE TABLE products (id INT PRIMARY KEY,status VARCHAR(20) DEFAULT 'active' -- 默认为"active"状态
);
5. 检查约束(CHECK)
- 作用:限制列中值的范围或条件(MySQL 8.0.16 及以上支持)。
- 示例:
CREATE TABLE employees (id INT PRIMARY KEY,salary DECIMAL(10,2) CHECK (salary > 0) -- 工资必须大于0
);
6. 自增约束(AUTO_INCREMENT)
- 作用:自动为新记录生成唯一的递增数值,通常与主键配合使用。
- 示例:
CREATE TABLE articles (id INT PRIMARY KEY AUTO_INCREMENT, -- 自动生成1,2,3...title VARCHAR(100)
);
外键(FOREIGN KEY)
外键是用于关联两个表的约束,确保表之间的数据关联性和一致性。
- 主表:被从表(包含外键的表)通过主键关联。
-
核心作用:强制从表(含外键的表)的某个字段值必须对应主表(被引用的表)中已存在的主键值。
-
示例场景:
主表students(学生信息)和从表scores(成绩信息)通过外键关联,确保成绩表中的学生必须是学生表中已存在的。-- 主表:学生表 CREATE TABLE students (id INT PRIMARY KEY,name VARCHAR(50) );-- 从表:成绩表(含外键) CREATE TABLE scores (score_id INT PRIMARY KEY,student_id INT, -- 关联学生表的idscore INT,-- 定义外键:student_id必须对应students表的idFOREIGN KEY (student_id) REFERENCES students(id)ON DELETE CASCADE -- 主表删除学生时,从表关联成绩也删除 ); -
外键规则:
当主表数据被修改时,可通过ON DELETE或ON UPDATE定义从表的行为(如CASCADE级联删除、SET NULL设为NULL等)。
三、数据完整性(Data Integrity)
完整性指数据库中的数据符合预定规则,不存在无效或错误信息,主要分为四类:
-
实体完整性
确保表中每条记录都是唯一且可识别的,通过主键和唯一约束实现(如学生表中“学号”唯一)。 -
域完整性
确保列中数据符合特定格式或范围,通过数据类型、非空约束、检查约束等实现(如“年龄”必须是正整数)。 -
参照完整性
确保多表之间的关联关系合法,通过外键实现(如成绩表的学生必须在学生表中存在)。 -
用户定义完整性
根据业务需求自定义的规则(如“订单金额必须大于0”),可通过CHECK约束或触发器实现。
四、唯一性(Uniqueness)
唯一性是指表中某个字段的值不允许重复,主要通过两种方式实现:
-
主键(PRIMARY KEY)
- 不仅要求唯一,还不允许
NULL,一个表只能有一个主键。 - 示例:
id INT PRIMARY KEY
- 不仅要求唯一,还不允许
-
唯一约束(UNIQUE)
- 仅要求值唯一,允许
NULL(但最多一个NULL),一个表可以有多个唯一约束。 - 示例:
email VARCHAR(100) UNIQUE
- 仅要求值唯一,允许
- 区别:主键是“唯一标识记录”,唯一约束是“确保字段值不重复”,主键本质上是一种特殊的唯一约束(加非空限制)。
总结
- 约束条件是保障数据规则的“工具集”(主键、外键、非空等);
- 外键是约束的一种,专门用于维护表之间的关联关系;
- 完整性是数据符合规则的“状态”(实体、域、参照等维度);
- 唯一性是数据的“属性”,确保字段值不重复(通过主键或唯一约束实现)。
合理使用这些机制,能有效保证数据库数据的准确性、一致性和可靠性。
四、SQL 复杂查询
五、MySQL 权限管理
六、MySQL 备份
七、MySQL 进阶
八、MySQL 主从集群
# 查看插入后的名单(名单名为user)
SELECT * FROM user;# 这条语句的完整含义是:向 user 表中插入一行数据,其中 id 为 1、name 为 “武大郎”、gender 为 “男”、password 为 “123321”、phone 为空值。
INSERT INTO user(id,name,gender,password,phone)
VALUE(1,'武大郎','男','123321',NULL);## 查看数据 DQL(数据查询语言)
select * from user; -- 查看所有数据
select name,gender from user;
#注意:user为我自己的表格名,name和gender为表格的选项,名字和性别。其他不改结尾要有;两个字段中间要有逗号
执行前要先选择数据库,我的为USE test; (
#use为固定,test为我的数据库名#修改语句,修改语句必须要加where条件,否则会更新所有行的数据。
update user set phone='1999' where id=1;
修改 user表中 id 为 1 的那一行数据,将其 phone字段的值更新为 '1999'。
## 删除数据必须要加where条件,否则会删除所有行的数据。
delete from user where id=6;
从 user 表中删除 id 为 6 的那一行数据。
#检查是否开启安全模式
show variables like 'sql_safe_updates';#开启安全模式
set sql_safe_updates = 1;
#关闭安全模式
set sql_safe_updates = 0;# 自动启动安全模式
vim /etc/my.cnf
# 在[mysqld]下配置一个
init-file=/usr/local/mysql/init-file.sqlvim /usr/local/mysql/init-file.sql
# 在sql脚本文件中添加下列语句
set global sql_safe_updates=1;# 重启MySQL服务
systemctl restart mysqld# 开启安全模式后的限制有哪些
1. update语句必须满足如下条件之一才能执行成功
1)使用where子句,并且where子句中列必须为索引列
2)使用limit
3)同时使用where子句和limit(此时where子句中列可以不是索引列)2. delete语句必须满足如下条件之一才能执行成功
1)使用where子句,并且where子句中列必须为索引列
2)同时使用where子句和limit(此时where子句中列可以不是索引列)#例子
LIMIT作用
-- 只返回前 5 条数据
SELECT * FROM user LIMIT 5;-- 从第 3 条开始(偏移 2),返回 5 条(常用于分页)
SELECT * FROM user LIMIT 2, 5; 偏移2,一共返回五条UPDATE user SET id=2 WHERE name='潘金莲'LIMIT 1;
# 把潘金莲那行的id改成2,最多只更新一行其他不变,更新最先检测到的
了解:聚合函数,分组查询,升序、降序,分页查询,子查询
下面为你详细介绍 SQL 中聚合函数、分组查询、排序(升序、降序)、分页查询和子查询的相关知识:
1. 聚合函数
聚合函数用于对一组数据进行计算并返回单个结果值,常用于统计分析。
常见的聚合函数:
-
count`:计算记录的数量
-- 计算表中所有记录数 SELECT COUNT(*) FROM students; -- 计算指定列非NULL值的数量 SELECT COUNT(age) FROM students; -
SUM():计算数值列的总和萨姆
-- 计算所有学生的总分 SELECT SUM(score) FROM exam_results; -
AVG():计算数值列的平均值安格
-- 计算学生的平均年龄 SELECT AVG(age) FROM students; -
MAX():获取指定列的最大值-- 获取最高分数 SELECT MAX(score) FROM exam_results; -
MIN():获取指定列的最小值-- 获取最低分数 SELECT MIN(score) FROM exam_results;
2. 分组查询
分组查询使用GROUP BY子句,将表中的数据按照指定列的值进行分组,然后对每个分组应用聚合函数。
基本语法:
SELECT 列1, 聚合函数(列2)
FROM 表名
GROUP BY 列1;
示例:
-- 按班级分组,计算每个班级的学生人数和平均年龄
SELECT class, COUNT(*), AVG(age)
FROM students
GROUP BY class;-- 结合HAVING筛选分组结果(HAVING用于筛选分组,WHERE用于筛选行)
-- 筛选出学生人数大于30的班级
SELECT class,
COUNT(*) AS student_count
FROM students
GROUP BY class
HAVING COUNT(*) > 30;-- 筛选出学生人数大于30的班级
SELECT class_name AS 班级,#起名班级COUNT(*) AS 学生人数 #起名学生人数
FROM class_students #总表名
GROUP BY class_name #人数列名
HAVING COUNT(*) > 30;SELECT
含义:"选择",用于指定要查询并返回的列或计算结果。
class_name
含义:表中的 "班级名称" 字段,代表要查询的具体列。
AS 班级
AS:"作为",用于给查询结果的列起别名
班级:为class_name字段起的别名,使结果更易读
COUNT(*)
COUNT:聚合函数,"计数"
(*):表示统计所有行(记录)的数量,不忽略 NULL 值
AS 学生人数
为COUNT(*)的计算结果起别名 "学生人数"
FROM class_students
FROM:"从... 中",指定查询的数据来源表
class_students:具体的表名,即要查询的表
GROUP BY class_name
GROUP BY:"按... 分组",用于将数据按指定列的值分组
class_name:按 "班级名称" 进行分组,相同班级的记录会被归为一组
HAVING COUNT(*) > 30
HAVING:"具有",用于筛选分组后的结果(与WHERE不同,WHERE筛选原始数据)
COUNT(*) > 30:筛选条件,只保留 "学生人数大于 30" 的分组(班级)-- 统计每个班级的人数并按人数排序(从多到少)
SELECT class_name AS '班级',#class是列,比如name,id列,这里表示按班级分组,一样的为一组COUNT(*) AS '人数' #统计每个分组(班级)的学生总数,并命名为 "人数"
FROM class_students #这个是表名
GROUP BY class_name #还是列
ORDER BY 人数 DESC; #ORDER BY 人数 DESC:将结果按人数从多到少排序,方便直观对比
3. 排序(升序、降序)
使用ORDER BY子句对查询结果进行排序,默认是升序。
- 升序(ASC):从小到大排序(可省略不写)
- 降序(DESC):从大到小排序
示例:
-- 按年龄升序排列学生( youngest to oldest)
SELECT student_name, score FROM class_students ORDER BY score ASC;
选择,name和score两列,然后根据score进行asc,选用class_students表
-- 按分数降序排列考试结果( highest to lowest)
SELECT student_name, score FROM class_students ORDER BY score DESC;-- 多列排序:先按班级升序,再按年龄降序
SELECT student_name, class_name, age FROM class_students ORDER BY class_name ASC, age DESC;
选择student_name, class_name, age 三列,选择class_students 表,然后class_name 升序ASC, age 降序DESC;
4. 分页查询
分页查询用于限制返回结果的数量,通常用于在网页上分页显示数据。不同数据库语法略有差异:
-
MySQL 使用
LIMIT:-- 从第0条记录开始,获取10条记录(第一页) SELECT * FROM class_students LIMIT 0, 10;厘米特 前面的数字是多少就是跳过多少行 -- 从第10条记录开始,获取10条记录(第二页) SELECT * FROM class_students LIMIT 10, 10;
5. 子查询
子查询是嵌套在其他 SQL 语句中的查询,也称为内部查询,而包含子查询的查询称为外部查询。
子查询可以用于SELECT、FROM、WHERE等子句中。
-
在 WHERE 子句中使用子查询:
-- 查找分数高于平均分的学生 SELECT class_name, score FROM class_students WHERE score > (SELECT AVG(score) FROM class_students); -
在 FROM 子句中使用子查询(作为临时表):
-- 查找每个班级分数最高的学生信息 SELECT s.name, s.class, s.score FROM exam_results s INNER JOIN (SELECT class, MAX(score) AS max_scoreFROM exam_resultsGROUP BY class ) AS sub ON s.class = sub.class AND s.score = sub.max_score;SELECT class_name, score, student_name FROM class_students s WHERE score = (SELECT MAX(score)FROM class_studentsWHERE class_name = s.class_name ); -
在 SELECT 子句中使用子查询:
-- 查询每个学生的姓名及其所在班级的平均年龄 SELECT class_name, (SELECT AVG(age) FROM class_students s2 WHERE s2.class = s1.class) AS class_avg_age FROM class_students s1;-- 修正字段名并优化:查询每个学生的姓名及其所在班级的平均年龄 SELECT student_name, -- 学生姓名class_name, -- 班级名称-- 子查询:计算当前学生所在班级的平均年龄(SELECT AVG(age) FROM class_students s2 WHERE s2.class_name = s1.class_name -- 关联条件:同一个班级) AS class_avg_age -- 别名:班级平均年龄 FROM class_students s1; -- 主表别名s1
这些是 SQL 查询中非常基础且常用的操作,掌握它们可以帮助你完成大部分数据查询和分析任务。在实际应用中,这些操作经常会结合使用,以实现更复杂的查询需求。
多表连接查询是 SQL 中用于从多个相关表中获取数据的核心操作,通过表之间的关联字段(通常是主键和外键)将数据连接起来。常见的连接类型及用法如下:
1. 内连接(INNER JOIN)
从三个表中分别提取需要的数据,并通过关联条件组合起来
作用:只返回两个表中匹配关联条件的记录(交集)。
语法:
SELECT 表1.字段, 表2.字段
FROM 表1
INNER JOIN 表2
ON 表1.关联字段 = 表2.关联字段;
示例:查询学生及其所在班级的信息(学生表 students 和班级表 classes 通过 class_id 关联):
SELECT students.name, classes.class_name
FROM students
INNER JOIN classes
ON students.class_id = classes.id;
2. 左连接(LEFT JOIN / LEFT OUTER JOIN)
- 左侧表(
LEFT JOIN左边的表)的所有记录都会被保留,无论是否能在右侧表中找到匹配的数据。 - 右侧表如果没有匹配的记录,对应的字段值就会用
NULL填充。
作用:返回左表(FROM 后的表)所有记录,以及右表中匹配关联条件的记录;右表无匹配时显示 NULL。
语法:
SELECT 表1.字段, 表2.字段
FROM 表1
LEFT JOIN 表2
ON 表1.关联字段 = 表2.关联字段;
示例:查询所有学生(包括未分配班级的)及其班级信息:
SELECT students.name, classes.class_name
FROM students
LEFT JOIN classes
ON students.class_id = classes.id;
3. 右连接(RIGHT JOIN / RIGHT OUTER JOIN)
作用:与左连接相反,返回右表所有记录,以及左表中匹配关联条件的记录;左表无匹配时显示 NULL。
语法:
SELECT 表1.字段, 表2.字段
FROM 表1
RIGHT JOIN 表2
ON 表1.关联字段 = 表2.关联字段;
示例:查询所有班级(包括没有学生的)及班级中的学生:
SELECT classes.class_name, students.name
FROM students
RIGHT JOIN classes
ON students.class_id = classes.id;
4. 全连接(FULL JOIN / FULL OUTER JOIN)
全连接(FULL JOIN 或 FULL OUTER JOIN) 的逻辑是:
左右两侧表的所有记录都会被保留,无论是否能在对方表中找到匹配的数据。
作用:返回左表和右表的所有记录,匹配的记录合并,不匹配的部分显示 NULL。
注意:MySQL 不直接支持 FULL JOIN,可通过 UNION 组合左连接和右连接实现。
语法(支持的数据库如 SQL Server):
SELECT 表1.字段, 表2.字段
FROM 表1
FULL JOIN 表2
ON 表1.关联字段 = 表2.关联字段;
5. 交叉连接(CROSS JOIN)
交叉连接(CROSS JOIN) 是 SQL 中一种特殊的连接方式,它的核心逻辑是:将左表的每一行与右表的每一行进行组合,生成两表所有可能的 “行对”,即数学中的 “笛卡尔积”(Cartesian product)。
特点与逻辑
- 不需要指定连接条件(
ON子句),因为它会强制匹配所有行。 - 结果集的行数 = 左表行数 × 右表行数。
- 无论两表是否有关联,都会生成所有可能的组合。
示例
作用:返回两个表的笛卡尔积(左表每条记录与右表所有记录组合),慎用(数据量可能极大)。
语法:
SELECT 表1.字段, 表2.字段
FROM 表1
CROSS JOIN 表2;
关键注意事项:
- 关联条件:必须通过
ON指定连接条件(避免笛卡尔积),多表连接时可连续使用JOIN。 - 表别名:使用
AS简化表名,例如students AS s可简写为s。 - 优先级:
JOIN优先级高于WHERE,建议先连接再过滤(用WHERE或ON补充条件)。
通过多表连接,可以灵活组合不同表的数据,满足复杂查询需求(如 “查询某课程的学生成绩及对应教师信息” 等)。
…6
这段内容是 MySQL 数据库的查询语句及执行结果,以下是拆解解析:
1. SQL 查询语句
SELECT u2.username, u2.city
FROM users u1
JOIN users u2 ON u1.city = u2.city
WHERE u1.username = '张三' AND u2.username != '张三';
-
作用:从
users表中,查询与 “张三”同城市,但不是张三本人的用户信息(姓名、城市)。 -
语法拆解
:
SELECT u2.username, u2.city:指定要查询的字段(u2表的username和city)。FROM users u1:从users表取数据,给表起别名u1(方便后续关联)。JOIN users u2 ON u1.city = u2.city:自连接(同一张表users自己关联自己),条件是u1和u2的city字段值相同(即 “同城市”)。WHERE u1.username = '张三' AND u2.username != '张三':筛选条件,u1是 “张三”,且u2不是 “张三”(避免查自己)。
2. 执行结果
+----------+--------+
| username | city |
+----------+--------+
| 赵六 | 北京 |
+----------+--------+
1 row in set (0.00 sec)
-
含义
:查询结果返回 1 条数据,说明:
- 表中 “张三” 所在城市是 北京;
- 同在北京、且不是 “张三” 的用户是 赵六。
在 MySQL 中,除了DATE(日期类型)、INT(整数类型)外,还有很多其他数据类型,以下是常见的数据类型及其说明:
表格标题选择的数值类型
TINYINT:极小整数类型,占用 1 个字节存储空间。有符号的范围是 -128 到 127,无符号的范围是 0 到 255。常用于存储取值范围较小的整数,比如年龄等级(1 - 5 级)等。SMALLINT:小整数类型,占用 2 个字节。有符号范围是 -32768 到 32767,无符号范围是 0 到 65535。可用于存储人数、简单计数等。MEDIUMINT:中等大小整数类型,占用 3 个字节。有符号范围是 -8388608 到 8388607,无符号范围是 0 到 16777215 。BIGINT:大整数类型,占用 8 个字节,有符号范围非常大,适用于存储极大的数值,像自增 ID 在预计数据量特别大时可以使用此类型。FLOAT:单精度浮点数类型,占用 4 个字节,用于存储带有小数部分的数值,但存在一定精度损失,如存储3.1415926可能会有细微偏差。DOUBLE:双精度浮点数类型,占用 8 个字节,精度比FLOAT更高,但同样存在精度问题,适用于对精度要求不是极高的科学计算、价格计算等场景。DECIMAL:定点数类型,能精确存储小数,占用字节数根据精度设置而定。常用于存储对精度要求极高的财务数据,如金额等,可指定精度和小数位数,如DECIMAL(10, 2)表示总位数为 10 位,小数部分占 2 位。
日期和时间类型
TIME:时间类型,用于存储一天内的时间,格式为HH:MM:SS(时:分: 秒),也可以只存储部分,如HH:MM。YEAR:年份类型,占用 1 个字节,可存储范围是 1901 - 2155。DATETIME:日期时间类型,占用 8 个字节,能存储从 1000 - 01 - 01 00:00:00 到 9999 - 12 - 31 23:59:59 的日期和时间信息。TIMESTAMP:时间戳类型,占用 4 个字节,存储范围是1970 - 01 - 01 00:00:01 UTC到2038 - 01 - 19 03:14:07 UTC,会自动根据时区进行调整,常用来记录数据的创建或更新时间。
字符串类型
CHAR:固定长度字符串类型,定义时需指定长度,如CHAR(10),无论实际存储的字符串是否达到指定长度,都会占用固定字节数。适合存储长度固定的字符串,如身份证号后 4 位校验码(固定 4 位)等。VARCHAR:可变长度字符串类型,同样要指定最大长度,如VARCHAR(50),实际占用空间为字符串长度加上 1 - 2 个字节的长度标识,更节省存储空间,适用于存储长度不确定的字符串,比如姓名、地址等。TEXT:文本类型,用于存储大量文本数据,如文章内容、备注信息等。根据存储数据量大小,又分为TINYTEXT(最大 255 字节)、TEXT(最大 65535 字节 )、MEDIUMTEXT(最大 16777215 字节 )、LONGTEXT(最大 4294967295 字节 ) 。BINARY和VARBINARY:分别是固定长度和可变长度的二进制字符串类型,用于存储二进制数据,如图片、音频等文件的二进制内容(实际应用中更多使用专门的文件存储方式,但理论上可存 )。
其他类型
ENUM:枚举类型,定义时需列出所有可能的值,如ENUM('男', '女'),只能从列出的值中选择一个进行存储,节省存储空间,常用于存储取值固定的字段,如性别、订单状态等。SET:集合类型,与ENUM类似,但可以同时存储多个值,如SET('苹果', '香蕉', '橙子'),可以存储一个或多个水果名称 。
