【MySQL全面教学】MySQL基础SQL语句Day3(2026年)

欢迎来到MySQL系列教程的第3天!今天我们将学习SQL语句的基础操作,包括DDL(数据定义语言)、DML(数据操作语言)和DQL(数据查询语言)。这些将是日后最常用的SQL命令,务必熟练掌握。

文章目录


一、写在前面

SQL语句分为以下几类:

分类 全称 主要语句 用途
DDL Data Definition Language CREATE, DROP, ALTER 定义数据库结构
DML Data Manipulation Language INSERT, UPDATE, DELETE 操作数据
DQL Data Query Language SELECT 查询数据
DCL Data Control Language GRANT, REVOKE 权限控制
TCL Transaction Control Language COMMIT, ROLLBACK 事务控制

今天我们重点学习DDL、DML和DQL的基础用法。


二、DDL语句:数据库和表的操作

2.1 数据库操作

sql 复制代码
-- 创建数据库
CREATE DATABASE IF NOT EXISTS ecommerce 
    DEFAULT CHARACTER SET utf8mb4 
    COLLATE utf8mb4_unicode_ci;

-- 使用数据库
USE ecommerce;

-- 查看所有数据库
SHOW DATABASES;

-- 查看当前数据库
SELECT DATABASE();

-- 删除数据库(危险操作!)
DROP DATABASE IF EXISTS ecommerce;

-- 修改数据库字符集
ALTER DATABASE ecommerce CHARACTER SET utf8mb4;

经验之谈: 创建数据库时务必指定 utf8mb4 字符集,支持完整的Unicode(包括emoji)。

2.2 表操作:CREATE TABLE

