MySQL DDL 与 DML 数据定义与操作(完整版)

---

课程目标

---

第一部分:DDL 之表操作

---

一、表(Table)是什么?

表(Table) 是数据库中最核心的对象,用来存储数据。

表在mysql的安装路径的数据目录下面 /usr/local/mysql/data 目录的数据库同名目录下面的文件。

就像你在 Excel 里看到的那种"表格"一样,数据库中的"表"也是由行(row)列(column)组成的结构化数据集合。

1.1 生活中的例子

想象你在学校管理学员:

学员编号(id)姓名(name)年龄(age)生日(birthday)
1张三252025-10-11
2李四302025-10-11
3王五282025-10-11

这个"学员表"其实就是数据库中的一张表(table)。它的每一列代表一个"属性(字段)",每一行代表一个"数据记录"。

1.2 表的结构组成

一张表由以下几部分组成:

组成部分说明举例
表名表的名字,用来标识表student、user_info
列(字段,Column) ☆☆表中每一列代表一个属性name、age、gender
行(记录,Row)表中每一行代表一条完整数据张三、25、先生
数据类型(Data Type) ☆☆定义每一列能存放什么类型的数据INT、VARCHAR、DATE、TEXT
约束(Constraint)对列的规则限制NOT NULL、PRIMARY KEY、UNIQUE、DEFAULT

---

二、数据表字段类型

数据类型(Data Type) 用来定义表中"每一列(字段)"可以存储的数据类型和范围。

通俗讲:就像在 Excel 中定义某一列只能输入数字、或者只能输入日期。在数据库中,数据类型帮助 MySQL 知道这列该存什么、占多少空间、怎么比较。

2.1 数值类型

整数类型

类型占用字节取值范围(有符号)取值范围(无符号 UNSIGNED)
TINYINT1 字节-128 ~ 1270 ~ 255
SMALLINT2 字节-32768 ~ 327670 ~ 65535
MEDIUMINT3 字节-8388608 ~ 83886070 ~ 16777215
INT4 字节-2³¹ ~ 2³¹-10 ~ 2³²-1
BIGINT8 字节-2⁶³ ~ 2⁶³-10 ~ 2⁶⁴-1

说明: UNSIGNED 表示无符号整数,即不存负数,取值范围翻倍。

小数类型

类型说明特点示例
FLOAT单精度浮点数(4字节)精度有限比例
DOUBLE双精度浮点数(8字节)精度更高科学计算
DECIMAL(M,D)定点小数(M总位数,D小数位)精度准确,不丢失金额计算

2.2 字符串类型

定长字符串:CHAR

-- 表示用1个字符来存储数据
gender CHAR(1)

可变长字符串:VARCHAR

特点说明
变长(按内容长度存储)节省空间,存放长度不一的文本
适用场景姓名、地址、邮箱等
最大长度65535 字符(受行大小限制)
-- 表示最多存储50个字符
name VARCHAR(50)

CHAR vs VARCHAR 对比

类型优点缺点
CHAR查询更快,空间浪费固定长度
VARCHAR节省空间查询稍慢

文本类型(Text 系列)

类型最大长度用途
TINYTEXT255 字符短文本,如备注
TEXT65KB一般文本内容
MEDIUMTEXT16MB大段文本,如日志
LONGTEXT4GB超大文本,如文章内容
comment TEXT

注意:

2.3 日期与时间类型

时间戳 是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,它是一个数值。

类型存储字节范围格式用途
DATE31000-01-01 ~ 9999-12-31YYYY-MM-DD日期
TIME3-838:59:59 ~ 838:59:59HH:MM:SS时间
YEAR11901 ~ 2155YYYY年份
DATETIME81000-01-01 00:00:00 ~ 9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS日期时间(本地时间)
TIMESTAMP41970-01-01 ~ 2038YYYY-MM-DD HH:MM:SS自动记录当前时间(UTC)

---

三、创建数据表

表一定要在一个数据库中

3.1 创建表语法

-- if not exists 如果表不存在则创建,存在则不创建
create table [if not exists] 表名 (
    字段名1  数据类型 [约束],
    字段名2  数据类型 [约束]
    ...
) [character set 字符集(如:utf8mb4,默认为utf8mb4,不用指定)];

3.2 案例:创建admin管理员表

-- 前提创建一个数据库
create database test;

-- 使用数据库
use test;

