1.DDL(数据定义语言)

数据定义语言(Data Definition Language,简称 DDL)主要用于定义或修改数据库的结构,包括数据库、表、视图、索引等。它是我们构建数据库大厦的"设计图纸"和"骨架"。


🔰 SQL 基础入门常识(新手必读)

作为 SQL 的初学者,在编写任何 SQL 代码之前,请牢记以下几条铁律:

  1. 三种注释的写法
    • # 注释内容:单行注释(MySQL 特有方式,推荐日常使用)。
    • -- 注释内容:单行注释(标准 SQL 方式,注意 -- 后面必须有一个空格!,否则会报错)。
    • /* 注释内容 */:多行注释,适合写长篇大论或场景说明。
  2. 大小写规范
    • SQL 关键字(如 CREATETABLEINT)在数据库中不区分大小写
    • 行业推荐规范:关键字一律大写,库名、表名、列名等自定义名称一律小写,这样代码可读性极高。
  3. 语句结束符
    • 每一条完整的 SQL 语句都建议以英文分号 ; 结尾,以此告诉 MySQL 这一条指令结束了。
  4. 反单引号 (`````) 的妙用
    • 键盘 Tab 键上方的那个键 `````(反单引号)。如果在命名时,你的表名或列名不幸和 MySQL 的系统关键字冲突了(比如你想建一个叫 create 的表),可以用反单引号包裹起来:CREATE TABLE `create` ( ... );
  5. DDL 的"破坏性"
    • DDL 操作(如 DROP 删除、TRUNCATE 清空)直接作用于物理文件,默认是无法撤销(回滚)的。在生产环境中执行此类操作前,请务必反复确认!

1. DDL之数据库操作

1.1 数据库创建

创建数据库的核心语法如下:

  • 基础创建

    sql 复制代码
    CREATE DATABASE 数据库名;
  • 安全创建 (推荐!防止因为同名库已存在而导致程序运行报错中断):

    sql 复制代码
    CREATE DATABASE IF NOT EXISTS 数据库名;
  • 指定字符集 (建议使用 utf8mb4,支持存储 Emoji 表情和更多生僻字):

    sql 复制代码
    CREATE DATABASE 数据库名 CHARACTER SET utf8mb4;
  • 指定排序规则 (排序规则决定了字符比较和排序时的逻辑,如是否区分大小写):

    sql 复制代码
    CREATE DATABASE 数据库名 COLLATE utf8mb4_0900_ai_ci;
  • 同时指定字符集与排序规则

    sql 复制代码
    CREATE DATABASE 数据库名 CHARACTER SET 字符集 COLLATE 排序方式;

!NOTE\] **MySQL 8.0 默认字符集与排序规则**: * 字符集:`utf8mb4` * 排序规则:`utf8mb4_0900_ai_ci`(`ai` 代表 Accent Insensitive 区分重音,`ci` 代表 Case Insensitive **不区分大小写**)

查询当前数据库默认的字符集与排序规则

sql 复制代码
-- 查看当前数据库字符集配置
SHOW VARIABLES LIKE 'character_set_database';
-- 查看当前数据库排序规则配置
SHOW VARIABLES LIKE 'collation_database';

✍️ 示例与练习

创建名为 ddl_d1 的数据库,指定字符集为 utf8mb4,且排序规则使用大小写敏感(Case Sensitive,末尾是 cs)的 utf8mb4_0900_as_cs 模式:

sql 复制代码
-- as: Accent Sensitive (区分重音), cs: Case Sensitive (区分大小写)
CREATE DATABASE IF NOT EXISTS ddl_d1 CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;

1.2 数据库查看与管理

以下是常用的数据库查询与切换指令,建议逐行执行观察效果:

sql 复制代码
-- 1. 查看当前连接的 MySQL 服务器中所有的数据库
SHOW DATABASES;

-- 2. 查看当前正在使用的是哪一个数据库(若未选中任何库,会返回 NULL)
SELECT DATABASE();

-- 3. 选中或切换到指定的数据库(在对表进行增删改查前,**必须**先选中库!)
USE mysql;