sql 复制代码
-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
    username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
    email VARCHAR(100) NOT NULL UNIQUE COMMENT '邮箱',
    phone CHAR(11) COMMENT '手机号',
    password VARCHAR(255) NOT NULL COMMENT '密码(加密存储)',
    status TINYINT UNSIGNED DEFAULT 1 COMMENT '状态:0-禁用 1-启用',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    INDEX idx_email (email),
    INDEX idx_phone (phone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

CREATE TABLE要点:

  • 每个表建议有 id 主键
  • 常用查询字段加索引
  • 必须设置字符集为utf8mb4
  • 添加COMMENT注释,方便维护

2.3 表操作:ALTER TABLE

sql 复制代码
-- 添加列
ALTER TABLE users ADD COLUMN nickname VARCHAR(50) COMMENT '昵称' AFTER username;

-- 修改列类型
ALTER TABLE users MODIFY COLUMN phone VARCHAR(20) COMMENT '手机号(支持国际号码)';

-- 修改列名(MySQL 8.0+)
ALTER TABLE users RENAME COLUMN nickname TO display_name;

-- 删除列
ALTER TABLE users DROP COLUMN display_name;

-- 添加索引
ALTER TABLE users ADD INDEX idx_created_at (created_at);

-- 删除索引
ALTER TABLE users DROP INDEX idx_created_at;

-- 修改表名
ALTER TABLE users RENAME TO sys_users;
RENAME TABLE sys_users TO users;

2.4 删除表

sql 复制代码
-- 删除表(会删除数据和结构)
DROP TABLE IF EXISTS temp_table;

-- 清空表数据(保留结构)
TRUNCATE TABLE temp_table;

三、DML语句:数据的增删改

3.1 INSERT语句的多种写法

sql 复制代码
-- 方式1:标准插入(推荐,明确指定列)
INSERT INTO users (username, email, phone, password) 
VALUES ('zhangsan', 'zhangsan@example.com', '13800138000', 'encrypted_pwd');

-- 方式2:插入多行(性能更好)
INSERT INTO users (username, email, password) VALUES 
    ('lisi', 'lisi@example.com', 'pwd1'),
    ('wangwu', 'wangwu@example.com', 'pwd2'),
    ('zhaoliu', 'zhaoliu@example.com', 'pwd3');

-- 方式3:使用SET语法
INSERT INTO users SET 
    username = 'sunqi',
    email = 'sunqi@example.com',
    password = 'pwd4';

-- 方式4:从其他表插入(数据迁移常用)
INSERT INTO users_backup (username, email)
SELECT username, email FROM users WHERE status = 0;

-- 方式5:存在则更新,不存在则插入(UPSERT)
INSERT INTO users (id, username, email) 
VALUES (1, 'newname', 'new@example.com')
ON DUPLICATE KEY UPDATE 
    username = VALUES(username),
    email = VALUES(email);

-- MySQL 8.0.19+ 新语法
INSERT INTO users (id, username, email) 
VALUES (1, 'newname', 'new@example.com') AS new
ON DUPLICATE KEY UPDATE 
    username = new.username,
    email = new.email;

经验之谈:

  • 生产环境务必指定列名,不要依赖列顺序
  • 批量插入比单条插入性能高很多
  • 使用 INSERT IGNORE 忽略重复键错误

3.2 UPDATE的安全写法

sql 复制代码
-- 危险!忘记WHERE会更新所有行!
UPDATE users SET status = 0;  -- 所有用户都被禁用了!

-- 安全的UPDATE写法(先查询确认)
-- 步骤1:先SELECT确认要更新的数据
SELECT * FROM users WHERE id = 1;

-- 步骤2:执行UPDATE(必须带WHERE)
UPDATE users 
SET status = 0, updated_at = NOW() 
WHERE id = 1;

-- 使用LIMIT限制更新数量(保险措施)
UPDATE users SET status = 0 WHERE status = 1 LIMIT 10;

-- 多表UPDATE
UPDATE users u
JOIN orders o ON u.id = o.user_id
SET u.order_count = u.order_count + 1
WHERE o.status = 'completed';

3.3 DELETE和TRUNCATE的区别

sql 复制代码
-- DELETE:删除指定行,可以回滚,记录日志
DELETE FROM users WHERE id = 1;

-- DELETE忘记WHERE的补救:使用LIMIT
DELETE FROM users LIMIT 1;  -- 只删1条

-- TRUNCATE:清空整个表,速度快,不可回滚
TRUNCATE TABLE temp_logs;
特性 DELETE TRUNCATE
删除范围 可指定条件 全部数据
执行速度 较慢(逐行删除) 很快(删除表重建)
事务回滚 支持 不支持
触发器 会触发 不会触发
自增计数 保留 重置
日志记录 记录每行 最小日志

四、DQL基础:SELECT查询

4.1 SELECT * 的坑

sql 复制代码
-- 不推荐:SELECT * 会返回所有列
SELECT * FROM users;

-- 推荐:明确指定需要的列
SELECT id, username, email, created_at FROM users;

-- 原因:
-- 1. 网络传输更多数据
-- 2. 可能包含敏感字段(password)
-- 3. 表结构变化会影响应用程序
-- 4. 无法利用覆盖索引优化

4.2 别名和去重

sql 复制代码
-- 列别名(AS可省略)
SELECT 
    id AS user_id,
    username AS name,
    created_at AS register_time
FROM users;

-- 表别名(多表查询常用)
SELECT u.id, u.username FROM users u;

-- 去重DISTINCT
SELECT DISTINCT status FROM users;  -- 查看有哪些状态值

-- 多列去重(组合唯一)
SELECT DISTINCT status, gender FROM users;

五、实战:创建电商订单系统相关表

5.1 完整的电商表结构设计

sql 复制代码
-- 用户表
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    phone CHAR(11),
    password VARCHAR(255) NOT NULL,
    status TINYINT UNSIGNED DEFAULT 1,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_phone (phone)
) ENGINE=InnoDB COMMENT='用户表';

-- 商品表
CREATE TABLE products (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(200) NOT NULL COMMENT '商品名称',
    description TEXT COMMENT '商品描述',
    price DECIMAL(10, 2) NOT NULL COMMENT '售价',
    stock INT UNSIGNED DEFAULT 0 COMMENT '库存',
    status TINYINT UNSIGNED DEFAULT 1 COMMENT '0-下架 1-上架',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_status_price (status, price)
) ENGINE=InnoDB COMMENT='商品表';

