Skip to content

MySQL 数据库

Java 学累了,学学 MySQL

CRUD整理
  1. 查询

    sql
    SELECT
      s.id,
      s.name,
      s.gender,
      s.class_id,
      c.name AS class_name,
      s.score
    FROM
      students AS s
      INNER JOIN classes AS c ON s.class_id = c.id
    WHERE
      s.class_id <> 3
    ORDER BY
      score DESC
      LIMIT 6 OFFSET 0;
  2. 插入

    sql
    INSERT INTO students (NAME, gender, class_id, score)
    VALUES
    ('张三', '男', 1, 90),
    ('李四', '女', 2, 80),
    ('王五', '男', 3, 70);
  3. 更新

    sql
    UPDATE students
    SET
    score = 80,
    name = "张三"
    WHERE
      id = 1;
  4. 删除

    sql
    DELETE
    FROM
      students
    WHERE
      id = 1;

01. 简介

1.1 什么是 MySQL

MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL 是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

1.2 为什么需要数据库

应用程序储存信息可以把数据储存在文档中,但是随着业务复杂度提升,数据量增大,如何管理数据成了最大的问题。同时,不同的程序读取数据的方式也不同,导致代码难以复用。

所以,数据库作为一种专门管理数据的软件就出现了。应用程序不需要自己管理数据,而是通过数据库软件提供的接口来读写数据。至于数据本身如何存储到文件,那是数据库软件的事情,应用程序自己并不关心:

┌───────────┐
│application│
└───────────┘
     ▲ │
     │ │
 read│ │write
     │ │
     │ ▼
┌───────────┐
│ database  │
└───────────┘

这样一来,编写应用程序的时候,数据读写的功能就被大大地简化了。

1.3 数据库的分类

  • 关系型数据库
    • MySQL
    • Oracle
    • SQL Server
    • PostgreSQL
    • SQLite
    • ...
  • 非关系型数据库
    • MongoDB
    • Redis
    • ...
  • 数据库的选择
    • 关系型数据库:适用于需要复杂查询和事务处理的场景,如金融、银行、电商等。
    • 非关系型数据库:适用于需要高并发、高可用、高可扩展性的场景,如社交媒体、游戏、物联网等。

1.4 数据类型

对于一个关系表,除了定义每一列的名称外,还需要定义每一列的数据类型。关系数据库支持的标准数据类型包括数值、字符串、时间等:

名称类型说明
INT整型4 字节整数类型,范围约+/-21 亿
BIGINT长整型8 字节整数类型,范围约+/-922 亿亿
REAL浮点型4 字节浮点数,范围约+/-1038
DOUBLE浮点型8 字节浮点数,范围约+/-10308
DECIMAL(M,N)高精度小数由用户指定精度的小数,例如,DECIMAL(20,10)表示一共 20 位,其中小数 10 位,通常用于财务计算
CHAR(N)定长字符串存储指定长度的字符串,例如,CHAR(100)总是存储 100 个字符的字符串
VARCHAR(N)变长字符串存储可变长度的字符串,例如,VARCHAR(100)可以存储 0~100 个字符的字符串
BOOLEAN布尔类型存储 True 或者 False
DATE日期类型存储日期,例如,2018-06-22
TIME时间类型存储时间,例如,12:20:59
DATETIME日期和时间类型存储日期+时间,例如,2018-06-22 12:20:59

02. 安装

  1. MySQL 官方,下载最新的 MySQL Community Server 版本,并安装
  2. 配置环境变量
    1. 打开环境变量配置界面
    2. 点击 新建,变量名 MYSQL_HOME,变量值为 MySQL 安装目录
    3. Path 变量中添加 MySQL 安装目录的 bin 目录
  3. 启动 MySQL 服务
    1. 打开命令行工具
    2. 输入 mysql -u root -p 并回车
    3. 输入密码并回车【密码为安装时创建的,默认为root
    4. 登录成功后,会显示 MySQL 版本信息
  4. 输入 exit 退出 MySQL 数据库

