别再碎片化学 MySQL!DDL + 数据类型 + JSON 一篇讲透
📅 2026/8/2 7:08:13
👁️ 阅读次数
📝 编程学习
目录
DDL概述
DDL的核心操作
DDL与DML的本质区别
数据库层面的DDL操作
1.创建数据库(CREATE DATABASE)
2.查看数据库
3.修改数据库(ALTER DATABASE)
4.删除数据库(DROP DATABASE)
数据类型详解(DDL的基础)
1.数据类型
2字符串类型
3.日期时间类型
4.枚举与集合类型
5.Json类型(Mysql 8.0增强)
表层面的DDL操作
1.创建表(CREATE TABLE)
2.查看表结构
3.复制表结构
4.修改表结构(ALTER TABLE)
添加列(ADD COLUMN)
修改列(MODIFY/CHANGE)
删除列(DROP COLUMN)
5.修改表名(RENAME)
修改表的字符集/引擎
删除表(DROP TABLE)
DDL概述
DDL(Data Definition language,数据定义语言)用于定义和管理数据库中的所有对象,包括:
- 数据库 Database
- 表 Table
- 索引 Index
- 视图 View
- 存储过程 Procedure
- 触发器 Trigger
- 用户 User
DDL的核心操作
| 操作关键字 | 英文全称 | 中文含义 |
| CREATE | Create | 创建 |
| ALTER | Alter | 修改 |
| DROP | Drop | 删除(整表/整库) |
| TRUNCATE | Truncate | 清空(删除所有数据,保留结构) |
| RENAME | Rename | 重命名 |
DDL与DML的本质区别
| 对比项 | DDL | DML |
| 操作对象 | 数据库结构(库,表,索引等) | 数据本身(行记录) |
| 典型命令 | CREATE,ALTER,DROP | INSERT,UPDATE,DELETE,SELECT |
| 事务支持 | Mysql 8.0+部分DDL支持事务(原子DDL) | 支持事务 |
| 是否可回滚 | Mysql 8.0+大部分可回滚 | 可回滚 |
| 执行速度 | 通常较快 | 取决于数据量 |
⚠️ Mysql 8.0 重要特性:原子DDL(Atomi DDL)
- DDL操作要么完全成功,要么完全回滚
- 例如: DROP TABLE t1,t2 如果t2不存在,t1也不会被删除
- 之前的版本中,t1会被删除,t2报错,导致不一致
数据库层面的DDL操作
1.创建数据库(CREATE DATABASE)
完整语法:
CREATE DATABASE [IF NOT EXISTS] 数据库名 [CHARACTER SET 字符集] [COLLATE 排序规则];示例:
-- 最简方式 (使用默认字符集 utf8mb4) CREATE DATABASE school; --指定字符集和排序规则(推荐方式) CREATE DATABASE school CHARACTER SET utfmb4 COLLATE utf8mb4_unicode_ci; --避免重复报错(安全创建) CREATE DATABASE IF NOT EXISTS school CHARACTER SET utfmb4 COLLATE utf8mb4_unicode_ci; --查看创建语句 SHOW CREATE DATABASE school;2.查看数据库
--查看所有数据库 SHOW DATABASES; --查看数据库的创建信息 SHOW CREATE DATABASE school; --查看当前所在数据库 SELECT DATABASE(); --切换数据库 USE school;3.修改数据库(ALTER DATABASE)
--修改数据库字符集 ALTER DATABASE school CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; --注意:Mysql 8.0不支持直接命名数据库(需通过其他方式) --错误示例: RENAME DATABASE old_name TO new_name; -- Mysql 8.0不支持4.删除数据库(DROP DATABASE)
--删除数据库(谨慎操作) DROP DATABASE school; --安全删除(避免报错) DROP DATABASE IF EXISTS school; --删除后查看 SHOW DATABASES;⚠️警告:DROP DATABASE 会永久删除所有数据,无法恢复(除非有备份)。生产环境必须谨慎
数据类型详解(DDL的基础)
1.数据类型
| 数据类型 | 存储大小(字节) | 有符号范围 | 无符号范围 | 用途 |
| TINYINT | 1 | -128~127 | 0~255 | 年龄,状态码 |
| SMALLINT | 2 | -32768~32767 | 0~65535 | 小范围统计 |
| MEDIUMINT | 3 | ~8388608~8388607 | 0~16777215 | 中等范围 |
| INT/INTEGER | 4 | -21亿~21亿 | 0~42亿 | 主键ID(常用) |
| BIGINT | 8 | -9.22e18~9.22e18 | 0~1.84e19 | 大型系统ID |
| FLOAT | 4 | 约7位小数精度 | - | 科学计算 |
| DOUBLE | 8 | 约15位小数精度 | - | 高精度科学计算 |
| DECIMAL(M,D) | 可变 | 精确小数 | - | 金额,财务数据 |
选择建议:
-- 年龄用TINYINT UNSIGNED age TINYINT UNSIGNED -- 主键用 INT UNSIGNED 或 BIGINT id INT UNSIGNED AUTO_INCREMENT -- 金额必须用Decimal(避免精度丢失) price DECIMAL(10,2) -- 总位数10,小数2位 --状态码用TINYINT status TINYINT DEFAULT 1 -- 1 = 启用,0 = 禁用2字符串类型
| 数据类型 | 最大长度 | 存储方式 | 用途 |
| CHAR(M) | 0~255字符 | 固定长度 | 身份证号,手机号 |
| VARCHAR(M) | 0~65535字节(约16383字符) | 可变长度+1~2字前缀 | 用户名,标题,描述 |
| TINYTEXT | 255字节 | 可变 | 短文本 |
| TEXT | 65535字节 | 可变 | 文章内容,评论 |
| MEDIUMTEXT | 16777215字节(约16MB) | 可变 | 较大文本 |
| LONGTEXT | 4294967295字节(约4GB) | 可变 | 超大文本 |
| BLOB | 65535字节 | 可变 | 二进制数据(图片,文件) |
CHAR vs VARCHAR 对比:
| 对比项 | CHAR | VARCHAR |
| 长度定义 | 固定长度(最大255) | 可变长度(最大65535字节) |
| 存储空间 | 总是分配定义长度 | 按实际长度 + 额外字节 |
| 性能 | 读取速度快 | 读取速度稍慢 |
| 适用场景 | 长度固定的数据 | 长度变化的数据 |
-- 正确使用示例 phone CHAR(11) NOT NULL --手机号固定11位 id_card CHAR(18) NOT NULL -- 身份证固定18位 username VARCHAR(30) NOT NULL --用户名长度不固定 email VARCHAR(100) NOT NULL -- 邮箱长度变化 content TEXT -- 文章内容较长3.日期时间类型
| 数据类型 | 格式 | 范围 | 存储大小 | 用途 |
| DATE | YYYY-MM-DD | 1000-01-01~9999-12-31 | 3字节 | 生日,入职日期 |
| TIME | HH:MM:SS | -838:59:59~838:59:59 | 3字节 | 时间段,时长 |
| DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 8字节 | 事件时间,创建时间 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01~2038-01-19 03:14:07 | 4字节 | 自动更新时间戳 |
| YEAR | YYYY | 1901~2155 | 1字节 | 年份统计 |
DATETIME vs TIMESTAMP 核心区别
| 对比项 | DATETIME | TIMESTAMP |
| 时区支持 | ❌不支持(存什么就是什么) | ✅支持(自动转换时区) |
| 存储大小 | 8字节 | 4字节 |
| 范围 | 更大(1000~9999年) | 较小(1970~2038年) |
| 自动更新 | 需手动设置 | 支持 CURRENT_TIMESTAMP |
-- 实际应用示例 birthday DATE NOT NULL, --只需要日期 created_at DATETIME DEFAULT CURRENT_TIMESTAMP, --创建时间 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, --更新时间(自动更新) start_time TIME, --时间段 enroll_year YEAR --入学年份4.枚举与集合类型
-- ENUM(枚举): 只能从列表中选一个值 gender ENUM('男','女','保密') DEFAULT '保密', level ENUM('初级','中级','高级') DEFAULT '初级', -- SET(集合):可以从列表中选择多个值 hobby SET('篮球','足球','音乐','阅读') DEFAULT '阅读', -- 插入示例 INSERT INTO users (gender,hobbt) VALUES ('男','篮球,音乐');⚠️注意:ENUM和SET 虽然方便,但扩展性差,修改需要ALTER TABLE,建议用外键关键字关联字典替代
5.Json类型(Mysql 8.0增强)
-- 创建包含JSON字段的表 CREATE TABLE orders( id INT PRIMARY KEY AUTO_INCREMENT, order_data JSON, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); --插入JSON数据 INSERT INTO orders(order_data) VALUES{ '{"customer":"张三", "items":[ {"name":"手机","price":2999}, {"name":"耳机","price":199} ], "total":3198}' ); --查询JSON字段 SELECT id, JSON_EXTRACT(order_data,'$.customer') AS customer, JSON_EXTRACT(order_data,'$.total') AS total FROM orders; -- Mysql 8.0简写方式(适用 -> 操作符) SELECT id, order_data ->>'$.customer' AS customer, order_data ->'$.total' AS total FROM orders; -- 条件查询JSON字段 SELECT * FROM orders; WHERE JSON_CONTAINS(orders_data->'$.items[*].name','"手机"');表层面的DDL操作
1.创建表(CREATE TABLE)
CREATE TABLE [IF NOT EXISTS] 表名( 列名1 数据类型 [约束] [默认值] [注释], 列名2 数据类型 [约束] [默认值] [注释], ... [表级约束], [索引定义] ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci [注释];实战示例:创建完整的学生表
CREATE TABLE IF NOT EXISTS students( --主键列 id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', --基本信息 student_no CHAR(10) NOT NULL UNIQUE COMMENT '学号(固定10位)', name VARCHAR(50) NOT NULL COMMENT '姓名', gender ENUM('男','女','保密') DEFAULT '保密' COMMENT '性别', age TINYINT UNSIGNED COMMENT '年龄', birthday DATE COMMENT '出生日期', --联系方式 phone CHAR(11) COMMENT '手机号', email VARCHAR(100) UNIQUE COMMENT '邮箱', --地址信息 province VARCHAR(30) COMMENT '省份', city VARCHAR(30) COMMENT '城市', address VARCHAR(200) COMMENT '详细地址', --状态与时间 status TINYINT DEFAULT 1 COMMENT '状态:1-在读 2-休学 3-毕业 0-退学', created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', --索引定义 INDEX idx_name(name), INDEX idx_age(age), INDEX idx_status(status) )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='学生信息表';2.查看表结构
-- 查看所有表 SHOW TABLES -- 查看表结构(三种方式) DESC students; --简单结构 DESCRIBE students; --万完整写法 SHOW COLUMNS FROM students; --详细信息3.复制表结构
-- 方式1:复制表结构(不包含数据) CREATE TABLE student_bak LIKE students; -- 方式2:复制表结构 + 数据 CREATE TABLE students_copy AS SELECT * FROM students; -- 方式3:仅复制部分字段和数据结构 WHERE 1=0 表示不复制数据 CREATE TABLE students_simple AS SELECT id, name, age FROM students WHERE 1=0;4.修改表结构(ALTER TABLE)
添加列(ADD COLUMN)
-- 在末尾添加列 ALTER TABLE students ADD COLUMN wechat VARCHAR(30) COMMENT '微信号'; -- 在指定位置添加列 ALTER TABLE students ADD COLUMN nickname VARCHAR(50) AFTER name; ALTER TABLE students ADD COLUMN class_id INT FIRST; -- 添加到最前面 -- 一次性添加多列 ALTER TABLE students ADD COLUMN height DECIMAL(5,2) COMMENT '身高(cm)', ADD COLUMN weight DECIMAL(5,2) COMMENT '体重(kg)' ;修改列(MODIFY/CHANGE)
-- MODIFY 修改列的类型 默认值 注释(不修改列名) ALTER TABLE students MODIFY age TINYINT UNSIGNED DEFAULT 18 COMMENT '年龄'; -- CHANGE 修改列名 类型 默认值 注释(可以改名) ALTER TABLE students CHANGE gender sex ENUM('男','女','保密') DEFAULT '保密'; -- 修改列的位置 ALTER TABLE stduents MODIFY email VARCHAR(100) AFTER phone;删除列(DROP COLUMN)
-- 删除单个列 ALTER TABLE students DROP COLUMN wechat; -- 删除多个列 ALTER TABLE students DROP COLUMN height, DROP COLUMN weight;5.修改表名(RENAME)
-- 重命名表 ALTER TABLE students RENAME TO students_info; -- 或 RENAME TABLE student_info TO students; -- 重命名多个表(批量) RENAME TABLE old_table1 TO new_table1, old_table2 TO new_total2;修改表的字符集/引擎
-- 修改字符集和排序规则 ALTER TABLE students CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 只修改默认字符集(不改已有数据) ALTER TABLE students DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 修改存储引擎 ALTER TABLE students ENGINE=InnoDB;删除表(DROP TABLE)
-- 删除单个表 DROP TABLE student_bak; -- 安全删除(避免报错) DROP TABLE IF EXISTS student_bak; -- 删除多个表 DROP TABLE IF EXISTS temp1, temp2, temp3; -- 删除表并重新创建(清空数据并重置自增) TRUNCATE TABLE students; -- 与DROP + CREATE等效
编程学习
技术分享
实战经验