-- 订单表
CREATE TABLE orders (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    order_no VARCHAR(32) NOT NULL UNIQUE COMMENT '订单编号',
    user_id INT UNSIGNED NOT NULL COMMENT '用户ID',
    total_amount DECIMAL(10, 2) NOT NULL COMMENT '订单总金额',
    status TINYINT UNSIGNED DEFAULT 0 COMMENT '0-待支付 1-已支付 2-已发货 3-已完成 4-已取消',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_order_no (order_no),
    INDEX idx_created_at (created_at),
    FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB COMMENT='订单表';

-- 订单商品表(订单明细)
CREATE TABLE order_items (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    order_id INT UNSIGNED NOT NULL COMMENT '订单ID',
    product_id INT UNSIGNED NOT NULL COMMENT '商品ID',
    product_name VARCHAR(200) NOT NULL COMMENT '商品名称(快照)',
    price DECIMAL(10, 2) NOT NULL COMMENT '下单时价格',
    quantity INT UNSIGNED NOT NULL COMMENT '数量',
    subtotal DECIMAL(10, 2) NOT NULL COMMENT '小计金额',
    INDEX idx_order_id (order_id),
    FOREIGN KEY (order_id) REFERENCES orders(id),
    FOREIGN KEY (product_id) REFERENCES products(id)
) ENGINE=InnoDB COMMENT='订单商品表';

5.2 插入测试数据

sql 复制代码
-- 插入用户
INSERT INTO users (username, email, phone, password) VALUES 
    ('user001', 'user001@test.com', '13800138001', 'pwd001'),
    ('user002', 'user002@test.com', '13800138002', 'pwd002'),
    ('user003', 'user003@test.com', '13800138003', 'pwd003');

-- 插入商品
INSERT INTO products (name, description, price, stock) VALUES 
    ('iPhone 15', '苹果最新手机', 5999.00, 100),
    ('MacBook Pro', '苹果笔记本电脑', 14999.00, 50),
    ('AirPods Pro', '无线耳机', 1999.00, 200);

-- 插入订单
INSERT INTO orders (order_no, user_id, total_amount, status) VALUES 
    ('ORDER202401010001', 1, 5999.00, 1),
    ('ORDER202401010002', 1, 1999.00, 0),
    ('ORDER202401010003', 2, 14999.00, 2);

-- 插入订单明细
INSERT INTO order_items (order_id, product_id, product_name, price, quantity, subtotal) VALUES 
    (1, 1, 'iPhone 15', 5999.00, 1, 5999.00),
    (2, 3, 'AirPods Pro', 1999.00, 1, 1999.00),
    (3, 2, 'MacBook Pro', 14999.00, 1, 14999.00);

六、踩坑提醒

6.1 UPDATE忘记WHERE的悲剧

真实案例: 某运营人员执行了以下SQL:

sql 复制代码
-- 本意:只禁用某个违规用户
UPDATE users SET status = 0;
-- 结果:所有用户都被禁用了!网站瘫痪!

防范措施:

  1. 执行UPDATE前先用SELECT确认
  2. 使用 SET sql_safe_updates = 1; 开启安全模式
  3. UPDATE必须带WHERE条件
sql 复制代码
-- 开启安全更新模式
SET sql_safe_updates = 1;

-- 此时执行无WHERE的UPDATE会报错
UPDATE users SET status = 0;
-- ERROR 1175 (HY000): You are using safe update mode...

6.2 DELETE忘记WHERE的悲剧

sql 复制代码
-- 本意:删除测试数据
DELETE FROM orders;
-- 结果:所有订单都没了!

防范措施:

  1. 先用SELECT确认要删除的数据
  2. 使用事务,删除前可以回滚
  3. 重要数据先备份
sql 复制代码
-- 安全的删除流程
START TRANSACTION;
SELECT * FROM orders WHERE status = 4;  -- 确认要删除的已取消订单
DELETE FROM orders WHERE status = 4;
-- 确认无误后提交
COMMIT;
-- 如果有问题回滚
-- ROLLBACK;

七、面试高频考点

考点1:DELETE和TRUNCATE的区别?

答案:

  1. DELETE是DML语句,TRUNCATE是DDL语句
  2. DELETE可以带WHERE条件删除部分数据,TRUNCATE只能清空全部
  3. DELETE逐行删除,记录日志,可以回滚;TRUNCATE直接删除表重建,速度快,不可回滚
  4. DELETE会触发表上的触发器,TRUNCATE不会
  5. DELETE保留自增计数,TRUNCATE重置自增计数

考点2:DROP和DELETE的区别?

答案:

  • DROP是DDL语句,删除整个表(结构和数据)
  • DELETE是DML语句,只删除数据,保留表结构
  • DROP不可回滚,DELETE在事务中可以回滚

考点3:INSERT的几种写法?

答案:

  1. INSERT INTO table (cols) VALUES (...) - 标准插入
  2. INSERT INTO table VALUES (...) - 省略列名(不推荐)
  3. INSERT INTO table SET col1=val1, col2=val2 - SET语法
  4. INSERT INTO table SELECT ... - 从其他表插入
  5. INSERT ... ON DUPLICATE KEY UPDATE - 存在更新,不存在插入

考点4:如何防止UPDATE/DELETE误操作?

答案:

  1. 开启sql_safe_updates安全模式
  2. 执行前先SELECT确认
  3. 使用事务,先执行后确认再提交
  4. 重要操作先在测试环境验证
  5. 定期备份数据

八、总结

今天我们学习了:

  1. DDL语句:CREATE/DROP/ALTER操作数据库和表结构
  2. DML语句:INSERT/UPDATE/DELETE操作数据
  3. DQL语句:SELECT基础查询
  4. 实战:创建了电商系统的核心表

核心要点:

  • 创建表要设置utf8mb4字符集
  • UPDATE/DELETE必须带WHERE条件
  • SELECT不要直接用*,指定需要的列
  • 重要操作前先备份,使用事务保护

九、下一步预告

Day4:MySQL条件查询与排序

我们将学习:

  • WHERE子句的各种条件写法
  • NULL值的处理
  • ORDER BY排序技巧
  • LIMIT分页实现
  • 电商系统的各种查询场景

十、参考资料

  1. MySQL 8.0官方文档 - SQL语句
  2. SQL必知必会(第5版)
  3. MySQL是怎样运行的:从根儿上理解MySQL

互动话题

  1. 你在工作中有没有遇到过UPDATE/DELETE忘记WHERE的惊险时刻?后来怎么解决的?
  2. 你们公司的数据库表设计规范有哪些?欢迎在评论区分享!
  3. 对于电商系统的表设计,你有什么优化建议?

如果觉得有帮助,请点赞+收藏+关注!我们Day4见!

相关推荐
XS0301063 小时前
MyBatis动态SQL
数据库·sql·mybatis
MandalaO_O3 小时前
MyBatis 与 MySQL 执行流程
数据库·mysql·mybatis
老毛肚4 小时前
Spring boot 特性和自写Reids组件
java·spring boot·后端
蝎子莱莱爱打怪4 小时前
👍🏻👍🏻6年381颗芯片+韬定律,华为重新定义半导体,为什么还有人喷???
后端·面试·程序员
武子康4 小时前
Java-05 深入浅出 MyBatis动态SQL与参数拼接完全指南
java·spring boot·后端
l1t5 小时前
DeepSeek总结的将 Rust Delta Kernel 集成到 ClickHouse
数据库·clickhouse·rust
qq_283720055 小时前
万字深度:Chroma 向量数据库全解析 — 核心原理、实战操作、性能优化与工程最佳实践
数据库·性能优化
Kir1to5 小时前
RabbitMQ消息可靠性三板斧
后端
ServBay5 小时前
Google I/O 2026 Antigravity 更新与 SDK
后端·ai编程·google io