03. 关系模型

概念

  • 表的每一行称为记录(Record),记录是一个逻辑意义上的数据。
  • 表的每一列称为字段(Column),同一个表的每一行记录都拥有相同的若干字段。

关系数据库的表和表之间需要建立“一对多”,“多对一”和“一对一”的关系,这样才能够按照应用程序的逻辑来组织和存储数据。关系是通过 主键外键 来维护的。

3.1 主键

引子

对于关系表,有个很重要的约束,就是任意两条记录不能重复。不能重复不是指两条记录不完全相同,而是指能够通过某个字段唯一区分出不同的记录,这个字段被称为 主键

作为主键最好是完全业务无关的字段,我们一般把这个字段命名为id。常见的可作为id字段的类型有:

  • 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键重复,也不用自己预先生成主键;
  • 全局唯一 GUID 类型:也称 UUID,使用一种全局唯一的字符串作为主键,类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57。GUID 算法通过网卡 MAC 地址、时间戳和随机数保证任意计算机在任意时间生成的字符串都是不同的,大部分编程语言都内置了 GUID 算法,可以自己预算出主键。

对于大部分应用来说,通常自增类型的主键就能满足需求。

注意

如果使用 INT 自增类型,那么当一张表的记录数超过 2147483647(约 21 亿)时,会达到上限而出错。使用 BIGINT 自增类型则可以最多约 922 亿亿条记录。

3.2 外键

  1. 一对多

    当我们用主键唯一标识记录时,我们就可以在students表中确定任意一个学生的记录:

    idnameother columns...
    1小明...
    2小红...

    我们还可以在classes表中确定任意一个班级记录:

    idnameother columns...
    1一班...
    2二班...

    但是我们如何确定students表的一条记录,例如,id=1的小明,属于哪个班级呢?

    由于一个班级可以有多个学生,在关系模型中,这两个表的关系可以称为“一对多”,即一个classes的记录可以对应多个students表的记录。

    为了表达这种一对多的关系,我们需要在students表中加入一列class_id,让它的值与classes表的某条记录相对应:

    idclass_idnameother columns...
    11小明...
    21小红...
    52小白...

    这样,我们就可以根据class_id这个列直接定位出一个students表的记录应该对应到classes的哪条记录。

    例如:

    • 小明的class_id1,因此,对应的classes表的记录是id=1的一班;
    • 小红的class_id1,因此,对应的classes表的记录是id=1的一班;
    • 小白的class_id2,因此,对应的classes表的记录是id=2的二班。

    students表中,通过class_id的字段,可以把数据与另一张表关联起来,这种列称为外键。

    外键并不是通过列名实现的,而是通过定义外键约束实现的:

    sql
    -- 外键约束
    ALTER TABLE students
    ADD CONSTRAINT fk_class_id
    FOREIGN KEY (class_id)
    REFERENCES classes(id);

    其中,外键约束的名称fk_class_id可以任意,FOREIGN KEY (class_id)指定了class_id作为外键,REFERENCES classes (id)指定了这个外键将关联到classes表的id列(即classes表的主键)。

    通过定义外键约束,关系数据库可以保证无法插入无效的数据。即如果classes表不存在id=99的记录,students表就无法插入class_id=99的记录。

    由于外键约束会降低数据库的性能,大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性。这种情况下,class_id仅仅是一个普通的列,只是它起到了外键的作用而已。

  2. 多对多

    通过一个表的外键关联到另一个表,我们可以定义出一对多关系。有些时候,还需要定义“多对多”关系。例如,一个老师可以对应多个班级,一个班级也可以对应多个老师,因此,班级表和老师表存在多对多关系。

    多对多关系实际上是通过两个一对多关系实现的,即通过一个中间表,关联两个一对多关系,就形成了多对多关系:

    teachers表:

    idname
    1张老师
    2王老师
    3李老师
    4赵老师

    classes表:

    idname
    1一班
    2二班

    中间表teacher_class关联两个一对多关系:

    idteacher_idclass_id
    111
    212
    321
    422
    531
    642

    通过中间表teacher_class可知teachersclasses的关系:

    • id=1的张老师对应id=1,2的一班和二班;
    • id=2的王老师对应id=1,2的一班和二班;
    • id=3的李老师对应id=1的一班;
    • id=4的赵老师对应id=2的二班。

    同理可知classesteachers的关系:

    • id=1的一班对应id=1,2,3的张老师、王老师和李老师;
    • id=2的二班对应id=1,2,4的张老师、王老师和赵老师;

    因此,通过中间表,我们就定义了一个“多对多”关系。

  3. 一对一

    一对一关系是指,一个表的记录对应到另一个表的唯一一个记录。

    例如,students表的每个学生可以有自己的联系方式,如果把联系方式存入另一个表contacts,我们就可以得到一个“一对一”关系:

    idstudent_idmobile
    11135xxxx6300
    22138xxxx2209
    35139xxxx8086

    有细心的童鞋会问,既然是一对一关系,那为啥不给students表增加一个mobile列,这样就能合二为一了?

    如果业务允许,完全可以把两个表合为一个表。但是,有些时候,如果某个学生没有手机号,那么,contacts表就不存在对应的记录。实际上,一对一关系准确地说,是contacts表一对一对应students表。

    还有一些应用会把一个大表拆成两个一对一的表,目的是把经常读取和不经常读取的字段分开,以获得更高的性能。例如,把一个大的用户表分拆为用户基本信息表user_info和用户详细信息表user_profiles,大部分时候,只需要查询user_info表,并不需要查询user_profiles表,这样就提高了查询速度。

