QL基础语言
SQL的分类:
DDL:(数据定义语言)(Data Definition Language) 对库和表进行操作,库和表结构的创建、修改、删除;
create 创建库、表、索引、视图、用户
alter 修改库字符集、表结构、索引、视图、用户、密码
drop 删除各种结构、库、表、视图、索引、用户
show 显示库、表
DML:(数据操纵语言) (Data Manipulation Language) 对表中的数据内容进行添加、修改、删除
insert 在表中插入、添加数据
update 修改表中的内容
delete 删除表中的内容
DQL:(数据查询语言) (Data Query Language) 对表中数据进行查询操作
select 根据条件查询内容、可以配合函数使用。
DCL:(数据控制语言) (Data Control Language) 对数据库进行权限管理、用户管理、事务管理
use 切换数据库
grant 权限设置
revoke 移除权限
DTL:(事务控制语言) (Data Transaction Language)
commit 事务提交
rollback 回滚
总结:需要记下来并且能默写
create 创建库、表、索引、视图、用户
alter 修改库字符集、表结构、索引、视图、用户、密码
drop 删除各种结构、库、表、视图、索引、用户
show 显示库、表
insert 在表中插入、添加数据
update 修改表中的内容
delete 删除表中的内容
select 根据条件查询内容、可以配合函数使用
use 切换数据库
grant 权限设置
revoke 移除权限
commit 事务提交
rollback 回滚
操作总结:
创建创建数据库
-- 基础创建库 CREATE DATABASE school; 拆解:CREATE # 创建(库/表) DATABASE # 创建库 school # 库名 -- 安全创建库(存在则忽略) CREATE DATABASE IF NOT EXISTS school CHARACTER SET utf8mb4 拆解:IF NOT EXISTS # 仅当数据库不存在时才创建,存在则忽略(不会报错) CHARACTER SET utf8mb4 # 指定使用 UTF-8 MB4查看/切换/删除
-- 查看所有数据库 SHOW DATABASES; -- 查看数据库里所有的表 SHOW TABLES; -- 切换数据库 USE 库名; -- 查看当前所在数据库 SELECT DATABASE(); -- 查看表结构(两种方式) DESC 表名; -- 查看表结构 SHOW COLUMNS FROM 表名; -- 查看建表语句 SHOW CREATE TABLE 表名; -- 删除数据库(谨慎!) DROP DATABASE school; -- 或安全删除 DROP DATABASE IF EXISTS school; -- 删除表(谨慎!) DROP TABLE 表名; -- 安全删除 DROP TABLE IF EXISTS 表名;创建表操作
-- 基础创建表 CREATE TABLE school ( id INT, name VARCHAR(20), age VARCHAR(3) ); 拆解:CREATE # 创建(库/表) TABLE # 创建表 school # 表名 格式介绍: # 可以加comment '注释信息' 团队协作或后期维护,能让人看懂字段的用途。 # 数据限制类型包括varchar、char CREATE TABLE 表名 ( 列名1 数据类型 comment '注释信息', 列名2 数据类型 约束条件, 列名3 数据类型(数据限制), ); 案例: create table `库名`.`表名`( # 在数据库中创建一张表 id int, # 整型,学生编号 name varchar(30), # 可变长度字符串,最大30个字符,姓名 gender enum('男','女'), # 枚举类型,只能选'男'或'女',性别 birthday date # 日期类型(格式:YYYY-MM-DD)生日 age INT CHECK (age >= 18 AND age <= 65) # 年龄必须在 18-65 之间 ); # 数据类型:用于规范数据列的内容; int # 整数 bigint # 长整数 check # 限制列中值的范围或条件 char # 定长字符串(18) varchar # 变长字符串varchar(18)节省储存空间,性能稍微 enum # 枚举类型,本质也是字符类型,类似单选框只能从已有选项中,选择一个添加 set # 集合类型,字符串,可选一个或多个选择 text # 文本类型65,535 字节 (约 64 KB) longtext # 大文本类型4,294,967,295 字节 (约 4 GB) float # 浮点类型,普通小数,精确度低,约6-7位有效数字 double # 双精度浮点类型,比float精度高一倍,约15-16位有效数字 decimal # 小数,本质是以字符方式储存数据decimal(20,10) (总位数,小数位) date # 日期类型 'YYYY-MM-DD' time # 时间类型 'HH:MM:SS' datetime # 时间日期类型 'YYYY-MM-DD HH:MM:SS' 【建议使用】 TIMESTAMP # 时间戳 'yyyymmddhhmmss' # 约束条件:对数据列或表进行设置与约束 ## 表级约束 engine # 存储引擎 charset # 字符集 ## 行级约束 PRIMARY KEY # 主键,唯一、不能为空,精确查询; unsigned # 无符号,数字只能为正数,不能为负数; not null # 不能为空,不添加数据会报错; auto_increment # 自动增长,整数添加,自动+1; unique key # 值唯一,不能重复; foreign key # 外键约束,用于多表连接查询; default # 设置默认值 ## 约束补充 - 检查约束(CHECK) - 作用:限制列中值的范围或条件(MySQL 8.0.16及以上支持) - 自增约束(AUTO_TNCREMENT) - 作用:自动为新记录生成唯一的递增数值,通常与主键配合使用。 修改表操作
-- 添加字段(表添加一个新的列) ALTER TABLE 表名 ADD 列名 VARCHAR(20); -- 修改字段类型(修改某一列的数据类型) ALTER TABLE 表名 MODIFY 列名 TINYINT; -- 重命名字段(给列名重命名,能同时修改列名和数据类型) ALTER TABLE 表名 CHANGE 旧列名 新列名 VARCHAR(10); -- 删除字段(删除某一列,COLUMN可忽略) ALTER TABLE 表名 DROP COLUMN 列名; -- 重命名表(给表重新改一个名字) ALTER TABLE 旧表名 RENAME TO 新表名;数据操作(CRUD)
-- 插入完整数据 INSERT INTO students (id, name ,gender) VALUES (1, '安某某', '女'); -- 插入完整数据(中文版) INSERT INTO 表名 (`编号`, `姓名`, `性别`) VALUES (1, '安某某', '女'); -- 插入多条数据(中文版) INSERT INTO 表名 (`编号`, `姓名`, `性别`) VALUES (2, '张三', '男'), (3, '李四', '女'); -- 插入部分字段(中文版) INSERT INTO 表名 (`编号`, `姓名`) VALUES (4, '王五'); -- 从其他表复制数据 INSERT INTO 被复制表 SELECT * FROM 表名;表数据查询
-- 查询所有(查看表里面的数据) SELECT * FROM 表名; -- 查询指定字段 SELECT 列名,列名 FROM 表名; -- 条件查询 SELECT * FROM 表名 WHERE id(列名) = 1; SELECT * FROM 表名 WHERE gender(列名) = '女' AND age(列名) > 18; SELECT * FROM 表名 WHERE gender(列名) = '男' OR age(列名) > 20; # 运算符 含义 效果 AND 逻辑与 所有条件都满足才返回 TRUE OR 逻辑或 任意一个条件满足就返回 TRUE -- 模糊查询 SELECT * FROM 表名 WHERE 列名 LIKE '安%'; -- 以"安"开头 SELECT * FROM 表名 WHERE 列名 LIKE '%倩'; -- 以"倩"结尾 SELECT * FROM 表名 WHERE 列名 LIKE '%张%'; -- 包含"张" -- 排序 SELECT * FROM 表名 ORDER BY 列名 DESC; -- 降序 SELECT * FROM 表名 ORDER BY 列名 ASC; -- 升序 # ORDER BY 对查询结果排序 ASC/升序 DESC/降序 -- 分页 SELECT * FROM 表名 LIMIT 10; -- 前10条 SELECT * FROM 表名 LIMIT 10 OFFSET 20; -- 第21-30条 # LIMIT 10 限制返回行数,只返回前 10 条记录 # OFFSET 20 跳过前 20 条记录,从第 21 条开始取 -- 聚合查询 SELECT COUNT(*) FROM 表名; -- 统计表中总共有多少条记录 SELECT AVG(列名) FROM 表名; -- 计算表中某一列所有数值的平均值 SELECT gender(列名), COUNT(*) FROM 表名 GROUP BY gender(列名); -- 按性别分组,统计每个性别各有多少人。修改数据
-- 更新单条数据 UPDATE 表名 SET 列名(性别) = '男' WHERE 列名(id) = 1; -- 更新多条数据 UPDATE 表名 SET 列名(年龄) = 20 WHERE 列名(性别) = '女'; -- 更新多个字段 UPDATE 表名 SET 列名(姓名) = '赵六', 列名(年龄) = 22 WHERE 列名(id) = 4; -- ⚠️ 忘记WHERE的后果(更新所有行!) UPDATE 表名 SET 列名(年龄) = 18; -- 所有学生年龄都变成18删除数据
-- 删除指定记录 DELETE FROM 表名 WHERE 列名(id) = 1; -- 删除所有记录(保留表结构) DELETE FROM 表名; -- 或快速清空 TRUNCATE TABLE 表名; -- ⚠️ 忘记WHERE的后果(删除所有数据!) DELETE FROM `学生信息`; -- 所有数据被删除约束(Constraint)
CREATE TABLE `学生信息` ( `编号` INT PRIMARY KEY AUTO_INCREMENT, -- 主键+自增 `姓名` VARCHAR(20) NOT NULL, -- 非空 `邮箱` VARCHAR(50) UNIQUE, -- 唯一 `年龄` INT DEFAULT 18, -- 默认值 `班级` VARCHAR(20), FOREIGN KEY (`班级`) REFERENCES `班级表`(`班级编号`) -- 外键 );
数据类型查询
数据类型查询表
1. 整数型
类型后面括号里的
m指的是显示宽度,显示宽度与所能存储的数据范围无关,目前已知的是当设置了ZEROFILL(填充0)约束条件时,填充0的 个数由m决定2. 浮点数和定点数
3. 日期时间
4. 字符串类型
安全模式
# 查看安全模式是否开启
## 需要进入mysql执行操作(关闭状态)
mysql> show variables like 'sql_safe_updates';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | OFF |
+------------------+-------+
1 row in set (0.25 sec)
## 需要进入mysql执行操作(开启状态)
mysql> show variables like 'sql_safe_updates';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | ON |
+------------------+-------+
1 row in set (0.01 sec)
# 临时开启(exit退出后失效)
## 需要进入mysql执行操作
set sql_safe_updates = 1;
# 永久开启,修改配置文件
vim /etc/my.cnf # mysql配置文件
# 每次开启MySQL时,自动加载文件中的操作
## 在/etc/my.cnf的[mysqld]最下面添加(自动加载文件)
init-file=/usr/local/mysql/init-file.sql # init-file= 固定语句 后面跟随路径
# 创建init-file.sql并在里面配置加载参数
## vim 创建init-file.sql
vim /usr/local/mysql/init-file.sql # 创建加载配置文件
## 在init-file.sql里面添加以下内容(安全模式)
set global sql_safe_updates = 1; # 每次开启MySQL时,自动加载文件中的操作
# 修改文件属主及属组权限(保持mysql文件权限统一性)
chown mysql:mysql /usr/local/mysql/init-file.sql
# 重启mysql服务
systemctl restart mysqld外键(FOREIGN KEY)
外键是用于关联两个表的约束,确保表之间的数据关联性和一致性。
主表:被从表(包含外键的表)通过主键关联。
核心作用:强制从表(含外键的表)的某个字段值必须对应主表(被引用的表)中已存在的主键值。
在从表中创建外键,外键字段对应主表的主键,并且外键对应的主键必须存在,才能被录入,否则会报错;
但是生产环境使用时要注意,外键会影响写入性能,对于性能要求较高的应用,不建议使用外键,可以使用后端程序进行一致性和完整性验证;
示例场景: 主表
students(学生信息)和从表scores(成绩信息)通过外键关联,确保成绩表中的学生必须是学生表中已存在的。-- 主表:学生表 CREATE TABLE students ( -- 创建 students表名 `学生ID` INT PRIMARY KEY, `姓名` VARCHAR(50) ); -- 从表:成绩表 CREATE TABLE scores ( -- 创建 scores表名 `成绩ID` INT PRIMARY KEY, `ID学生` INT, -- ✅ 字段名:ID学生 `分数` INT, FOREIGN KEY (`ID学生`) REFERENCES students(`学生ID`) -- ✅ 引用正确的字段名 ON DELETE CASCADE );外键规则: 当主表数据被修改时,可通过
ON DELETE或ON UPDATE定义从表的行为(如CASCADE级联删除、SET NULL设为NULL等)。总结
约束条件是保障数据规则的“工具集”(主键、外键、非空等);
外键是约束的一种,专门用于维护表之间的关联关系;
完整性是数据符合规则的“状态”(实体、域、参照等维度);
唯一性是数据的“属性”,确保字段值不重复(通过主键或唯一约束实现)。
合理使用这些机制,能有效保证数据库数据的准确性、一致性和可靠性。
SQL查询
SQL常见查询条件(where前表名后列名)
CHAR_LENGTH()与LENGTH()的区别(避坑指南)
CHAR_LENGTH(str):返回字符数,无论中文还是英文,一个汉字算 1 个长度。
例子:
CHAR_LENGTH('你好')-> 结果 2
LENGTH(str):返回字节数 ,这取决于数据库的编码格式。
英文字母、数字、标点:每个占 1 字节。
中文汉字:每个占 3 字节。
Emoji 表情:每个占 4 字节。
特殊符号或生僻字:可能占 2~4 字节不等。
例子:
LENGTH('你好')-> 结果 6建议:如果你是指“字数”(即几个字),请务必使用
CHAR_LENGTH()。
WHERE 普通查询,通过条件,过滤出结果
HAVING 根据分组后的结果在进行条件过滤
SELECT user_id, SUM(total_amount) FROM orders GROUP BY user_id HAVING SUM(total_amount) < 5000;
多表连接查询
交叉连接(笛卡尔积连接):连接查询时,没有指定条件或条件错误导致,两张表中的内容进行排列组合;
内连接 JOIN:只返回有关联关系的结果;
外连接
左(外)连接:完整显示左表中的所有数据,右边显示关联数据,没有关联数据显示NULL;
右(外)连接:完整显示右表中的所有数据,左边显示关联数据,没有关联数据显示NULL;
联合查询
交叉连接(笛卡尔积连接):select * from 表名 join 表名;
例子:select * from users join products;
内连接 JOIN:select * from 表名 inner join 表名 on 表名.id = 表名.id;(inner可省略)
例子:select * from users join products on users.id = products.id;
外连接:
左连接:select * from 表名 left join 表名 on 表名.id = 表名.id;
例子:select * from users left join products on users.id = products.id;
右连接:select * from 表名 right join 表名 on 表名.id = 表名.id;
例子:select * from users right join products on users.id = products.id;
别名连接:select * from 表名 别名 join 表名 别名 on 别名.id = 别名.id
例子:select * from user u join products p on u.id = p.id
别名连接简化查询:在后面加上 where 别名.列名 > 筛选条件;
例子:select * from user u join products p on u.id = p.id where p.price > 10000;
核心一句话总结:
内连接:只要双方都有,我才要。
左连接:左边的全部要,右边有的就带上,没有就填
NULL。右连接:右边的全部要,左边有的就带上,没有就填
NULL。
三表连接查询:使用外键关联三张表;
SELECT * FROM orders o JOIN users u ON o.user_id = u.id JOIN products p ON o.product_id = p.id; 拆解: 🔍关联用户表 JOIN users u -- ① 关联表:users(用户表) -- ② 别名:u -- ③ 连接类型:JOIN = INNER JOIN(内连接) ON o.user_id = u.id -- ④ 关联条件:订单的 user_id = 用户的 id 🔍关联商品表 JOIN products p -- ① 关联表:products(商品表) -- ② 别名:p -- ③ 连接类型:JOIN = INNER JOIN(内连接) ON o.product_id = p.id -- ④ 关联条件:订单的 product_id = 商品的 idSELECT o.id AS 订单号, u.name AS 用户名, p.name AS 商品名, o.quantity AS 数量, o.total_amount AS 金额 FROM orders o JOIN users u ON o.user_id = u.id JOIN products p ON o.product_id = p.id; 拆解: 🔍选择指定列(带中文别名) SELECT o.id AS 订单号, -- ① 从 orders 表取订单ID,显示为"订单号" u.name AS 用户名, -- ② 从 users 表取用户名,显示为"用户名" p.name AS 商品名, -- ③ 从 products 表取商品名称,显示为"商品名" o.quantity AS 数量, -- ④ 从 orders 表取购买数量,显示为"数量" o.total_amount AS 金额 -- ⑤ 从 orders 表取订单总金额,显示为"金额" 🔍指定主表 FROM orders o -- ① 主表:orders(订单表) -- ② 别名:o 🔍关联用户表 JOIN users u -- ① 关联表:users(用户表) -- ② 别名:u -- ③ 连接类型:JOIN = INNER JOIN(内连接) ON o.user_id = u.id -- ④ 关联条件:订单的 user_id = 用户的 id
联合查询:
UNION:合并结果集并自动去除重复记录;
UNION ALL:合并结果集但保留重复记录(效率比UNION高);
UNION合并结果集并自动去除重复记录方式(合并结果集但保留重复记录:UNION ALL): -- 查询价格低于200的商品和年龄小于25的用户 SELECT '商品' AS 类型, name AS 名称, '价格低' AS 描述 FROM products WHERE price < 200 UNION SELECT '用户' AS 类型, username AS 名称, '年龄小' AS 描述 FROM users WHERE age < 25; 拆解: 🔍 上半部分:查询商品数据 SELECT '商品' AS 类型, -- ① 常量字符串:固定显示"商品" name AS 名称, -- ② 从 products 表取商品名称 '价格低' AS 描述 -- ③ 常量字符串:固定显示"价格低" FROM products -- ④ 数据来源:商品表 WHERE price < 200; -- ⑤ 筛选条件:价格低于 200 🔍 下半部分:查询用户数据 SELECT '用户' AS 类型, -- ① 常量字符串:固定显示"用户" username AS 名称, -- ② 从 users 表取用户名 '年龄小' AS 描述 -- ③ 常量字符串:固定显示"年龄小" FROM users -- ④ 数据来源:用户表 WHERE age < 25; -- ⑤ 筛选条件:年龄小于 25 注:-- 这条语句会真的创建一张名为 summary_report 的新表 CREATE TABLE summary_report AS SELECT '商品' AS 类型, name AS 名称, '价格低' AS 描述 FROM products WHERE price < 200 UNION SELECT '用户' AS 类型, username AS 名称, '年龄小' AS 描述 FROM users WHERE age < 25;
MySQL基础语法
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法