DDL:Data Deine Language数据定义语⾔,主要⽤来对数据库、表进⾏⼀些管理操作。 如:建库、删库、建表、修改表、删除表、对列的增删改等等。 ⽂中涉及到的语法⽤\[\]包含的内容属于可选项,下⾯做详细说明。
库的管理
创建库
CREATE DATABASE [IF NOT EXISTS] 库名;
IF NOT EXISTS:可选,判断库不存在才创建,防止库已存在时报错。
示例:
CREATE DATABASE IF NOT EXISTS javacode2018;
删除库
DROP DATABASE [IF EXISTS] 库名;
IF EXISTS:可选,库存在才删除;库不存在也不会报错(不加 if exists,删不存在的库会抛异常)
重建库通用写法(先删、再新建)
DROP DATABASE IF EXISTS 旧库名;
CREATE DATABASE 新库名;
作用:不管这个库有没有,先尝试删掉,再全新创建,测试场景经常用。
查看数据库
SHOW DATABASES LIKE 'javacode2018';
LIKE 'xxx':模糊匹配,查看名字为javacode2018的库- 有库:返回 1 行结果;没有库:
Empty set空结果集
图片示例执行流程拆解
-- 查看是否存在javacode2018库,查到了
show databases like 'javacode2018';
-- 如果库存在,删除它
drop database if exists javacode2018;
-- 再次查询,库已经被删除 → Empty set
show databases like 'javacode2018';
-- 创建新库javacode2018
create database javacode2018;
考点小结:
- 创建:
CREATE DATABASE [IF NOT EXISTS] 库名; - 删除:
DROP DATABASE [IF EXISTS] 库名;(database 单数!不要写 databases) IF EXISTS / IF NOT EXISTS作用:避免不存在对象时报错SHOW DATABASES LIKE '库名':查询指定名称数据库是否存在
表管理(创建表 + not null 约束)
创建表
建表语法:
create table 表名(
字段名1 类型[(宽度)] [约束条件] [comment '字段说明'],
字段名2 类型[(宽度)] [约束条件] [comment '字段说明'],
字段名3 类型[(宽度)] [约束条件] [comment '字段说明']
)[表的一些设置];
6 条注意事项(考试重点)
-
同一张表内,字段名不能重复
-
字段名、数据类型必须写;宽度、约束、注释是可选
-
最后一个字段后面不能加逗号,加了会语法报错
-
数据类型:限制这个字段存储什么格式的数据
-
数据类型本身就是一种约束,限定存入数据的类型
-
类型后面写的约束(not null、primary key 等),是额外增加的约束
约束:
not null(非空约束)
not null:标识该字段不能存入 NULL 空值,插入 / 更新时不给值就报错。
示例代码:
-- 创建test1表,字段a是int类型,非空,注释:字段a
create table test1(a int not null comment '字段a');
-- 尝试插入null,触发报错
insert into test1 values (null);
报错信息:ERROR 1048 (23000): Column 'a' cannot be null
翻译:列 a 不能为空
补充区分
not null:不允许 NULL,必须有值(可以是 0、空字符串'',但不能是 null)- 不加 not null:默认允许字段为 NULL
配套常用语句(拓展)
-- 查看表结构
desc test1;
-- 删除表
drop table if exists test1;
-- 查看建表语句
show create table test1;
考点一句话记忆
创建表时,字段名和数据类型是必填项;not null 是非空约束,添加后该字段不能存入 null,否则抛出 1048 错误。
default 默认值约束 知识点
语法说明
default value:给字段设置默认值 ,插入数据时如果不给这个字段传值,会自动填入默认值。
示例代码分步解析
-- 如果test2存在就先删除,避免报错
drop table IF EXISTS test2;
-- 创建test2表
create table test2(
a int not null comment '字段a',
b int not null default 0 comment '字段b'
);
-
字段
a:int,非空,没有默认值,插入时必须给 a 传值 -
字段
b:int,非空,默认值 0,插入不指定 b,自动填充 0-- 插入只给a赋值,没有写b
insert into test2(a) values (1);
查询结果:
select * from test2;
| a | b |
|---|---|
| 1 | 0 |
原理:插入时没有指定 b 的值,自动使用default 0默认值。
⭐考点重点
default作用:插入数据不提供该字段值,自动使用预设默认值。not null + default组合:字段不能为空,不给值就自动填充默认值,不会出现 null。- 区分:
- 有 default:插入时省略该字段,自动填默认值
- 无 default、加 not null:插入必须手动给值,否则报错
- 注意:如果手动写
insert ... values(...,null),会直接违反 not null 约束报错,default 不会生效 。default 只在不写这个字段的时候触发。
对比小例子:
-- 这个会成功,b自动取默认0
insert into test2(a) values(2);
-- 这个会报错!给b显式传入null,not null不允许
insert into test2(a,b) values(3,null);
一句话记忆
default 用来设置字段默认值,插入数据不指定该字段时,自动使用默认值;如果显式传入 null,default 不会生效。
primary key 主键约束 知识点
作用
primary key:主键,唯一标识表中一行记录。 主键自带两个特性:
- 唯一:主键字段的值不能重复,插入重复值报错
- 非空 :主键字段不能为
NULL(自带not null效果,不用额外写)
报错
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'含义:主键重复,主键里已经存在值1,不能再次插入。
两种定义主键写法
方式 1:列级定义(直接写在字段后面,适合单字段主键)
drop table IF EXISTS test3;
create table test3(
a int not null comment '字段a' primary key
);
单字段主键推荐这种写法。
插入1成功;再插1,主键重复报错。
方式 2:表级定义(所有字段写完之后定义,适合联合主键)
drop table IF EXISTS test4;
create table test4(
a int comment '字段a',
b int comment '字段b',
primary key(a,b) -- 表级定义,联合主键
);
联合主键:a+b 合在一起唯一,单独 a 可以重复、单独 b 可以重复,a 和 b 组合不能重复。
⭐考试重点
- 一张表只能有 1 个主键(但主键可以由多个字段组成 = 联合主键)
- 主键自带:唯一 + 非空 ,不需要额外加
not null - 主键作用:唯一标识一行记录
- 报错
1062 Duplicate entry:主键值重复冲突
对比小结
| 约束 | 特点 |
|---|---|
| not null | 不能为空,可以重复 |
| default | 不填值自动给默认值 |
| primary key | 唯一 + 非空,一张表只能一个主键 |
一句话记忆:主键用来唯一标识记录,不能重复、不能为空;单主键写在字段后,联合主键写在所有字段的末尾。
foreign key 外键约束 知识点
作用
foreign key(外键):用来维护两张表之间的参照完整性。
子表(从表)的外键字段的值,必须在主表(父表)被引用的字段中已经存在,否则插入报错。
语法:
foreign key(当前表的列名) references 引用的外键表(外键表中字段名称)
示例分步解析:
-- 先删表(注意:必须先删子表test6,再删主表test5,顺序不能反!)
drop table IF EXISTS test6;
drop table IF EXISTS test5;
-- 创建【主表/父表】test5,a是主键
create table test5(
a int not null comment '字段a' primary key
);
-- 创建【子表/从表】test6,ts5_a作为外键,关联test5表的a字段
create table test6(
b int not null comment '字段b',
ts5_a int not null,
foreign key(ts5_a) references test5(a)
);
-- 主表插入 1
insert into test5 (a) values (1);
-- 子表插入ts5_a=1,1在主表test5中存在 → 成功
insert into test6 (b,test6.ts5_a) values (1,1);
-- 子表插入ts5_a=2,主表test5没有2 → 报错
insert into test6 (b,test6.ts5_a) values (2,2);
报错: ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
含义:子表外键的值,在主表不存在,违反外键约束
⭐4 条注意事项(考点)
- 建立外键关联的两个字段,数据类型必须一致
- 被引用的字段(主表这边)必须是主键
- 子表外键字段的值,必须在主表被引用字段里预先存在,否则插入失败
- 建表顺序:先建主表,再建子表;删表顺序:先删子表,再删主表
考试优先记:被引用的字段必须是主键。
外键特点总结
- 主表:被引用的表,字段必须是主键
- 子表:带有 foreign key 的表
- 作用:保证数据引用有效,防止插入不存在的关联 id
- 存储引擎要求:InnoDB 才支持外键,MyISAM 不支持
一句话记忆:
外键用于关联两张表,子表外键的值必须在主表主键中存在;主表先创建,子表后创建,删除时反过来。
unique key(唯一约束)知识点
作用:
unique key(简写unique):字段的值在整张表里不能重复,支持单个字段或多个字段组合唯一;插入重复值会报错,插入失败。
区别于主键:
primary key:唯一 + 不允许 NULL,一张表只能有 1 个主键unique key:仅要求值唯一,默认允许 NULL(可以存多个 NULL),一张表可以有多个唯一约束
两种定义方式:
方式 1:列级定义(写在字段后面,适合单字段唯一)
drop table IF EXISTS test8;
create table test8(
a int not null comment '字段a' unique key
);
insert into test8(a) VALUES (1); -- 成功
insert into test8(a) VALUES (1); -- 再次插入1 → 报错1062,重复
方式 2:表级定义(所有字段写完后定义,适合多字段联合唯一)
create table test8(
a int comment '字段a',
b int comment '字段b',
unique key uk_a_b(a,b)
);
联合唯一:a+b 整体不能重复;单独 a 可以重复,单独 b 可以重复。
⭐核心考点
- 一张表可以设置多个 unique 约束,但主键只能有 1 个。
unique默认允许字段为NULL,可以有多行 NULL (NULL 不等于 NULL,不判定重复);如果加上not null,就和主键行为很像。- 插入重复值时报错:
ERROR 1062 (23000): Duplicate entry,和主键重复报错号一样。 - 语法简写:
unique key可以直接简写为unique,效果完全一样。
主键 vs 唯一约束对比(高频考题)
| 约束 | 是否唯一 | 是否允许 NULL | 一张表数量 |
|---|---|---|---|
| primary key 主键 | ✅唯一 | ❌不允许 NULL | 最多 1 个 |
| unique key 唯一约束 | ✅唯一 | ✅默认允许 NULL | 可以多个 |
一句话记忆:
unique key 保证字段值唯一,可多个;primary key 唯一且非空,一张表只能一个。
MySQL 5 大约束 汇总背诵表
| 约束 | 关键字 | 核心作用 | 特点 | 报错场景 |
|---|---|---|---|---|
| 非空约束 | NOT NULL |
字段不能为 NULL | 只是禁止空值;允许重复数据;一张表可以多个 not null | 插入NULL → 1048 Column xxx cannot be null |
| 默认值约束 | DEFAULT |
插入时不填该字段,自动填入预设默认值 | 只在省略该字段 时生效;如果手动写null,default 不会生效 |
一般不单独报错,配合 not null 才会触发非空报错 |
| 主键约束 | PRIMARY KEY |
唯一标识一行记录 | ✅唯一 ✅自带 NOT NULL;一张表只能 1 个主键(可以是多字段联合主键) | 插入重复主键值 → 1062 Duplicate entry |
| 唯一约束 | UNIQUE KEY(可简写 UNIQUE) |
字段值不能重复 | ✅唯一;默认允许 NULL,可多个 NULL;一张表可以有多个 unique | 插入重复值 → 1062 Duplicate entry |
| 外键约束 | FOREIGN KEY |
维护表与表之间参照完整性 | 子表外键的值,必须存在于主表被引用的主键;主表字段必须是主键,字段类型要一致 | 子表插入主表不存在的值 → 1452 foreign key constraint fails |
📌高频对比考点(考试常考)
- 主键 vs UNIQUE
- primary key:唯一 + 非空,一张表最多 1 个
- unique:唯一,默认允许 NULL,一张表可以多个
-
NOT NULL 和 DEFAULT 搭配
b int not null default 0
不填 b 自动填充 0;不能手动插入 null
- 外键建表 / 删表顺序
- 建表:先建主表(父表),后建子表(从表)
- 删除:先删子表,再删主表,否则外键报错
📝一句话速记
NOT NULL:不能为空,允许重复DEFAULT:不赋值自动填默认值PRIMARY KEY:唯一 + 非空,一张表只能一个UNIQUE:值唯一,允许 null,可多个FOREIGN KEY:关联两张表,子表的值必须在主表主键存在
配套练习题(自测)
- 一张表可以有几个主键?几个 unique?
- unique 字段可以存 null 吗?
- 外键引用的主表字段有什么要求?
表操作:删除表、改表名、表注释、复制表
1. 删除表
语法:
drop table [if exists] 表名;
if exists:可选。表存在才删除,不存在不会报错- 注意:如果表有外键关联,必须先删除子表,再删主表
示例:
drop table if exists test1;
2. 修改表名
语法:
alter table 表名 rename [to] 新表名;
-
to可以省略,写不写效果一样 示例:alter table test1 rename test_new;
3. 设置 / 修改表备注
alter table 表名 comment '备注信息';
示例:
alter table student comment '学生信息表';
4. 复制表
复制表两种方式 知识点:
方式 1:只复制表结构(like)
语法:
create table 新表名 like 被复制的表名;
示例:
create table test12 like test11;
-
✅ 复制:字段、数据类型、约束、主键、索引、字符集、存储引擎全部保留
-
❌ 不复制:表里面的行数据
select * from test12; -- Empty set 空表,没有数据
show create table test12; 查看建表语句,可以看到主键、注释、自增属性全部原样复制过来。
方式 2:复制表结构 + 数据(as select)
语法:
create table 新表名 [as] select 字段,... from 原表 [where 条件];
as可以省略。where可选,用来筛选部分数据复制。
示例:
-- 复制整张表所有字段+全部数据
create table test13 as select * from test11;
-- 只复制a字段,并且只复制a>10的数据
create table test14 as select a from test11 where a>10;
✅ 复制:字段名、字段类型、查询出来的数据 ❌ 不复制:主键、unique、索引、自增、注释这些约束(高频考点!)
⭐对比总结(考试必背)
表格
| 语句 | 复制表结构 | 复制数据 | 复制主键 / 索引 / 约束 |
|---|---|---|---|
create table A like B |
✅ | ❌ | ✅ |
create table A as select ... from B |
✅ | ✅ | ❌ |
一句话速记
like:抄表骨架(约束索引全保留,不带数据 ) as select:抄骨架 + 数据,但是约束索引全部丢失
补充小考点
as select可以加 where 条件,只复制原表部分数据,like 做不到筛选- 实际开发中:如果既要复制数据,又要保留约束,一般分两步:先用
like建空表,再insert into ... select导入数据
表中列的管理
添加列
语法
alter table 表名 add column 列名 类型 [列约束];
column关键字可以省略,简写:alter table 表名 add 列名 类型 [约束];
示例分步解析
-- 删除旧表
drop table IF EXISTS test14;
-- 创建test14,a为主键自增字段
create table test14(
a int not null AUTO_INCREMENT PRIMARY KEY comment '字段a'
);
-- 新增字段b:int,非空,默认值0,注释
alter table test14 add column b int not null default 0 comment '字段b';
-- 新增字段c
alter table test14 add column c int not null default 0 comment '字段c';
执行成功后,表就有 a、b、c 三个字段。
拓展(考试常考,调整字段位置)
-
after 字段名:新增字段放在某个字段后面alter table test14 add column d int after b;
-
first:新增字段放到表的最前面alter table test14 add column e int first;
不加
after/first,默认新增字段放在表最后一列。
⭐考点
alter table ... add column用于给已有表增加新字段- 添加字段时,可以同时带上:数据类型、not null、default、comment 等约束
- 默认加到末尾;可以用
after、first控制位置
修改列
modify & change 知识点
modify :只修改字段类型、约束 ,不能改字段名
alter table 表名 modify column 列名 新类型 [约束];
change :既能改字段类型、约束 ,还可以修改字段名称
alter table 表名 change column 旧列名 新列名 新类型 [约束];
column 关键字都可以省略。
✅核心区别(高频考点)
modify:不改名字,只改类型 / 约束change:可以改名,同时改类型 / 约束
⭐考试要点
change 必须写旧名 + 新名,哪怕不想改名,也要写两遍同一个名字
-- 不想改名,只用change改类型,也要写两次名字
alter table test14 change column b b varchar(20);
modify 适合只改类型约束,写法更简洁
修改字段时,原有约束如果不写,会丢失!
例:原来字段有 not null、default,modify/change 的时候如果不写,会被清除。
一句话速记:
modify 只改属性不改名;change 改名改属性都行。
删除列 drop column
语法
alter table 表名 drop column 列名;
column 可以省略,简写:
alter table 表名 drop 列名;
示例
alter table test14 drop column d;
执行后,表test14里的字段d直接被删掉,该列所有数据一并删除,不可恢复。
执行show create table test14查看表结构,只剩下字段 a、b。
⭐考点 & 注意事项
- 删除列会永久丢失该列全部数据,生产环境谨慎操作。
- 如果该字段是外键、主键,不能直接 drop,要先删除对应的约束,再删字段。
- 一张表不能把所有列全部删光,至少保留一列。
📌alter 表字段全套汇总(增 / 改 / 删)
表格
| 操作 | 语法 | 说明 |
|---|---|---|
| 添加列 | alter table 表名 add column 列名 类型 [约束]; |
新增字段,默认放末尾;可加 after/first 控制位置 |
| 修改列(不改名字) | alter table 表名 modify column 列名 新类型 [约束]; |
只改类型、约束,不能改名 |
| 修改列(可改名) | alter table 表名 change column 旧名 新名 新类型 [约束]; |
既能改名,也能改类型约束 |
| 删除列 | alter table 表名 drop column 列名; |
删除字段 + 该列全部数据 |
一句话速记:
add 加列,modify 改属性不改名,change 改名改属性,drop 删掉整列。