3.3 索引

在关系数据库中,如果有上万甚至上亿条记录,在查找记录的时候,想要获得非常快的速度,就需要使用索引。

索引是关系数据库中对某一列或多个列的值进行预排序的数据结构。通过使用索引,可以让数据库系统不必扫描整个表,而是直接定位到符合条件的记录,这样就大大加快了查询速度。

例如,对于students表:

idclass_idnamegenderscore
11小明M90
21小红F95
31小军M88

如果要经常根据 score 列进行查询,就可以对 score 列创建索引:

sql
ALTER TABLE students
ADD INDEX idx_score (score);

使用ADD INDEX idx_score (score)就创建了一个名称为idx_score,使用列score的索引。索引名称是任意的,索引如果有多列,可以在括号里依次写上,例如:

sql
ALTER TABLE students
ADD INDEX idx_name_score (name, score);

索引的效率取决于索引列的值是否散列,即该列的值如果越互不相同,那么索引效率越高。反过来,如果记录的列存在大量相同的值,例如gender列,大约一半的记录值是M,另一半是F,因此,对该列创建索引就没有意义。

可以对一张表创建多个索引。索引的优点是提高了查询效率,缺点是在插入、更新和删除记录时,需要同时修改索引,因此,索引越多,插入、更新和删除记录的速度就越慢。

对于主键,关系数据库会自动对其创建主键索引。使用主键索引的效率是最高的,因为主键会保证绝对唯一。

唯一索引

在设计关系数据表的时候,看上去唯一的列,例如身份证号、邮箱地址等,因为他们具有业务含义,因此不宜作为主键。

但是,这些列根据业务要求,又具有唯一性约束:即不能出现两条记录存储了同一个身份证号。这个时候,就可以给该列添加一个唯一索引。例如,我们假设students表的name列不能重复:

sql
ALTER TABLE students
ADD UNIQUE INDEX uni_name (name);

通过UNIQUE关键字我们就添加了一个唯一索引。

也可以只对某一列添加一个唯一约束而不创建唯一索引:

sql
ALTER TABLE students
ADD CONSTRAINT uni_name UNIQUE (name);