-- 4. 在不切换当前数据库的前提下,查看指定数据库(如 mysql 库)下的所有表
SHOW TABLES FROM mysql;

-- 5. 查看创建某个数据库(如 ddl_d1)时的详细建库 SQL 语句和配置
SHOW CREATE DATABASE ddl_d1;

1.3 数据库修改

主要用于修改数据库的字符集或排序规则。

  • 修改字符集与排序方式

    sql 复制代码
    ALTER DATABASE 数据库名 CHARACTER SET 字符集 COLLATE 排序方式;

!WARNING\] **新手避坑** :MySQL 中**没有任何直接修改数据库名称**的指令(如 rename database)。如果你想改库名,正确做法是: 1. 导出/备份原数据库内的数据(使用 mysqldump 等工具)。 2. 删除旧数据库(`DROP DATABASE 旧库名;`)。 3. 创建新名字的数据库。 4. 将数据导入/恢复到新库中。


1.4 数据库删除

  • 直接删除 (不推荐,库不存在会报错):

    sql 复制代码
    DROP DATABASE 数据库名;
  • 安全删除 (推荐,如果存在才删除,不存在也不报错):

    sql 复制代码
    DROP DATABASE IF EXISTS 数据库名;

1.5 数据库管理综合实战

场景模拟

  1. 创建多语言博客平台数据库 blog_platform,采用 utf8mb4 字符集。
  2. 切换到该库,查看其默认字符集和排序规则。
  3. 修改排序规则为大小写敏感的 utf8mb4_0900_as_cs
  4. 模拟项目废弃,安全删除数据库。
sql 复制代码
-- 1. 创建数据库(如果不存在则创建,并指定字符集)
CREATE DATABASE IF NOT EXISTS blog_platform CHARACTER SET utf8mb4;

-- 2. 切换至该库
USE blog_platform;

-- 查看字符集和排序规则参数
SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'collation_database';

-- 3. 修改排序规则为大小写敏感模式
ALTER DATABASE blog_platform COLLATE utf8mb4_0900_as_cs;

-- 4. 模拟跑路删除项目库
DROP DATABASE IF EXISTS blog_platform;

-- 查看所有数据库,验证是否已成功删除
SHOW DATABASES;

2. DDL之数据表操作

2.1 建表语法与规范

sql 复制代码
CREATE TABLE [IF NOT EXISTS] 表名 (
    列名1 数据类型 [列约束] [COMMENT '列注释'],
    列名2 数据类型 [列约束] [COMMENT '列注释'],
    ...
    列名N 数据类型 [列约束] [COMMENT '列注释']
) [ENGINE=存储引擎] [CHARSET=字符集] [COMMENT='表注释'];

💡 核心建表规范(新手必读):

  1. 最后一列千万不能有逗号。SQL 的列定义之间是用逗号分隔的,如果在最后一列的括号前加了逗号,MySQL 会报错。
  2. 列注释与表注释 :通过 COMMENT 关键字添加,这是极佳的职业习惯,能极大提高后续维护的体验。
  3. 表名与列名 :要做到"见名知意",尽量避免使用拼音,推荐使用英文下划线命名法(如 user_info)。

2.2 建表实战练习

场景模拟 : 为图书管理系统创建数据库 book_libs,并在其中创建图书表 books

sql 复制代码
-- 创建并切换到数据库
CREATE DATABASE IF NOT EXISTS book_libs CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;
USE book_libs;

-- 创建图书表
CREATE TABLE IF NOT EXISTS books (
    book_name VARCHAR(20) COMMENT '图书名',
    book_price DOUBLE(4,1) COMMENT '图书价格,格式为最大4位数且含1位小数',
    book_num INT COMMENT '图书数量'
) CHARSET = utf8mb4 COMMENT '图书表';

-- 验证表是否创建成功
SHOW TABLES FROM book_libs;

2.3 常用数据类型解析与避坑指南

选择数据类型时,应遵循**"够用就行,空间越小越好"**的原则,能有效提升数据库的查询性能和节约磁盘空间。

① 整数类型