-- 创建admin表,拥有3个字段(编号、用户名称、用户密码)
create table if not exists `admin` (
   `id` int,
   `uname` varchar(10),
   `pwd`   char(32)
);
-- 查看当前库下面所有的数据表
root@localhost [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| admin          |
+----------------+

3.3 案例:创建article文章表

-- 创建article文章表,拥有4个字段(编号、标题、作者、内容)
create table if not exists article (
    id int,
    title varchar(20),
    author varchar(10),
    content text
);

---

四、查看表

-- use 先切换到具体的库
mysql> use 数据库名称;

-- 查看当前库下面所有的数据表
root@localhost [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| admin          |
| article        |
+----------------+

4.1 查看表结构

-- 显示数据表的创建过程(编码格式、字段等信息)
mysql> desc 数据表名称;
mysql> show create table 数据表名称;
-- 查看 admin 表 相关字段信息
root@localhost [test]> desc admin;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | YES  |     | NULL    |       |
| uname | varchar(10) | YES  |     | NULL    |       |
| pwd   | char(32)    | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
-- 查看创建表的语句
root@localhost [test]> show create table admin\G
*************************** 1. row ***************************
       Table: admin
Create Table: CREATE TABLE `admin` (
  `id` int DEFAULT NULL,
  `uname` varchar(10) DEFAULT NULL,
  `pwd` char(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

---

五、删除表

注意: 在生产中,如果有删除表操作,前提你一定要先备份好,再考虑删除。

mysql> drop table 数据表名称;
root@localhost [test]> drop table admin;

root@localhost [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| article        |
+----------------+
1 row in set (0.00 sec)

---

六、修改表名称(了解)

rename table 旧名称 to 新名称;
root@localhost [test]> rename table admin to user;
Query OK, 0 rows affected (0.00 sec)

root@localhost [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| article        |
| user           |
+----------------+
2 rows in set (0.01 sec)

---

七、修改表字段(了解)

7.1 添加字段

-- 默认在表的最后列中添加一个新字段
mysql> alter table 数据表名称 add 新字段名称 字段类型;

-- 把新添加字段放在第一位
mysql> alter table 数据表名称 add 新字段名称 字段类型 [first];

-- 把新添加字段放在指定字段的后面
mysql> alter table 数据表名称 add 新字段名称 字段类型 [after 其他字段名称];

选项说明:

案例: 在article文章表中添加一个addtime字段,类型为date

-- 默认没有加位置条件,它会在表的最后列中添加一个新字段
root@localhost [test]> alter table article add addtime date;
root@localhost [test]> desc article;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int         | YES  |     | NULL    |       |
| title   | varchar(20) | YES  |     | NULL    |       |
| author  | varchar(10) | YES  |     | NULL    |       |
| content | text        | YES  |     | NULL    |       |
| addtime | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

-- 在列表第1列中添加一个新字段
root@localhost [test]> alter table article add addtime1 date first;

-- 在title字段后面添加一个新字段
root@localhost [test]> alter table article add addtime2 date after title;

7.2 删除字段

mysql> alter table 表名 drop 字段名称;
-- 删除 addtime1 字段
root@localhost [test]> alter table article drop addtime1;

-- 删除 addtime2 字段
root@localhost [test]> alter table article drop addtime2;

7.3 修改字段名称、类型

使用 change 修改字段名称与类型

-- change 比较神奇,既可以修改字段名称,又可以修改字段类型!
-- change 源字段名称 修改后字段名称 修改后的字段类型(这个也可以不改,但是必须要写)
mysql> alter table 表名 change 原字段名 新字段名 类型  [约束];
-- 修改表user 中的字段 uname为username新字段,类型不变
root@localhost [test]> desc user;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | YES  |     | NULL    |       |
| uname | varchar(10) | YES  |     | NULL    |       |
| pwd   | char(32)    | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

root@localhost [test]> alter table user change uname username varchar(10);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

root@localhost [test]> desc user;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int         | YES  |     | NULL    |       |
| username | varchar(10) | YES  |     | NULL    |       |
| pwd      | char(32)    | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+

使用 modify 仅修改字段类型

-- modify 字段名称 新字段类型(仅可以修改字段类型)
mysql> alter table 表名 modify 字段名 类型  [约束];
-- 只修改username字段的类型
root@localhost [test]> alter table user modify username varchar(100);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

root@localhost [test]> desc user;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| username | varchar(100) | YES  |     | NULL    |       |
| pwd      | char(32)     | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+

7.4 课堂练习

情景: 在企业开发中,小明接到一个需求,要求参与研发一套新的OA系统。其中有一张管理员表,交给了他。

-- 1、创建一张表 tb_admin( id、name、sex)
create database if not exists test;
use test;

create table tb_admin (
    id int,
    name varchar(10),
    sex char(1)
);

-- 2、应前端要求,添加字段address、phone_number
alter table tb_admin add address varchar(20);
alter table tb_admin add phone_number varchar(20);

-- 3、后来发现,地址信息几乎不怎么用,要求把 address 字段删除
alter table tb_admin drop  address;

-- 4、后来组员提出疑问,性别用gender更合适。建议把 sex 字段改成 gender
alter table tb_admin change sex gender char(1);

---

第二部分:DML 数据库操作语言

---

一、什么是 DML?

DML(Data Manipulation Language) —— 数据操作语言,用于对表中数据内容进行"增、删、改"的操作。

---

二、插入数据(INSERT)

2.1 指定字段插入【重点】

INSERT INTO 表名 (字段1, 字段2, 字段3) VALUES (值1, '值2', 值3);
-- 复制表中的内容[蠕虫复制]
insert into 表名 select * from 表名

注意:

案例: 向学生表(student)中插入一条学生信息数据

-- 创建数据库
create database if not exists test;
use test;

-- 创建数据表
create table student (
    id int,
    name varchar(20),
    age int,
    gender varchar(10)
);

-- 插入数据
insert into student (id,name, age, gender) values (1,'张三',20,'先生');

2.2 省略字段名(了解)

INSERT INTO 表名 VALUES (值1, 值2, 值3);

注意: 必须写出所有字段顺序

-- 值的数量和表字段的数量是相同的,所以插入是可以成功的
root@localhost [test]> insert into student values (2,'aaa',20,'aa');
Query OK, 1 row affected (0.00 sec)

-- 值的数量和表字段的数量不一样,所以插入不会成功
root@localhost [test]> insert into student values (3,'aaa',20);
ERROR 1136 (21S01): Column count doesn't match value count at row 1

-- 好处:不用写字段名
-- 坏处:字段顺序要对应上不能错,而且所有的字段还都要给值

2.3 一次插入多行数据(了解)

INSERT INTO 表名 (字段1, 字段2, 字段3) VALUES (值1, 值2, 值3),(值1, 值2, 值3);

优点: 效率高于多次单条 INSERT。

-- 需求1:向学生表(student)中插入3条学生信息数据
root@localhost [test]> insert into student (id,name, age, gender) values (3,'bb',20,'bbb'),(4,'cc',20,'cccc');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

需求2: 请在商品表(product)中,一次性插入以下数据

-- 商品表(product)
-- 1 iPhone16 Pro Max 12999 c01
-- 2 三星W25 15999 c01
-- 3 海尔冰箱 4999 c02
-- 4 联想电脑Y9000 4399 c03
-- 5 微波炉 899 c02

create table product (
    id int,
    name varchar(20),
    price int,
    fenli varchar(10)
);

insert into product (id,name,price,fenli) values
(1,'iPhone16 Pro Max',12999,'c01'),
(2,'三星W25',15999,'c01'),
(3,'海尔冰箱',4999,'c02'),
(4,'联想电脑Y9000',4399,'c03'),
(5,'微波炉',899,'c02');

需求3: 快速给用户表中添加100条数据【扩展】

#!/bin/bash

sql="insert into test.student (id,name, age, gender) values "
for i in {1..2}
do
     sql="$sql($i,'user_$i',20,'先生'),"
done

# 把最后1位的字符去除
sql=$(echo $sql | rev | cut -c2- | rev)

mysql -uroot -pAa123456. -e "$sql;" &>/dev/null

if [ $? -eq 0 ];then
        echo "成功"
else
        echo "失败"
fi

命令作用:

执行结果:

关键参数:

注意事项:

使用select语句把原有的数据进行重复插入


---

---


注意:

对比项DELETETRUNCATE
删除方式一行一行删除整表清空
自增ID不会重置自增id重置为1
速度

+--------+-------------+------+-----+---------+-------+ +--------+-------------+------+-----+---------+-------+ +--------+-------------+------+-----+---------+-------+

+------+------+------+--------+--------+ +------+------+------+--------+--------+ | 4 | cc | 20 | cccc | 0 | +------+------+------+--------+--------+


---


---





---






**在手写sql时最常用**

  ...
)

);

+------------+-------------+------+-----+---------+-------+ +------------+-------------+------+-----+---------+-------+ +------------+-------------+------+-----+---------+-------+



**在所有字段后去设置主键,此方案好处它可以指定单个字段为主键,也可以指定多个字段为主键**

  ...,
);

  ...,
);

( );



(
);

(1,'a','b','aa','bb');

(null,'a','b','aa','bb');

+------------+-------------+------+-----+---------+-------+
+------------+-------------+------+-----+---------+-------+
+------------+-------------+------+-----+---------+-------+


(
);

( );


---



**规则:**


  ...
)

( );

+------------+-------------+------+-----+---------+----------------+ +------------+-------------+------+-----+---------+----------------+ +------------+-------------+------+-----+---------+----------------+

( );


---





)

( );

( );


---






| 对比项 | PRIMARY KEY | UNIQUE |
|---|---|---|
| 定义的语句 | 不一样 | 不一样 |
| NULL值 | 不能为null | 可以为null |
| 数量 | 一个表只能有一个 | 可以有多个 |
| 自动特性 | 自动拥有唯一特性 | 没有 |


);

( );



(
);
+------------+-------------+------+-----+---------+----------------+
+------------+-------------+------+-----+---------+----------------+
+------------+-------------+------+-----+---------+----------------+

);



(
);

( );

( );


---


**DEFAULT**,默认值,插入数据时当不填写字段对应的值会使用默认值,如果填写时以填写为准。

**注意:**

);

( );


---



**外键约束前提:**

);

);

);

);


);


);




---

约束类型关键字说明
主键约束PRIMARY KEY唯一标识,不能重复,不能为null
自动增长AUTO_INCREMENT配合主键使用,自动生成唯一值
非空约束NOT NULL必须填写有效值,不能为null
唯一约束UNIQUE值必须唯一,但可以为null
默认值DEFAULT不填写时使用默认值
外键约束FOREIGN KEY多表关联,级联操作