这种情况下,name列没有索引,但仍然具有唯一性保证。

无论是否创建索引,对于用户和应用程序来说,使用关系数据库不会有任何区别。这里的意思是说,当我们在数据库中查询时,如果有相应的索引可用,数据库系统就会自动使用索引来提高查询效率,如果没有索引,查询也能正常执行,只是速度会变慢。因此,索引可以在使用数据库的过程中逐步优化。

04. 查询数据

数据准备

  1. 下载SQL 脚本,并在命令行运行:
  2. 推荐使用 MySQL 客户端工具,例如 Navicat 等,运行 SQL 文件导入。

就会得到两张表classesstudents

classes表:

idname
1一班
2二班
3三班
4四班

students表:

idclass_idnamegenderscore
11小明M90
21小红F95
31小军M88
41小米F73
52小白F81
62小兵M55
72小林M85
83小新F91
93小王M89
103小丽F85

4.1 基础查询

全表查询 SQL 语句:

sql
SELECT * FROM <表名>;

如表名是students,要查询students表的所有行,则查询语句为:

sql
SELECT * FROM students;

解析

语句中,SELECT是关键字,*表示查询所有列,FROM表示将要从哪个表查询,最后是要查询的表名。

  1. SELECT语句是大小写不敏感的,selectSELECTSeLeCt等都是一样的。
  2. *表示查询所有列,也可以指定要查询的列,例如:SELECT id, name FROM students;表示查询students表的idname列。

4.2 条件查询

条件查询 SQL 语句:

sql
SELECT * FROM <表名> WHERE <条件>;

如要查询students表中genderM的行,则查询语句为:

sql
SELECT * FROM students WHERE gender = 'M';

解析

语句中,WHERE表示查询条件,gender = 'M'表示查询gender列值为M的行。

通过ANDOR可以组合多个条件,例如:

sql
SELECT * FROM students WHERE gender = 'M' AND score >= 80;

表示查询genderMscore大于等于80的行。

OR表示或的关系,例如:

sql
SELECT * FROM students WHERE gender = 'M' OR score >= 80;

表示查询genderMscore大于等于80的行。

ANDOR可以组合使用,例如:

sql
SELECT * FROM students WHERE gender = 'M' AND (score >= 80 OR score <= 60);

表示查询genderMscore大于等于80或小于等于60的行。

解析

语句中,()表示优先级,ANDOR的优先级相同,从左到右依次执行。

NOT表示非的关系,例如:

sql
SELECT * FROM students WHERE NOT class_id = 2;

表示查询class_id不为2的行,其实等价于:SELECT * FROM students WHERE class_id <> 2;NOT查询不常用。

常用表达式

条件表达式举例 1表达式举例 2说明
=判断相等score = 80name = 'abc'字符串需要用单引号括起来
>判断大于score > 80name > 'abc'字符串比较根据 ASCII 码,中文字符比较根据数据库设置
>=判断大于或相等score >= 80name >= 'abc'
<判断小于score < 80name <= 'abc'
<=判断小于或相等score <= 80name <= 'abc'
<>判断不相等score <> 80name <> 'abc'
LIKE判断相似name LIKE 'ab%'name LIKE '%bc%'%表示任意字符,例如'ab%'将匹配'ab','abc','abcd'

4.3 投影查询

投影查询 SQL 语句:

sql
SELECT <列名>, <列名>, ... FROM <表名>;

如要查询students表中idnamescore列的所有行,则查询语句为:

sql
SELECT id, name, score FROM students;

可以看到只返回了idnamescore这三列的所有行数据,投影查询就是让结果仅包含指定列

使用投影查询还可以给列起别名,例如:

sql
SELECT id, name, score AS `成绩` FROM students;

可以看到返回的结果中,score列的标题是成绩

解析

语句中,AS表示别名,成绩score的别名,也可以省略AS,例如:SELECT id, name, score 成绩 FROM students;

