数据库、数据表与增删改查
🎯 引言
上一篇我们已经用 Docker 跑起了 MySQL 8,并连上了客户端。学完这篇文章,你能创建自己的数据库和数据表,并完成数据的增加、查询、修改、删除四种基本操作,也就是大家常说的 CRUD。这四种操作是日常使用数据库的核心,后面的所有课程都建立在它们之上。
🧱 创建数据库
一个 MySQL 服务里可以放很多个数据库(Database),每个数据库相互独立。可以把它理解成 Excel:一个数据库就是一个 Excel 文件,里面的每张表就是一个工作表。
通常一个项目对应一个数据库。我们为本课程的示例创建一个名为 blog_demo 的数据库:
CREATE DATABASE blog_demo;
查看当前有哪些数据库:
SHOW DATABASES;
执行结果大致如下(不同环境自带的数据库可能略有差异):
| Database |
|---|
| blog_demo |
| information_schema |
| mysql |
| performance_schema |
| sys |
结果里除了 blog_demo,你还会看到 mysql、sys 等几个自带的数据库,它们是 MySQL 自己用的,不要去动它们。
执行下面的语句后,接下来的操作就都发生在 blog_demo 里了:
USE blog_demo;
USE blog_demo; 只对当前连接生效。如果你关掉客户端重新连接,需要再执行一次,否则 MySQL 不知道你要操作哪个数据库。🛠 创建数据表
数据库只是容器,真正存数据的是表(Table)。表由行和列组成:每一列是一个字段(比如用户名、年龄),每一行是一条具体的数据(比如一个用户)。
我们在 blog_demo 里创建一张 user 用户表:
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
age INT,
city VARCHAR(50)
);
逐个字段来看:
id INT PRIMARY KEY AUTO_INCREMENT:整数类型,作为主键(每条数据的唯一标识),AUTO_INCREMENT表示插入时自动生成,从 1 开始递增,不用我们操心。username VARCHAR(50):字符串类型,长度不超过 50 个字符。age INT:整数类型。city VARCHAR(50):字符串类型。
表创建好后,可以查看当前数据库里有哪些表:
SHOW TABLES;
执行结果如下:
| Tables_in_blog_demo |
|---|
| user |
用 DESC 查看表的结构,确认字段有没有写对:
DESC user;
执行结果如下:
| Field | Type | Null | Key | Default | Extra |
|---|---|---|---|---|---|
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(50) | YES | NULL | ||
| age | int | YES | NULL | ||
| city | varchar(50) | YES | NULL |
会看到每个字段的名称、类型、是否主键等信息。这几列的含义是:
Field:字段名;Type:字段类型。Null:这个字段允不允许存空值,YES表示允许。id是NO,因为主键不能为空。Key:PRI表示这个字段是主键。Default:插入数据时如果没给这个字段赋值,默认填什么。我们建表时没有声明任何DEFAULT,所以全部是NULL,表示「没有默认值」。这是正常现象,不是出错了。Extra:额外属性,id的auto_increment就显示在这里。
✨ 插入数据 INSERT
表是空的,我们先往里放数据。插入用 INSERT INTO,指定表名、字段名和对应的值:
INSERT INTO user (username, age, city) VALUES ('张三', 25, '北京');
注意我们没有给 id 赋值,它设了 AUTO_INCREMENT,MySQL 会自动生成。字符串要用引号包起来,数字不用。
一次插入多条数据,用逗号分隔多组值即可,比逐条执行更方便:
INSERT INTO user (username, age, city) VALUES
('李四', 30, '上海'),
('王五', 22, '广州'),
('赵六', 28, '深圳');
两次插入完成后,执行 SELECT * FROM user; 看一眼,表里的数据如下:
| id | username | age | city |
|---|---|---|---|
| 1 | 张三 | 25 | 北京 |
| 2 | 李四 | 30 | 上海 |
| 3 | 王五 | 22 | 广州 |
| 4 | 赵六 | 28 | 深圳 |
💡 查询数据 SELECT
查询用 SELECT,这是日常使用频率很高的语句。查全部数据、全部列:
SELECT * FROM user;
执行结果如下:
| id | username | age | city |
|---|---|---|---|
| 1 | 张三 | 25 | 北京 |
| 2 | 李四 | 30 | 上海 |
| 3 | 王五 | 22 | 广州 |
| 4 | 赵六 | 28 | 深圳 |
* 是通配符,表示「所有列」。执行后能看到刚才插入的四条数据,每条都带着自动生成的 id。
实际开发中更推荐写明需要的列,只取要用的数据:
SELECT username, age FROM user;
执行结果如下:
| username | age |
|---|---|
| 张三 | 25 |
| 李四 | 30 |
| 王五 | 22 |
| 赵六 | 28 |
这样结果里就只有用户名和年龄两列。写明列名还有个好处:即使以后给表加了新字段,这条查询的结果也不会变。
⚡ 修改数据 UPDATE
已有数据写错了怎么办?用 UPDATE ... SET ... WHERE 来改。比如张三搬到了杭州:
UPDATE user SET city = '杭州' WHERE id = 1;
SET后面写要改哪些列、改成什么值,改多列时用逗号分隔,例如SET age = 26, city = '杭州'。WHERE后面写条件,只有满足条件的行才会被修改。这里用主键id定位,能精确改到某一条。
改完后再执行 SELECT * FROM user; 确认一下,张三的城市已经变成杭州:
| id | username | age | city |
|---|---|---|---|
| 1 | 张三 | 25 | 杭州 |
| 2 | 李四 | 30 | 上海 |
| 3 | 王五 | 22 | 广州 |
| 4 | 赵六 | 28 | 深圳 |
🪤 删除数据 DELETE
删除数据用 DELETE FROM ... WHERE。比如把赵六这条数据删掉:
DELETE FROM user WHERE id = 4;
删除后再执行 SELECT * FROM user; 确认,赵六这条数据已经不在了:
| id | username | age | city |
|---|---|---|---|
| 1 | 张三 | 25 | 杭州 |
| 2 | 李四 | 30 | 上海 |
| 3 | 王五 | 22 | 广州 |
删除是不可逆的,执行前建议先用同样条件的 SELECT 查一遍,确认要删的就是这些数据。
DELETE FROM user; 会把表里所有数据删光,这是新手很容易踩的坑。请养成习惯:写 UPDATE 和 DELETE 时先写 WHERE,确认条件没问题再执行。🧾 小节总结
- 用
CREATE DATABASE blog_demo;创建数据库,USE blog_demo;切换到它。 - 用
CREATE TABLE建表,定义字段名和类型;SHOW TABLES;和DESC user;可以查看表和表结构。 INSERT INTO插入数据,支持一次插入多条;设了AUTO_INCREMENT的主键会自动生成。SELECT * FROM查全部列,SELECT 列名只查指定列。UPDATE ... SET ... WHERE修改数据,DELETE FROM ... WHERE删除数据。- UPDATE 和 DELETE 一定要带 WHERE,否则会作用于整张表。
❓ 知识问答
Q1:重新连接客户端后,执行 SQL 报错说没选数据库?
USE blog_demo; 只对当前连接生效,重新连接后需要再执行一次。也可以在表名前加上数据库名,写成 SELECT * FROM blog_demo.user;。
Q2:插入数据时可以不给某些字段赋值吗?
可以。没写在字段列表里的列会是默认值(目前课程里就是空值 NULL)。第 04 篇讲约束时会介绍如何给字段设置默认值、禁止为空。
Q3:为什么查询建议写明列名,而不是都用 *?
写明列名只取需要的数据,表字段变多时也不会影响原来的查询结果,代码意图也更清晰。学习时用 * 图方便没问题,实际项目里建议写具体列名。
Q4:DELETE 删掉一行后,AUTO_INCREMENT 的 id 会重新排号吗?
不会。id 一旦生成过就不会再复用,删掉 id 为 4 的数据后,下一条新数据的 id 会从 5 开始,中间留空是正常的。
Q5:执行 UPDATE 后怎么确认改成功了?
再执行一次 SELECT 查看对应的行即可。客户端也会提示「影响了多少行」,数字为 0 通常说明 WHERE 条件没匹配到任何数据。
🧪 小练习
在 user 表中完成下面两步操作:
- 插入一条你自己的数据(用户名随意,年龄和城市填真实的)。
-- 请在这里编写 SQL
- 把上一步插入的这条数据的城市改成「成都」,然后把它查询出来确认。
-- 请在这里编写 SQL
🎉 恭喜你已经掌握数据库与数据表的增删改查技能啦!下一篇我们学习条件查询、排序分页与聚合分组,让 SELECT 真正发挥威力,从一堆数据里精确找出你想要的那部分。
