1. 前言
MySQL 里最常打交道的东西,除了 SQL 查询,就是表了。建表、看表、改表、删表,这些操作看着简单,但真到项目里,坑也不少。比如字段类型选错了、删字段删错了、字符集没对齐,都是很常见的事。
这篇文章不整那些虚的,直接照着 MySQL 的官方语法,把表的增删改查讲明白。每个操作都配上实际案例,你照着敲一遍就能跑通。
2. 创建表
2.1 基本语法
创建表的语法长这样:
sql
CREATE TABLE table_name (
field1 datatype,
field2 datatype,
field3 datatype
) character set 字符集 collate 校验规则 engine 存储引擎;
几个关键点先说一下:
field表示列名datatype表示列的类型character set字符集,如果没有指定,就以所在数据库的字符集为准collate校验规则,如果没有指定,就以所在数据库的校验规则为准engine存储引擎,比如 InnoDB、MyISAM
2.2 一个完整的建表案例
我们建一张用户表,包含 id、用户名、密码、生日这几个字段:
sql
create table users (
id int,
name varchar(20) comment '用户名',
password char(32) comment '密码是32位的md5值',
birthday date comment '生日'
) character set utf8 engine MyISAM;
这里有个细节值得注意:password 用的是 char(32),因为 MD5 加密后的结果固定是 32 位,用定长字符串存最合适。name 用 varchar(20),因为用户名长度不固定,用变长字符串更省空间。
2.3 存储引擎不同,文件也不一样
不同的存储引擎,创建表生成的文件是不同的。
比如上面这张 users 表,存储引擎是 MyISAM,在数据目录下会有三个文件:
users.frm:表结构users.MYD:表数据users.MYI:表索引
如果你用的是 InnoDB 引擎,文件组织方式又不一样。建议你自己动手试一下:创建一个 engine 是 InnoDB 的表,然后去存储目录里看看生成了哪些文件,对比一下和 MyISAM 的区别。这个实验做完,你对存储引擎的理解会深不少。
3. 查看表结构
表建好了,怎么确认结构对不对?用 desc 命令:
sql
desc 表名;
比如查看 users 表:
sql
mysql> desc users;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| password | char(32) | YES | | NULL | |
| birthday | date | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
desc 会列出每一列的字段名、类型、是否允许为空、是否有索引、默认值等信息。日常开发中看表结构,基本就是靠它。
4. 修改表
项目开发中,表结构很少是一开始就定死不变的。字段名字要改、字段大小要调、字段类型要换、字符集要改、存储引擎要换,甚至要加字段、删字段,这些都得靠 ALTER TABLE 来完成。
4.1 修改表的语法
sql
ALTER TABLE tablename ADD (column datatype [DEFAULT expr][,column datatype]...);
ALTER TABLE tablename MODIFY (column datatype [DEFAULT expr][,column datatype]...);
ALTER TABLE tablename DROP (column);
ADD:添加新字段MODIFY:修改字段定义DROP:删除字段
4.2 先准备点数据
改表之前,先往 users 表里插两条记录,方便后面验证修改效果:
sql
mysql> insert into users values(1,'a','b','1982-01-04'),(2,'b','c','1984-01-04');
4.3 添加字段
给 users 表加一个字段,用来保存图片路径:
sql
mysql> alter table users add assets varchar(100) comment '图片路径' after birthday;
注意这里用了 after birthday,意思是把新字段加在 birthday 字段后面。不加这个的话,新字段默认加在最后。
插入新字段后,对原来表中的数据没有影响:
sql
mysql> select * from users;
+------+------+----------+------------+-------+
| id | name | password | birthday | assets |
+------+------+----------+------------+-------+
| 1 | a | b | 1982-01-04 | NULL | <= 原来的数据仍然存在
| 2 | b | c | 1984-01-04 | NULL |
+------+------+----------+------------+-------+
新加的 assets 字段,老数据里都是 NULL,这是正常的,因为之前的数据本来就没有这个字段的值。
4.4 修改字段
把 name 字段的长度从 20 改成 60:
sql
mysql> alter table users modify name varchar(60);
改完再看表结构:
sql
mysql> desc users;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(60) | YES | | NULL | | <= 长度变成60
| password | char(32) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| assets | varchar(100) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
4.5 删除字段
把 password 列删掉:
sql
mysql> alter table users drop password;
这里必须提醒一句:删除字段一定要小心。字段删了,对应的列数据也就没了,而且这个操作不可逆。删之前最好确认一下这个字段是不是真的没用了,或者先备份一下数据。
删完再看:
sql
mysql> desc users;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(60) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| assets | varchar(100) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
4.6 修改表名
把 users 表改名为 employee:
sql
mysql> alter table users rename to employee;
to 这个关键字可以省掉,写成下面这样也行:
sql
mysql> alter table users rename employee;
改完表名,数据还在:
sql
mysql> select * from employee;
+------+------+------------+-------+
| id | name | birthday | assets |
+------+------+------------+-------+
| 1 | a | 1982-01-04 | NULL |
| 2 | b | 1984-01-04 | NULL |
+------+------+------------+-------+
4.7 修改字段名
把 name 列改名为 xingming:
sql
mysql> alter table employee change name xingming varchar(60); -- 新字段需要完整定义
注意,change 和 modify 的区别就在这里:change 可以同时改字段名和字段定义,但新字段必须给出完整定义;modify 只能改字段定义,不能改字段名。
改完再看:
sql
mysql> desc employee;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| xingming | varchar(60) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| assets | varchar(100) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
5. 删除表
删除表的语法:
sql
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ...
示例:
sql
drop table t1;
几个要点:
IF EXISTS加上之后,如果表不存在也不会报错,适合在脚本里用- 可以一次删多张表,表名之间用逗号隔开
TEMPORARY表示只删临时表
删除表同样是个危险操作,表和数据会一起没,执行前务必确认。
6. 总结
把这一篇的操作串起来,其实就是一张表从生到死的完整生命周期:
- 建表 :
CREATE TABLE,注意字符集、校验规则、存储引擎的选择 - 看表 :
DESC,快速确认表结构 - 改表 :
ALTER TABLE,加字段用ADD,改定义用MODIFY,改字段名用CHANGE,删字段用DROP,改表名用RENAME - 删表 :
DROP TABLE,操作前想清楚
最后再啰嗦两句:
- 改表结构之前,最好先备份,尤其是删字段、删表这种不可逆的操作
- 生产环境的表结构变更,尽量走迁移工具(比如 Flyway、Liquibase),别直接在线上手敲 SQL
- 字段类型和长度,建表的时候就想清楚,后面改来改去既麻烦又容易出问题
表操作是 MySQL 的基本功,把这些命令练熟了,后面学索引、学事务都会轻松很多。