类型 占用空间 无符号范围 (UNSIGNED) 有符号范围 (SIGNED) 适用场景
TINYINT 1 字节 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 ∼ 255 0 \sim 255 </math>0∼255 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 128 ∼ 127 -128 \sim 127 </math>−128∼127 极小整数,如:年龄、性别代号、是否删除等
SMALLINT 2 字节 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 ∼ 65 , 535 0 \sim 65,535 </math>0∼65,535 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 32 , 768 ∼ 32 , 767 -32,768 \sim 32,767 </math>−32,768∼32,767 较小整数,如:省份代码、年份等
MEDIUMINT 3 字节 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 ∼ 16 , 777 , 215 0 \sim 16,777,215 </math>0∼16,777,215 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 8 , 388 , 608 ∼ 8 , 388 , 607 -8,388,608 \sim 8,388,607 </math>−8,388,608∼8,388,607 中等范围整数
INT / INTEGER 4 字节 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 ∼ 约 42.9 亿 0 \sim约 42.9亿 </math>0∼约42.9亿 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 21.4 亿 ∼ 21.4 亿 -21.4亿 \sim 21.4亿 </math>−21.4亿∼21.4亿 常用标准整数,如:用户ID、点击量
BIGINT 8 字节 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 ∼ 超大数字 0 \sim超大数字 </math>0∼超大数字 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 2 63 ∼ 2 63 − 1 -2^{63} \sim 2^{63}-1 </math>−263∼263−1 极大整数,如:主键雪花ID、学号、手机号

!TIP\] **有符号 (SIGNED) 与 无符号 (UNSIGNED) 的区别**: * 默认情况下,所有整数列都是**有符号**的(即允许存储负数)。 * 如果确定该列的数据绝对不会有负数(例如:年龄、身高、主键ID),必须声明为 `UNSIGNED`。这样不仅能防止输入负数报错,还能将正数的最大范围扩大一倍!

整数表创建示例:
sql 复制代码
CREATE TABLE t1_integer_demo (
   -- tinyint unsigned 刚好适合年龄(0~255岁)
   t1_age TINYINT UNSIGNED COMMENT '年龄,无符号',
   -- bigint unsigned 适合极大的学号
   t1_number BIGINT UNSIGNED COMMENT '学号,无符号且防超范围'
);

② 浮点数与定点数类型

类型 占用空间 语法格式 核心特点与新手避坑指南
FLOAT 4 字节 FLOAT(M, D) 单精度浮点数,存在计算精度丢失。适合身高、体重等不要求极高精度的场景。
DOUBLE 8 字节 DOUBLE(M, D) 双精度浮点数,存在计算精度丢失。适合一般非金融类的科学计算。
DECIMAL 动态占用 DECIMAL(M, D) 定点数,高精度绝不丢失 !金融级数据类型,凡是涉及钱、工资、价格的,必须用它

!NOTE\] **什么是 `(M, D)` 限制?** * `M` 代表 **总有效位数**(最大 65 位)。 * `D` 代表 **小数点后的保留位数**(最大 30 位)。 * 举例:`DOUBLE(4, 1)` 表示总共最多允许输入 4 位数,其中 1 位是小数。例如:`999.9` 可以存,而 `1000.0` 和 `99.99` 就会报错。


③ 字符串类型

类型 物理占用 特点与新手选择建议
CHAR(M) 固定分配 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M 字符空间 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M 最大 255。如果存入数据长度不足 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M,会在右侧自动补空格,读取时再自动剥离空格。查询性能极佳,适合长度固定的字段(如:性别、身份证号、MD5密码、手机号)。
VARCHAR(M) 动态按实际长度分配 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M 代表最大字符限制。存入多少就占用多少空间,但需要额外 1~2 字节存储长度。性能略低于 CHAR,适合长度经常变化的字段(如:姓名、邮箱、地址)。
TEXT 独立存储,不占整行限制 存放文章、大段评论或正文描述。千万不要指定长度。由于它保存在行外,所以不会占用整行最多 65,535 字节的物理上限。
💡 字符串深度避坑:MySQL 的"行字节限制"
  • MySQL 规定:表中除了 TEXT / BLOB 类型的列外,所有其他列的字节大小总和不能超过 65,535 字节
  • utf8mb4 字符集下,1 个字符最多会占用 4 个字节
  • 如果你试图创建一列 VARCHAR(16000) 和一列 VARCHAR(2000),就会发生: <math xmlns="http://www.w3.org/1998/Math/MathML"> ( 16000 + 2000 ) × 4 (16000 + 2000) \times 4 </math>(16000+2000)×4 字节 <math xmlns="http://www.w3.org/1998/Math/MathML"> = 72 , 000 = 72,000 </math>=72,000 字节,远远超过 65,535 字节,此时数据库将拒绝建表并报错!
  • 解决方案 :将超长字符串字段的数据类型改为 TEXT,或者缩小字符数限制 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M。