当然,也可以拼接where条件实现复杂查询,例如:

sql
SELECT id, name, score AS `成绩` FROM students WHERE class_id = 1;

4.4 排序

排序 SQL 语句:

sql
SELECT <列名> FROM <表名> ORDER BY <列名> <排序方式>;

解析

语句中,ORDER BY表示排序,列名表示要排序的列,排序方式表示排序方式,ASC表示升序,DESC表示降序。

例如:

sql
SELECT id, name, score FROM students ORDER BY score DESC;

解析

表示查询students表的idnamescore列,按score列降序排序。

可以进行多列排序,例如:

sql
SELECT id, class_id, name, score FROM students ORDER BY class_id, score DESC;

解析

语句中,ORDER BY表示排序,class_id表示要排序的列默认升序,score表示要排序的列且为降序。

条件+排序 SQL 语句:

sql
SELECT <列名> FROM <表名> WHERE <条件> ORDER BY <列名> <排序方式>;

如只查询class_id1的行,按score列降序排序,则查询语句为:

sql
SELECT id, class_id, name, score FROM students WHERE class_id = 1 ORDER BY score DESC;

注意

WHERE子句要在ORDER BY子句之前,否则会查询报错。

4.5 分页查询

分页查询 SQL 语句:

sql
SELECT <列名> FROM <表名> LIMIT <N> OFFSET <M>;

解析

语句中,LIMIT表示限制,N表示限制返回的行数,OFFSET表示偏移,M表示偏移量。

如要查询students表中按score降序排列的第1页,每页3条数据,则查询语句为:

sql
SELECT id, name, score FROM students ORDER BY score DESC LIMIT 3 OFFSET 0;

如要查询students表中按score降序排列的第2页,每页3条数据,则查询语句为:

sql
SELECT id, name, score FROM students ORDER BY score DESC LIMIT 3 OFFSET 3;

如要查询students表中按score降序排列的第4页,每页3条数据,则查询语句为:

sql
SELECT id, name, score FROM students ORDER BY score DESC LIMIT 3 OFFSET 9;

会发现只返回了一条数据,这是因为students表中只有10条数据,第4页只剩了一条数据。

当我们查询第5页,每页3条数据,则查询语句为:

sql
SELECT id, name, score FROM students ORDER BY score DESC LIMIT 3 OFFSET 12;

会发现返回了0条数据,这是因为students表中只有10条数据,第5页已经没有数据可返回。

规律:

限制 LIMIT条数 ROW偏移量 OFFSET
130
233
336
439
5312

根据上表,可推断OFFSET = (LIMIT - 1) * ROW,即LIMIT = pageSizeOFFSET = (pageNo - 1) * pageSize

小结

  1. 分页查询的LIMITOFFSET参数都必须是非负整数
  2. 分页查询的LIMIT参数可以省略,默认返回所有行。
  3. 分页查询的OFFSET参数可以省略,默认从第0行开始。
  4. 分页查询的LIMIT参数和OFFSET参数的乘积超过行数时,返回空的结果集。
  5. LIMIT 10 OFFSET 20也可以写成LIMIT 20, 10
  6. 随着数据量的增加,分页查询的效率会降低。

4.6 聚合查询

聚合查询 SQL 语句:

sql
SELECT <聚合函数> FROM <表名>;

例如,查询students表的行数:

sql
SELECT COUNT(*) FROM students;

也可以给聚合函数起别名,例如:

sql
SELECT COUNT(*) AS total FROM students;

也可以进行聚合函数的条件查询,例如查询class_id1的学生人数:

sql
SELECT COUNT(*) AS total FROM students WHERE class_id = 1;

除了COUNT()外,其他聚合函数有:

函数说明
SUM()计算某一列的总和,该列必须为数值类型
AVG()计算某一列的平均值,该列必须为数值类型
MAX()计算某一列的最大值
MIN()计算某一列的最小值