sql 复制代码
-- 演示案例
CREATE TABLE t1_varchar_limit_demo (
   name1 VARCHAR(16000), -- 接近单行字节极限的 VARCHAR
   name2 TEXT            -- 超长文本交给 TEXT 类型,安全不受整行大小限制
) CHARSET=utf8mb4;

④ 时间类型

类型 占用空间 格式 默认行为与说明
YEAR 1 字节 YYYY 存储年份。虽然支持两位缩写,但强烈建议存四位年份防混淆。
TIME 3 字节 HH:MM:SS 只存时间,不存日期。
DATE 3 字节 YYYY-MM-DD 只存日期,不存具体时间。适合记录:生日、入职日期。
DATETIME 8 字节 YYYY-MM-DD HH:MM:SS 最通用的日期时间类型,可存储至 9999 年,且不受时区变化影响。
TIMESTAMP 4 字节 YYYY-MM-DD HH:MM:SS 时间戳,受系统时区影响(会随数据库时区切换自动转换显示)。缺点是 2038 年会溢出。
🚀 核心黑科技:自动维护"创建时间"与"更新时间"

在实际开发中,几乎每张表都需要记录"这条数据是什么时候被写进去的"、"最后一次修改是在什么时候"。通过以下方式,MySQL 会自动帮我们维护这些时间,完全不需要我们手动传入:

sql 复制代码
CREATE TABLE t2_auto_time_demo (
  name1 VARCHAR(20) COMMENT '用户名',
  -- 插入新数据时,MySQL 自动获取当前系统时间写入,后续更新这条数据时该时间保持不变
  reg_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '注册日期(自动生成,不变)',
  -- 插入新数据时自动写入当前时间;当这条数据被 UPDATE 修改时,MySQL 自动将其翻新为最新修改时间
  up_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间(自动维护,动态变动)'
);

2.4 学生借书信息表建表实战

结合上述所有知识点,我们编写一个符合规范的学生登记表:

sql 复制代码
CREATE TABLE student (
  stu_name VARCHAR(20) COMMENT '学生姓名,用 VARCHAR 弹性存储',
  stu_sex CHAR(1) COMMENT '学生性别,使用 CHAR(1) 固定存储单字',
  stu_age TINYINT UNSIGNED COMMENT '学生年龄,无负数且范围 0-255 足够用',
  stu_height DOUBLE(4,1) COMMENT '学生身高,形如 175.5 即可',
  stu_birthday DATE COMMENT '学生生日,只需要年月日即可,选择 DATE',
  stu_regtime DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '首次注册登记时间',
  stu_uptime DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '学生信息最后修改更新时间'
) CHARSET = utf8mb4 COMMENT '学生借阅登记表';

2.5 修改与删除表结构语法

对表结构的修改统称为 ALTER TABLE,这是新手经常觉得难记的部分。请仔细对比下述语法的核心变化:

① 修改表中的列

  • 添加新列

    sql 复制代码
    -- FIRST 表示加在表的最前面;AFTER 字段名 表示加在指定列后面。不加则默认拼在最后
    ALTER TABLE 表名 ADD 列名 类型 [FIRST | AFTER 某列名];
  • 修改列名与类型CHANGE 既可以改名也可以改类型,必须写齐"新旧两个列名"):

    sql 复制代码
    ALTER TABLE 表名 CHANGE 原列名 新列名 新类型 [FIRST | AFTER 某列名];
  • 修改列类型/位置MODIFY 只能修改类型或位置,不能改列名。写一个列名即可):

    sql 复制代码
    ALTER TABLE 表名 MODIFY 列名 新类型 [FIRST | AFTER 某列名];
  • 删除列

    sql 复制代码
    ALTER TABLE 表名 DROP 列名;

!NOTE\] **💡 教材/资料排雷** : 在某些教材中可能由于笔误,添加/修改列的语法写为了 `[FIRST | ALTER 列名]`。请注意,**SQL 中绝对没有 `ALTER 列名` 这种用法** !正确的字段排序关键字是 `AFTER 某列名`(置于某字段之后)或 `FIRST`(置于表头第一列)。

② 修改表名

sql 复制代码
ALTER TABLE 表名 RENAME [TO] 新表名;

③ 删除与清空表

  • 删除整个表 (物理删除,表结构和数据一起灰飞烟灭):

    sql 复制代码
    DROP TABLE IF EXISTS 表名;
  • 截断表/清空表数据超级实用 !瞬间清空表中所有数据,但完好地保留空表结构):

    sql 复制代码
    TRUNCATE TABLE 表名;

2.6 表操作综合实战

场景模拟: 根据要求对员工表进行多次结构升级,体验真实开发中的 DDL 操作。

sql 复制代码
-- 1. 建立初始员工表(表名拼错为 employeess)
CREATE TABLE employeess (
   emp_num INT COMMENT '员工工号',
   last_name VARCHAR(50) COMMENT '姓',
   first_name VARCHAR(50) COMMENT '名',
   mobile VARCHAR(25) COMMENT '手机号',
   code INT COMMENT '编号',
   job_time VARCHAR(50) COMMENT '入职日期',
   birth DATE COMMENT '生日',
   note VARCHAR(255) COMMENT '备注信息',
   sex VARCHAR(5) COMMENT '性别'
) CHARSET=utf8mb4 COMMENT='初始员工表';

-- 2. 将 mobile 字段的位置调整到 code 字段后面
ALTER TABLE employeess MODIFY mobile VARCHAR(25) AFTER code;

-- 3. 将 birth 字段重命名为 birthday,数据类型保持 DATE 不变
ALTER TABLE employeess CHANGE birth birthday DATE;

-- 4. 优化 sex 字段的数据类型,由 VARCHAR(5) 缩减为更合理的定长 CHAR(1)
ALTER TABLE employeess MODIFY sex CHAR(1);

-- 5. 随着业务升级,删除不再使用的备注字段 note
ALTER TABLE employeess DROP note;

-- 6. 新增"兴趣活动"字段 favoriate_activity,长度限制 100 字符
ALTER TABLE employeess ADD favoriate_activity VARCHAR(100) COMMENT '兴趣活动';

-- 7. 纠正表名,将错误的 employeess 修改为 employees_info
ALTER TABLE employeess RENAME employees_info;

-- 8. 执行 DESC 语句,直观查看最终更新后的完美表结构
DESC employees_info;
相关推荐
她的男孩5 小时前
Spring Boot 3 后台框架的自动配置设计:少写配置,多做组合
后端
小黑蛋9125 小时前
Linux核心知识点全解01
后端
日月云棠5 小时前
5 高级配置:多注册中心与异步化编程
java·后端
她的男孩5 小时前
Maven 多模块项目如何避免越写越乱?Forge Admin 的模块边界实践
后端
日月云棠5 小时前
4 高级配置:容错策略、降级保护与流量控制
java·后端
JuiceFS7 小时前
降低数据存储成本:JuiceFS v1.4 分层存储设计解析
运维·后端
无关86887 小时前
Spring Boot 项目标准化部署打包实战
java·spring boot·后端
Qhappy7 小时前
AI逆向实战:从零还原某航空App的AES加密
javascript·后端
tonydf7 小时前
Nginx爆新的RCE漏洞!别担心,平滑升级即可。
后端·nginx