例如,查询students表的性别为Mscore列的平均数:

sql
SELECT AVG(score) as avg_score FROM students WHERE gender = 'M';

注意

如果聚合查询的WHERE条件没有匹配到任何行,COUNT()会返回0,而 SUM()、AVG()、MAX()和 MIN()会返回NULL

4.7 分组查询

分组查询 SQL 语句:

sql
SELECT <列名>, <聚合函数> FROM <表名> GROUP BY <列名>;

例如,查询students表的各班的人数:

sql
SELECT class_id, COUNT(*) as count FROM students GROUP BY class_id;

例如,查询students表的各班平均分:

sql
SELECT class_id, AVG(score) as class_avg_score FROM students GROUP BY class_id;

例如,查询students表的各班的男生和女生人数:

sql
SELECT class_id, gender, COUNT(*) as count FROM students GROUP BY class_id, gender;

4.8 多表查询

多表查询 SQL 语句:

sql
SELECT <列名> FROM <表名1>, <表名2>;

例如:

sql
SELECT * FROM students, classes;

解析

语句中,FROM子句后面跟着的是多个表名,多个表名之间用逗号隔开。

这种一次查询两个表的数据,查询的结果也是一个二维表,它是students表和classes表的“乘积”,即students表的每一行与classes表的每一行都两两拼在一起返回。结果集的列数是students表和classes表的列数之和,行数是students表和classes表的行数之积。

这种多表查询又称笛卡尔查询,使用笛卡尔查询时要非常小心,由于结果集是目标表的行数乘积,对两个各自有 100 行记录的表进行笛卡尔查询将返回 1 万条记录,对两个各自有 1 万行记录的表进行笛卡尔查询将返回 1 亿条记录。

可以给查询的列起别名,例如:

sql
SELECT
  students.id sid,
  students.name,
  students.gender,
  students.score,
  classes.id cid,
  classes.name cname
FROM students, classes;

也可以给表起别名,例如:

sql
SELECT
  s.id sid,
  s.name,
  s.gender,
  s.score,
  c.id cid,
  c.name cname
FROM students s, classes c;

4.9 连表查询

连表查询 SQL 语句:

sql
SELECT <列名> FROM <表名1> <连接类型> JOIN <表名2> ON <连接条件>;

例如,将students表和classes表连接起来,查询每个学生的姓名、班级名称:

sql
SELECT
 s.id,
 s.name,
 s.gender,
 s.class_id,
 c.name AS class_name,
 s.score
FROM
 students AS s
INNER JOIN classes AS c ON s.class_id = c.id;

解析

  1. 先确定主表,仍然使用FROM <表1>的语法;
  2. 再确定需要连接的表,使用INNER JOIN <表2>的语法;
  3. 然后确定连接条件,使用ON <条件...>,这里的条件是s.class_id = c.id,表示students表的class_id列与classes表的id列相同的行需要连接;
  4. 使用别名不是必须的,但是可以简化查询语句;
  5. 可选:加上WHERE子句、ORDER BY等子句。

外连接查询

INNER JOIN改成LEFT JOINRIGHT JOIN,就变成了外连接查询。

sql
SELECT
 s.id,
 s.name,
 s.gender,
 s.class_id,
 c.name AS class_name,
 s.score
FROM
 students AS s
RIGHT JOIN classes AS c ON s.class_id = c.id;

执行上述RIGHT OUTER JOIN可以看到,和INNER JOIN相比,RIGHT OUTER JOIN多了一行,多出来的一行是“四班”,但是,学生相关的列如namegenderscore都为NULL

连接区别

  1. INNER JOIN只返回同时存在于两张表的行数据,由于students表的class_id包含123classes表的id包含1234,所以,INNER JOIN根据条件s.class_id = c.id返回的结果集仅包含123
  2. RIGHT OUTER JOIN返回右表都存在的行。如果某一行仅在右表存在,那么结果集就会以NULL填充剩下的字段。
  3. LEFT OUTER JOIN则返回左表都存在的行。如果某一行仅在左表存在,那么结果集就会以NULL填充剩下的字段。
  4. FULL OUTER JOIN返回左表和右表都存在的行。如果某一行仅在左表或右表存在,那么结果集就会以NULL填充剩下的字段。

注意

如何选择JOIN查询方法:

sql
SELECT <字段> FROM <表1> <连接类型> JOIN <表2> ON 表1.字段N = 表2.字段M;

可以把表1看做左表,把表2看做右表。

  1. 那么INNER JOIN是选出两张表都存在的记录: INNER JOIN
  2. LEFT OUTER JOIN是选出左表存在的记录: LEFT OUTER JOIN
  3. RIGHT OUTER JOIN是选出右表存在的记录: RIGHT OUTER JOIN
  4. FULL OUTER JOIN是选出两张表都存在的记录,或者说,就是并集: FULL OUTER JOIN

05. 修改数据

关系数据库的基本操作就是增删改查,即CRUD:Create、Retrieve、Update、Delete。

5.1 插入数据

插入数据 SQL 语句:

sql
INSERT INTO <表名> (<字段1>, <字段2>, ...) VALUES (<值1>, <值2>, ...);

students表插入数据:

sql
INSERT INTO students (name, gender, class_id, score)
VALUES
('张三', 'M', 1, 80);

或同时插入多条数据:

sql
INSERT INTO students (name, gender, class_id, score)
VALUES
('张三', 'M', 1, 80),
('李四', 'F', 2, 90),
('王五', 'M', 3, 85);

5.2 更新数据

更新数据 SQL 语句:

sql
UPDATE <表名> SET <字段1>=<值1>, <字段2>=<值2>, ... WHERE <条件>;

例如,将students表中id1的行的score更新为90name更新为'张三'

sql
UPDATE students
SET
score = 90,
name = '张三'
WHERE
id = 1;

可以一次更新多条数据,例如,将students表中class_id1的行的score更新为90

sql
UPDATE students
SET
score = 90
WHERE
class_id = 1;

更新数据可以使用表达式,例如,将students表中class_id1的行的score10分:

sql
UPDATE students
SET
score = score - 10
WHERE
class_id = 1;

小提示

  1. 如果WHERE子句为空,则会更新表中的所有行;
  2. 如果WHERE字句没有匹配到任何行,则不会更新任何行;

注意

在使用MySQL这类真正的关系数据库时,UPDATE语句会返回更新的行数以及WHERE条件匹配的行数。

例如,更新id=1的记录时:

bash
mysql> UPDATE students SET name='大宝' WHERE id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MySQL会返回1,可以从打印的结果Rows matched: 1 Changed: 1看到。

当更新id=999的记录时:

bash
mysql> UPDATE students SET name='大宝' WHERE id=999;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

MySQL会返回0,可以从打印的结果Rows matched: 0 Changed: 0看到。

5.3 删除数据

删除数据 SQL 语句:

sql
DELETE FROM <表名> WHERE <条件>;

例如,删除students表中id1的行:

sql
DELETE FROM students WHERE id=1;

可以一次删除多条数据,例如,删除students表中id567的行:

sql
DELETE FROM students WHERE id IN(5, 6, 7);

可以使用DELETE FROM语句删除表中的所有数据:

sql
DELETE FROM students;

小提示

  1. 如果WHERE子句为空,则会删除表中的所有行;
  2. 如果WHERE字句没有匹配到任何行,则不会删除任何行;

注意

在使用MySQL这类真正的关系数据库时,DELETE语句也会返回删除的行数以及WHERE条件匹配的行数。

例如,分别执行删除id=1id=999的记录:

bash
mysql> DELETE FROM students WHERE id=1;
Query OK, 1 row affected (0.01 sec)

mysql> DELETE FROM students WHERE id=999;
Query OK, 0 rows affected (0.01 sec)