MySQL 基础入门

MySQL 基础入门

【SQL数据库】SQL两小时半快速入门到精通 建议反复观看 学不会自我反省_哔哩哔哩_bilibili

什么是数据库?简单来说,数据库就是一个按照特定规则组织、存储和管理数据的“电子化仓库”。

对比维度 Excel表格 记事本/备忘录 专业数据库
数据容量 有限(百万行内) 很小 无限
查询速度 慢(数据多时) 手动查找 极快(毫秒级)
关系分析 困难 不可能 强大(JOIN操作)
历史回溯 版本混乱 难以查找 完整记录
多人协作 冲突频繁 无法协作 支持良好
学习成本 极低 中等
长期价值 低(易损坏) 指数增长

关键差异

  • Excel:适合静态快照,不适合持续跟踪
  • 数据库:适合动态系统,越用越有价值

image-20260130002510499

什么是数据库?

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。

每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据。

我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。

所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。

RDBMS 即关系数据库管理系统(Relational Database Management System)的特点:

  • 1.数据以表格的形式出现
  • 2.每行为各种记录名称
  • 3.每列为记录名称所对应的数据域
  • 4.许多的行和列组成一张表单
  • 5.若干的表单组成database

RDBMS 术语

在我们开始学习MySQL 数据库前,让我们先了解下RDBMS的一些术语:

  • 数据库: 数据库是一些关联表的集合。
  • 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
  • 列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。
  • 行:一行(元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
  • 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
  • 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
  • 外键:外键用于关联两个表。
  • 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
  • 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
  • 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。

MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个关系型数据库由一个或数个表格组成, 如图所示的一个表格:

img

  • 表头(header): 每一列的名称;
  • 列(col): 具有相同数据类型的数据的集合;
  • 行(row): 每一行用来描述某条记录的具体信息;
  • 值(value): 行的具体信息, 每个值必须与该列的数据类型相同;
  • 键(key): 键的值在当前列中具有唯一性。

MySQL数据库

MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

  • MySQL 是开源的,目前隶属于 Oracle 旗下产品。
  • MySQL 支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
  • MySQL 使用标准的 SQL 数据语言形式。
  • MySQL 可以运行于多个系统上,并且支持多种语言。这些编程语言包括 C、C++、Python、Java、Perl、PHP、Eiffel、Ruby 和 Tcl 等。
  • MySQL 对 PHP 有很好的支持,PHP 是很适合用于 Web 程序开发。
  • MySQL 支持大型数据库,支持 5000 万条记录的数据仓库,32 位系统表文件最大可支持 4GB,64 位系统支持最大的表文件为8TB。
  • MySQL 是可以定制的,采用了 GPL 协议,你可以修改源码来开发自己的 MySQL 系统。

MySQL 管理

启动及关闭 MySQL 服务器

Windows 系统下

启动 MySQL 服务器:

1、通过 "服务" 管理工具: 打开"运行"对话框(Win + R),输入 services.msc,找到"MySQL"服务,右击选择"启动"。

2、通过命令提示符: 打开命令提示符(以管理员身份),输入以下命令:

net start mysql

关闭MySQL服务器:

1、通过 "服务" 管理工具:同样打开"运行"对话框,输入 services.msc,找到 "MySQL" 服务,右击选择"停止"。

2、通过命令提示符: 打开命令提示符(以管理员身份),输入以下命令:

net stop mysql

Linux 系统下

1、启动 MySQL 服务:

使用 systemd命令(适用于大多数现代 Linux 发行版,如 Ubuntu、CentOS 等):

sudo systemctl start mysql

使用 service 命令(在一些较旧的发行版中):

sudo service mysql start

2、关闭 MySQL 服务:

使用 systemd:

sudo systemctl stop mysql

使用 service 命令:

sudo service mysql stop

3、重启 MySQL 服务:

使用 systemd:

sudo systemctl restart mysql

使用 service 命令:

sudo service mysql restart

4、检查 MySQL 服务状态:

使用 systemd命令:

sudo systemctl status mysql

使用 service 命令:

sudo service mysql status

MySQL 连接

安装 MySQL 后,你可以通过以下几种方式连接到 MySQL 服务端:

  • 1、使用命令行客户端连接
  • 2、使用图形化工具连接

常用 MySQL 图形化管理工具:

这里使用 Navicat 作为练习工具。

MySQL 创建数据库

我们可以在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下:

CREATE DATABASE 数据库名;

以下命令简单的演示了创建数据库的过程,数据名为 RUNOOB:

[root@host]# mysql -u root -p   
Enter password:******  # 登录后进入终端

mysql> create DATABASE RUNOOB;

建数据库的基本语法如下:

CREATE DATABASE [IF NOT EXISTS] database_name
  [CHARACTER SET charset_name]
  [COLLATE collation_name];

如果你希望在创建数据库时指定一些选项,可以使用 CREATE DATABASE 语句的其他参数,例如,你可以指定字符集和排序规则:

-- 创建数据库,用于存储应用数据
-- 如果数据库不存在则创建,避免重复创建错误
-- 使用utf8mb4字符集以支持完整的Unicode字符(包括emoji表情)
-- 使用utf8mb4_unicode_ci排序规则,提供准确的Unicode排序和大小写不敏感比较
CREATE DATABASE IF NOT EXISTS mydatabase 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;

如果数据库已经存在,执行 CREATE DATABASE 将导致错误。

为了避免这种情况,你可以在 CREATE DATABASE 语句中添加 IF NOT EXISTS 子句:

CREATE DATABASE IF NOT EXISTS mydatabase;

MySQL 删除数据库

使用普通用户登陆 MySQL 服务器,你可能需要特定的权限来创建或者删除 MySQL 数据库,所以我们这边使用 root 用户登录,root 用户拥有最高权限。

在删除数据库过程中,务必要十分谨慎,因为在执行删除命令后,所有数据将会消失。

drop 命令删除数据库

drop 命令格式:

DROP DATABASE <database_name>;        -- 直接删除数据库,不检查是否存在
或
DROP DATABASE [IF EXISTS] <database_name>;

参数说明:

  • IF EXISTS 是一个可选的子句,表示如果数据库存在才执行删除操作,避免因为数据库不存在而引发错误。
  • database_name 是你要删除的数据库的名称。

例如删除名为 RUNOOB 的数据库:

-- 直接删除数据库,不检查是否存在
mysql> DROP DATABASE RUNOOB;

-- 删除数据库,如果存在的话
DROP DATABASE IF EXISTS RUNOOB;

注意: 在执行删除数据库操作前,请确保你确实想要删除数据库及其所有数据,因为该操作是不可逆的。为了避免误操作,通常建议在执行删除之前备份数据库。

-- 删除数据库
DROP DATABASE IF EXISTS mydatabase;

image-20260130220443983

MySQL 选择数据库

在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库。


从命令提示窗口中选择 MySQL 数据库

mysql> 提示窗口中可以很简单的选择特定的数据库。

在 MySQL 中,要选择要使用的数据库,可以使用 USE 语句,以下是基本的语法:

USE database_name;

参数说明:

  • database_name 是你要选择的数据库的名称。

选择来数据库后,你的后续 SQL 查询和操作在指定的数据库 database_name 上执行。

以下实例选取了数据库 RUNOOB:

[root@host]# mysql -u root -p
Enter password:******
mysql> use RUNOOB;
Database changed
mysql>

执行以上命令后,你就已经成功选择了 RUNOOB 数据库,在后续的操作中都会在 RUNOOB 数据库中执行。

在命令行中,你可以通过以下方式选择数据库:

mysql -u your_username -p -D your_database
  • -D 参数用于指定要选择的数据库。

例如:

mysql -u root -p -D RUNOOB

在输入密码后,你将进入 MySQL 提示符,并且任何后续的查询和操作都将在 RUNOOB 数据库上执行。

请确保选择的数据库存在,否则你将收到错误消息。你可以使用 SHOW DATABASES; 查询可用的数据库,确保你要选择的数据库在列表中。

-- 创建数据库,下面是整句命令中间不能使用分号隔开
CREATE DATABASE IF NOT EXISTS mydatabase
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 选择数据库
USE mydatabase;

MySQL 数据类型

MySQL 中定义数据字段的类型对你数据库的优化是非常重要的。

MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。


数值类型

MySQL 支持所有标准 SQL 数值数据类型。

这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC),以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。

关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。

BIT数据类型保存位字段值,并且支持 MyISAM、MEMORY、InnoDB 和 BDB表。

作为 SQL 标准的扩展,MySQL 也支持整数类型 TINYINT、MEDIUMINT 和 BIGINT。下面的表显示了需要的每个整数类型的存储和范围。

类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 Bytes (-128,127) (0,255) 小整数值
SMALLINT 2 Bytes (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 Bytes (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 Bytes (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 Bytes (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
FLOAT 4 Bytes (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度 浮点数值
DOUBLE 8 Bytes (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度 浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值

日期和时间类型

表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

TIMESTAMP类型有专有的自动更新特性,将在后面描述。

类型 大小 ( bytes) 范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' YYYY-MM-DD hh:mm:ss 混合日期和时间值
TIMESTAMP 4 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYY-MM-DD hh:mm:ss 混合日期和时间值,时间戳

字符串类型

字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

类型 大小 用途
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过 255 个字符的二进制字符串
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65 535 bytes 二进制形式的长文本数据
TEXT 0-65 535 bytes 长文本数据
MEDIUMBLOB 0-16 777 215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215 bytes 中等长度文本数据
LONGBLOB 0-4 294 967 295 bytes 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295 bytes 极大文本数据

注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。

CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。

BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。

有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。


枚举与集合类型(Enumeration and Set Types)

  • ENUM: 枚举类型,用于存储单一值,可以选择一个预定义的集合。
  • SET: 集合类型,用于存储多个值,可以选择多个预定义的集合。

空间数据类型(Spatial Data Types)

GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION: 用于存储空间数据(地理信息、几何图形等)

MySQL 创建数据表

创建 MySQL 数据表需要以下信息:

  • 表名
  • 表字段名
  • 定义每个表字段的数据类型

语法

以下为创建 MySQL 数据表的 SQL 通用语法:

CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
);

参数说明:

  • table_name 是你要创建的表的名称。
  • column1, column2, ... 是表中的列名。
  • datatype 是每个列的数据类型。

以下是一个具体的实例,创建一个用户表 users

-- 创建一个用户表 users
CREATE TABLE users(
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL,
  email VARCHAR(100) NOT NULL,
  birthdate DATE,
  is_active BOOLEAN DEFAULT TRUE 
);

实例解析:

  • id: 用户 id,整数类型,自增长,作为主键。
  • username: 用户名,变长字符串,不允许为空。
  • email: 用户邮箱,变长字符串,不允许为空。
  • birthdate: 用户的生日,日期类型。
  • is_active: 用户是否已经激活,布尔类型,默认值为 true。

以上只是一个简单的实例,用到了一些常见的数据类型包括 INT, VARCHAR, DATE, BOOLEAN,你可以根据实际需要选择不同的数据类型。AUTO_INCREMENT 关键字用于创建一个自增长的列,PRIMARY KEY 用于定义主键。

如果你希望在创建表时指定数据引擎,字符集和排序规则等,可以使用 CHARACTER SETCOLLATE 子句:

CREATE TABLE mytable(
id INT PRIMARY KEY,
name VARCHAR(50)
)CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

以上代码创建一个使用 utf8mb4 字符集和 utf8mb4_general_ci 排序规则的表。

以下例子中我们将在 RUNOOB 数据库中创建数据表 runoob_tbl:

CREATE TABLE IF NOT EXISTS `runoob_tbl`(
   `runoob_id` INT UNSIGNED AUTO_INCREMENT,
   `runoob_title` VARCHAR(100) NOT NULL,
   `runoob_author` VARCHAR(40) NOT NULL,
   `submission_date` DATE,
   PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

实例解析:

  • 如果你不想字段为可以设置字段的属性为 NOT NULL,如上实例中的 runoob_title 与 runoob_author 字段, 在操作数据库时如果输入该字段的数据为空,就会报错。
  • AUTO_INCREMENT 定义列为自增的属性,一般用于主键,数值会自动加 1。
  • PRIMARY KEY 关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号 , 分隔。
  • ENGINE 设置存储引擎,CHARSET设置编码。

MySQL 删除数据表

MySQL中删除数据表是非常容易操作的,但是你在进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失。

语法

以下为删除 MySQL 数据表的通用语法:

DROP TABLE table_name;     -- 直接删除表,不检查是否存在

DROP TABLE [IF EXISTS] table_name;  -- 会检查是否存在,如果存在则删除

参数说明:

  • table_name 是要删除的表的名称。
  • IF EXISTS 是一个可选的子句,表示如果表存在才执行删除操作,避免因为表不存在而引发错误。
-- 删除表,如果存在的话
DROP TABLE IF EXISTS mytable;

-- 直接删除表,不检查是否存在
DROP TABLE mytable;

请替换 mytable 为你要删除的表的名称。

如果你只是想删除表中的所有数据,但保留表的结构,可以使用 TRUNCATE TABLE 语句:

TRUNCATE TABLE table_name;

这会清空表中的所有数据,但不会删除表本身。

注意事项:

  • 备份数据:在删除表之前,确保已经备份了数据,如果你需要的话。
  • 外键约束:如果该表与其他表有外键约束,可能需要先删除外键约束,或者确保依赖关系被处理好。
-- 删除表
DROP TABLE runoob_tbl;

MySQL 插入数据

MySQL 表中使用 INSERT INTO 语句来插入数据。

你可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据。

语法

以下为向MySQL数据表插入数据通用的 INSERT INTO SQL语法:

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

参数说明:

  • table_name 是你要插入数据的表的名称。
  • column1, column2, column3, ... 是表中的列名。
  • value1, value2, value3, ... 是要插入的具体数值。

如果数据是字符型,必须使用单引号 ' 或者双引号 ",如: 'value1', "value1"。

一个简单的实例,插入了一行数据到名为 users 的表中:

INSERT INTO users (username, email, birthdate, is_active)
VALUES ('test', 'test@runoob.com', '1990-01-01', true);
  • username: 用户名,字符串类型。
  • email: 邮箱地址,字符串类型。
  • birthdate: 用户生日, 日期类型。
  • is_active: 是否已激活,布尔类型。

如果你要插入所有列的数据,可以省略列名:

INSERT INTO users
VALUES (NULL,'test', 'test@runoob.com', '1990-01-01', true);

这里,NULL 是用于自增长列的占位符,表示系统将为 id 列生成一个唯一的值。

如果你要插入多行数据,可以在 VALUES 子句中指定多组数值:

INSERT INTO users (username, email, birthdate, is_active)
VALUES
    ('test1', 'test1@runoob.com', '1985-07-10', true),
    ('test2', 'test2@runoob.com', '1988-11-25', false),
    ('test3', 'test3@runoob.com', '1993-05-03', true);

以上代码将在 users 表中插入三行数据。

image-20260130223414895

MySQL 查询数据

MySQL 数据库使用 SELECT 语句来查询数据。

你可以通过 mysql> 命令提示窗口中在数据库中查询数据,或者通过 PHP 脚本来查询数据。

语法

以下为在 MySQL 数据库中查询数据通用的 SELECT 语法:

SELECT column1, column2, ...
FROM table_name
[WHERE condition]
[ORDER BY column_name [ASC | DESC]]
[LIMIT number];

参数说明:

  • column1, column2, ... 是你想要选择的列的名称,如果使用 * 表示选择所有列。
  • table_name 是你要从中查询数据的表的名称。
  • WHERE condition 是一个可选的子句,用于指定过滤条件,只返回符合条件的行。
  • ORDER BY column_name [ASC | DESC] 是一个可选的子句,用于指定结果集的排序顺序,默认是升序(ASC)。
  • LIMIT number 是一个可选的子句,用于限制返回的行数。

MySQL SELECT 语句简单的应用实例:

-- 选择所有列的所有行
SELECT * FROM users;

-- 选择特定列的所有行
SELECT username, email FROM users;

-- 添加 WHERE 子句,选择满足条件的行
SELECT * FROM users WHERE is_active = TRUE;

-- 添加 ORDER BY 子句,按照某列的升序排序
SELECT * FROM users ORDER BY birthdate;

-- 添加 ORDER BY 子句,按照某列的降序排序
SELECT * FROM users ORDER BY birthdate DESC;

-- 添加 LIMIT 子句,限制返回的行数
SELECT * FROM users LIMIT 10;

SELECT 语句可以是灵活的,我们可以根据实际需求组合和使用这些子句,比如同时使用 WHERE 和 ORDER BY 子句,或者使用 LIMIT 控制返回的行数。

WHERE 子句中,你可以使用各种条件运算符(如 =, <, >, <=, >=, !=),逻辑运算符(如 AND, OR, NOT),以及通配符(如 %)等。

以下是一些进阶的 SELECT 语句实例:

-- 使用 AND 运算符和通配符
SELECT * FROM users WHERE username LIKE 'j%' AND is_active = TRUE;

-- 使用 OR 运算符
SELECT * FROM users WHERE is_active = TRUE OR birthdate < '1990-01-01';

-- 使用 IN 子句
SELECT * FROM users WHERE birthdate IN ('1990-01-01', '1992-03-15', '1993-05-03');

image-20260130223752278

MySQL WHERE 子句

我们知道从 MySQL 表中使用 SELECT 语句来读取数据。

如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句中。

WHERE 子句用于在 MySQL 中过滤查询结果,只返回满足特定条件的行。

语法

以下是 SQL SELECT 语句使用 WHERE 子句从数据表中读取数据的通用语法:

SELECT column1, column2, ...
FROM table_name
WHERE condition;

参数说明:

  • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
  • table_name 是你要从中查询数据的表的名称。
  • WHERE condition 是用于指定过滤条件的子句。

更多说明:

  • 查询语句中你可以使用一个或者多个表,表之间使用逗号, 分割,并使用WHERE语句来设定查询条件。
  • 你可以在 WHERE 子句中指定任何条件。
  • 你可以使用 AND 或者 OR 指定一个或多个条件。
  • WHERE 子句也可以运用于 SQL 的 DELETE 或者 UPDATE 命令。
  • WHERE 子句类似于程序语言中的 if 条件,根据 MySQL 表中的字段值来读取指定的数据。

以下为操作符列表,可用于 WHERE 子句中。

下表中实例假定 A 为 10, B 为 20

操作符 描述 实例
= 等号,检测两个值是否相等,如果相等返回true (A = B) 返回false。
<>, != 不等于,检测两个值是否相等,如果不相等返回true (A != B) 返回 true。
> 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true (A > B) 返回false。
< 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true (A < B) 返回 true。
>= 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true (A >= B) 返回false。
<= 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true (A <= B) 返回 true。

简单实例

\1. 等于条件:

SELECT * FROM users WHERE username = 'test';

\2. 不等于条件:

SELECT * FROM users WHERE username != 'runoob';

\3. 大于条件:

SELECT * FROM products WHERE price > 50.00;

\4. 小于条件:

SELECT * FROM orders WHERE order_date < '2023-01-01';

\5. 大于等于条件:

SELECT * FROM employees WHERE salary >= 50000;

\6. 小于等于条件:

SELECT * FROM students WHERE age <= 21;

\7. 组合条件(AND、OR):

SELECT * FROM products WHERE category = 'Electronics' AND price > 100.00;

SELECT * FROM orders WHERE order_date >= '2023-01-01' OR total_amount > 1000.00;

\8. 模糊匹配条件(LIKE):

SELECT * FROM customers WHERE first_name LIKE 'J%';

\9. IN 条件:

SELECT * FROM countries WHERE country_code IN ('US', 'CA', 'MX');

\10. NOT 条件:

SELECT * FROM products WHERE NOT category = 'Clothing';

\11. BETWEEN 条件:

SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';

\12. IS NULL 条件

SELECT * FROM employees WHERE department IS NULL;

\13. IS NOT NULL 条件:

SELECT * FROM customers WHERE email IS NOT NULL;

如果我们想在 MySQL 数据表中读取指定的数据,WHERE 子句是非常有用的。

使用主键来作为 WHERE 子句的条件查询是非常快速的。

如果给定的条件在表中没有任何匹配的记录,那么查询不会返回任何数据。

MySQL UPDATE 更新

如果我们需要修改或更新 MySQL 中的数据,我们可以使用 UPDATE 命令来操作。

语法

以下是 UPDATE 命令修改 MySQL 数据表数据的通用 SQL 语法:

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

参数说明:

  • table_name 是你要更新数据的表的名称。
  • column1, column2, ... 是你要更新的列的名称。
  • value1, value2, ... 是新的值,用于替换旧的值。
  • WHERE condition 是一个可选的子句,用于指定更新的行。如果省略 WHERE 子句,将更新表中的所有行。

更多说明:

  • 你可以同时更新一个或多个字段。
  • 你可以在 WHERE 子句中指定任何条件。
  • 你可以在一个单独表中同时更新数据。

当你需要更新数据表中指定行的数据时 WHERE 子句是非常有用的。

以下实例演示了如何使用 UPDATE 语句。

\1. 更新单个列的值:

UPDATE employees
SET salary = 60000
WHERE employee_id = 101;

\2. 更新多个列的值:

UPDATE orders
SET status = 'Shipped', ship_date = '2023-03-01'
WHERE order_id = 1001;

\3. 使用表达式更新值:

UPDATE products
SET price = price * 1.1
WHERE category = 'Electronics';

以上 SQL 语句将每个属于 'Electronics' 类别的产品的价格都增加了 10%。

\4. 更新符合条件的所有行:

UPDATE students
SET status = 'Graduated';

以上 SQL 语句将所有学生的状态更新为 'Graduated'。

\5. 更新使用子查询的值:

UPDATE customers
SET total_purchases = (
    SELECT SUM(amount)
    FROM orders
    WHERE orders.customer_id = customers.customer_id
)
WHERE customer_type = 'Premium';

以上 SQL 语句通过子查询计算每个 'Premium' 类型客户的总购买金额,并将该值更新到 total_purchases 列中。

注意: 在使用 UPDATE 语句时,请确保你提供了足够的条件来确保只有你想要更新的行被修改。如果不提供 WHERE 子句,将更新表中的所有行,可能导致不可预测的结果。

MySQL DELETE 语句

你可以使用 DELETE FROM 命令来删除 MySQL 数据表中的记录。

你可以在 mysql> 命令提示符或 PHP 脚本中执行该命令。

语法

以下是 DELETE 语句从 MySQL 数据表中删除数据的通用语法:

DELETE FROM table_name
WHERE condition;

参数说明:

  • table_name 是你要删除数据的表的名称。
  • WHERE condition 是一个可选的子句,用于指定删除的行。如果省略 WHERE 子句,将删除表中的所有行。

更多说明:

  • 如果没有指定 WHERE 子句,MySQL 表中的所有记录将被删除。
  • 你可以在 WHERE 子句中指定任何条件
  • 您可以在单个表中一次性删除记录。

当你想删除数据表中指定的记录时 WHERE 子句是非常有用的。

以下实例演示了如何使用 DELETE 语句。

\1. 删除符合条件的行:

DELETE FROM students
WHERE graduation_year = 2021;

以上 SQL 语句删除了 students 表中所有 graduation_year 为 2021 的学生的记录。

\2. 删除所有行:

DELETE FROM orders;

以上 SQL 语句删除了 orders 表中的所有记录,但表结构保持不变。

\3. 使用子查询删除符合条件的行:

DELETE FROM customers
WHERE customer_id IN (
    SELECT customer_id
    FROM orders
    WHERE order_date < '2023-01-01'
);

以上 SQL 语句通过子查询删除了 orders 表中在 '2023-01-01' 之前下的订单对应的客户。

注意: 在使用 DELETE 语句时,请确保你提供了足够的条件来确保只有你想要删除的行被删除。如果不提供 WHERE 子句,将删除表中的所有行,可能导致不可预测的结果。

MySQL LIKE 子句

我们知道在 MySQL 中使用 SELECT 命令来读取数据, 同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录。

WHERE 子句中可以使用等号 = 来设定获取数据的条件,如 "runoob_author = 'RUNOOB.COM'"。

但是有时候我们需要获取 runoob_author 字段含有 "COM" 字符的所有记录,这时我们就需要在 WHERE 子句中使用 LIKE 子句。

LIKE 子句是在 MySQL 中用于在 WHERE 子句中进行模糊匹配的关键字。它通常与通配符一起使用,用于搜索符合某种模式的字符串。

LIKE 子句中使用百分号 %字符来表示任意字符,类似于UNIX或正则表达式中的星号 *****。

如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。

语法

以下是 SQL SELECT 语句使用 LIKE 子句从数据表中读取数据的通用语法:

SELECT column1, column2, ...
FROM table_name
WHERE column_name LIKE pattern;

参数说明:

  • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
  • table_name 是你要从中查询数据的表的名称。
  • column_name 是你要应用 LIKE 子句的列的名称。
  • pattern 是用于匹配的模式,可以包含通配符。

更多说明:

  • 你可以在 WHERE 子句中指定任何条件。
  • 你可以在 WHERE 子句中使用LIKE子句。
  • 你可以使用LIKE子句代替等号 =
  • LIKE 通常与 % 一同使用,类似于一个元字符的搜索。
  • 你可以使用 AND 或者 OR 指定一个或多个条件。
  • 你可以在 DELETE 或 UPDATE 命令中使用 WHERE...LIKE 子句来指定条件。

以下是一些 LIKE 子句的使用实例。

\1. 百分号通配符 %:

% 通配符表示零个或多个字符。例如,'a%' 匹配以字母 'a' 开头的任何字符串。

SELECT * FROM customers WHERE last_name LIKE 'S%';

以上 SQL 语句将选择所有姓氏以 'S' 开头的客户。

\2. 下划线通配符 _:

_ 通配符表示一个字符。例如,'_r%' 匹配第二个字母为 'r' 的任何字符串。

SELECT * FROM products WHERE product_name LIKE '_a%';

以上 SQL 语句将选择产品名称的第二个字符为 'a' 的所有产品。

\3. 组合使用 % 和 _:

SELECT * FROM users WHERE username LIKE 'a%o_';

以上 SQL 语句将匹配以字母 'a' 开头,然后是零个或多个字符,接着是 'o',最后是一个任意字符的字符串,如 'aaron'、'apol'。

\4. 不区分大小写的匹配:

SELECT * FROM employees WHERE last_name LIKE 'smi%' COLLATE utf8mb4_general_ci;

以上 SQL 语句将选择姓氏以 'smi' 开头的所有员工,不区分大小写。

LIKE 子句提供了强大的模糊搜索能力,可以根据不同的模式和需求进行定制。在使用时,请确保理解通配符的含义,并根据实际情况进行匹配。

MySQL UNION 操作符

本教程为大家介绍 MySQL UNION 操作符的语法和实例。

描述

MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合,并去除重复的行。

UNION 操作符必须由两个或多个 SELECT 语句组成,每个 SELECT 语句的列数和对应位置的数据类型必须相同。

语法

MySQL UNION 操作符语法格式:

SELECT column1, column2, ...
FROM table1
WHERE condition1
UNION
SELECT column1, column2, ...
FROM table2
WHERE condition2
[ORDER BY column1, column2, ...];

参数说明:

  • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
  • table1, table2, ... 是你要从中查询数据的表的名称。
  • condition1, condition2, ... 是每个 SELECT 语句的过滤条件,是可选的。
  • ORDER BY 子句是一个可选的子句,用于指定合并后的结果集的排序顺序。

\1. 基本的 UNION 操作:

SELECT city FROM customers
UNION
SELECT city FROM suppliers
ORDER BY city;

以上 SQL 语句将选择客户表和供应商表中所有城市的唯一值,并按城市名称升序排序。

\2. 使用过滤条件的 UNION:

SELECT product_name FROM products WHERE category = 'Electronics'
UNION
SELECT product_name FROM products WHERE category = 'Clothing'
ORDER BY product_name;

以上 SQL 语句将选择电子产品和服装类别的产品名称,并按产品名称升序排序。

\3. UNION 操作中的列数和数据类型必须相同:

SELECT first_name, last_name FROM employees
UNION
SELECT department_name, NULL FROM departments
ORDER BY first_name;

返回的结果包括了 employees 表中的 first_name 和 last_name,以及 departments 表中的 department_name 和 NULL, 所有的结果都按照 first_name 列排序。

\4. 使用 UNION ALL 不去除重复行:

SELECT city FROM customers
UNION ALL
SELECT city FROM suppliers
ORDER BY city;

以上 SQL 语句使用 UNION ALL 将客户表和供应商表中的所有城市合并在一起,不去除重复行。

UNION 操作符在合并结果集时会去除重复行,而 UNION ALL 不会去除重复行,因此 UNION ALL 的性能可能更好,但如果你确实希望去除重复行,可以使用 UNION。


演示数据库

在本教程中,我们将使用 RUNOOB 样本数据库。

下面是选自 "Websites" 表的数据:

mysql> SELECT * FROM Websites;
+----+--------------+---------------------------+-------+---------+
| id | name         | url                       | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1  | Google       | https://www.google.cm/    | 1     | USA     |
| 2  | 淘宝          | https://www.taobao.com/   | 13    | CN      |
| 3  | 菜鸟教程      | http://www.runoob.com/    | 4689  | CN      |
| 4  | 微博          | http://weibo.com/         | 20    | CN      |
| 5  | Facebook     | https://www.facebook.com/ | 3     | USA     |
| 7  | stackoverflow | http://stackoverflow.com/ |   0 | IND     |
+----+---------------+---------------------------+-------+---------+

下面是 "apps" APP 的数据:

mysql> SELECT * FROM apps;
+----+------------+-------------------------+---------+
| id | app_name   | url                     | country |
+----+------------+-------------------------+---------+
|  1 | QQ APP     | http://im.qq.com/       | CN      |
|  2 | 微博 APP | http://weibo.com/       | CN      |
|  3 | 淘宝 APP | https://www.taobao.com/ | CN      |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)

SQL UNION 实例

下面的 SQL 语句从 "Websites" 和 "apps" 表中选取所有不同的country(只有不同的值):

SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;

执行以上 SQL 输出结果如下:

img

注释:UNION 不能用于列出两个表中所有的country。如果一些网站和APP来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!


SQL UNION ALL 实例

下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的country(也有重复的值):

SELECT country FROM Websites
UNION ALL
SELECT country FROM apps
ORDER BY country;

执行以上 SQL 输出结果如下:

img


带有 WHERE 的 SQL UNION ALL

下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的中国(CN)的数据(也有重复的值):

SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;

执行以上 SQL 输出结果如下:

img

MySQL ORDER BY(排序) 语句

我们知道从 MySQL 表中使用 SELECT 语句来读取数据。

如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。

MySQL ORDER BY(排序) 语句可以按照一个或多个列的值进行升序(ASC)或降序(DESC)排序。

语法

以下是 SELECT 语句使用 ORDER BY 子句将查询数据排序后再返回数据:

SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;

参数说明:

  • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
  • table_name 是你要从中查询数据的表的名称。
  • ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ... 是用于指定排序顺序的子句。ASC 表示升序(默认),DESC 表示降序。

更多说明:

  • 你可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
  • 你可以设定多个字段来排序。
  • 你可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
  • 你可以添加 WHERE...LIKE 子句来设置条件。

以下是一些 ORDER BY 子句的使用实例。

\1. 单列排序:

SELECT * FROM products
ORDER BY product_name ASC;

以上 SQL 语句将选择产品表 products 中的所有产品,并按产品名称升序 ASC 排序。

\2. 多列排序:

SELECT * FROM employees
ORDER BY department_id ASC, hire_date DESC;

以上 SQL 语句将选择员工表 employees 中的所有员工,并先按部门 ID 升序 ASC 排序,然后在相同部门中按雇佣日期降序 DESC 排序。

\3. 使用数字表示列的位置:

SELECT first_name, last_name, salary
FROM employees
ORDER BY 3 DESC, 1 ASC;

以上 SQL 语句将选择员工表 employees 中的名字和工资列,并按第三列(salary)降序 DESC 排序,然后按第一列(first_name)升序 ASC 排序。

\4. 使用表达式排序:

SELECT product_name, price * discount_rate AS discounted_price
FROM products
ORDER BY discounted_price DESC;

以上 SQL 语句将选择产品表 products 中的产品名称和根据折扣率计算的折扣后价格,并按折扣后价格降序 DESC 排序。

5.从 MySQL 8.0.16 版本开始,可以使用 NULLS FIRST 或 NULLS LAST 处理 NULL 值:

SELECT product_name, price
FROM products
ORDER BY price DESC NULLS LAST;

以上 SQL 语句将选择产品表 products 中的产品名称和价格,并按价格降序 DESC 排序,将 NULL 值排在最后。

相反,如果你想让 NULL 值排在前面,可以这样写:

SELECT product_name, price
FROM products
ORDER BY price DESC NULLS FIRST;

ORDER BY 子句是一个强大的工具,可以根据不同的业务需求对查询结果进行排序。在实际应用中,注意选择适当的列和排序顺序,以获得符合期望的排序效果。

MySQL 序列使用(AUTO_INCREMENT)

在 MySQL 中,序列是一种自增生成数字序列的对象,是一组整数 1、2、3、...,由于一张数据表只能有一个字段自增主键。

尽管 MySQL 本身并没有内建的序列类型,但可以使用 AUTO_INCREMENT 属性来模拟序列的行为,通常 AUTO_INCREMENT 属性用于指定表中某一列的自增性。

一个使用 AUTO_INCREMENT 创建表的例子:

**CREATE** **TABLE** example_table (
  id **INT** **AUTO_INCREMENT** **PRIMARY** **KEY**,
  name **VARCHAR**(50)
);

以上例子中,id 列被定义为 INT AUTO_INCREMENT,这表示每次插入一行数据时,id 列的值会自动增加。主键约束保证了 id 列的唯一性。

当你插入一行数据时,可以不指定 id 列的值,数据库会自动为其分配一个唯一的、自增的值:

INSERT INTO example_table (name) VALUES ('John');

你也可以使用 LAST_INSERT_ID() 函数来获取刚刚插入的行的自增值:

SELECT LAST_INSERT_ID();

如果你需要获取表的当前自增值,可以使用以下语句:

SHOW TABLE STATUS LIKE 'example_table';

在结果集中,Auto_increment 列的值即为当前表的自增值。

请注意,使用 AUTO_INCREMENT 属性的列只能是整数类型(通常是 INT 或 BIGINT)。此外,如果你删除表中的某一行,其自增值不会被重新使用,而是会继续递增。如果你希望手动设置自增值,可以使用 SET 语句,但这不是一种常规的做法,因为可能引起唯一性冲突。

MySQL 函数

MySQL 有很多内置的函数,以下列出了这些函数的说明。


MySQL 字符串函数

函数 描述 实例
ASCII(s) 返回字符串 s 的第一个字符的 ASCII 码。 返回 CustomerName 字段第一个字母的 ASCII 码:SELECT ASCII(CustomerName) AS NumCodeOfFirstChar FROM Customers;
CHAR_LENGTH(s) 返回字符串 s 的字符数 返回字符串 RUNOOB 的字符数SELECT CHAR_LENGTH("RUNOOB") AS LengthOfString;
CHARACTER_LENGTH(s) 返回字符串 s 的字符数,等同于 CHAR_LENGTH(s) 返回字符串 RUNOOB 的字符数SELECT CHARACTER_LENGTH("RUNOOB") AS LengthOfString;
CONCAT(s1,s2...sn) 字符串 s1,s2 等多个字符串合并为一个字符串 合并多个字符串SELECT CONCAT("SQL ", "Runoob ", "Gooogle ", "Facebook") AS ConcatenatedString;
CONCAT_WS(x, s1,s2...sn) 同 CONCAT(s1,s2,...) 函数,但是每个字符串之间要加上 x,x 可以是分隔符 合并多个字符串,并添加分隔符:SELECT CONCAT_WS("-", "SQL", "Tutorial", "is", "fun!")AS ConcatenatedString;
FIELD(s,s1,s2...) 返回第一个字符串 s 在字符串列表(s1,s2...)中的位置 返回字符串 c 在列表值中的位置:SELECT FIELD("c", "a", "b", "c", "d", "e");
FIND_IN_SET(s1,s2) 返回在字符串s2中与s1匹配的字符串的位置 返回字符串 c 在指定字符串中的位置:SELECT FIND_IN_SET("c", "a,b,c,d,e");
FORMAT(x,n) 函数可以将数字 x 进行格式化 "#,###.##", 将 x 保留到小数点后 n 位,最后一位四舍五入。 格式化数字 "#,###.##" 形式:SELECT FORMAT(250500.5634, 2); -- 输出 250,500.56
INSERT(s1,x,len,s2) 字符串 s2 替换 s1 的 x 位置开始长度为 len 的字符串 从字符串第一个位置开始的 6 个字符替换为 runoob:SELECT INSERT("google.com", 1, 6, "runoob"); -- 输出:runoob.com
LOCATE(s1,s) 从字符串 s 中获取 s1 的开始位置 获取 b 在字符串 abc 中的位置:SELECT LOCATE('st','myteststring'); -- 5返回字符串 abc 中 b 的位置:SELECT LOCATE('b', 'abc') -- 2
LCASE(s) 将字符串 s 的所有字母变成小写字母 字符串 RUNOOB 转换为小写:SELECT LCASE('RUNOOB') -- runoob
LEFT(s,n) 返回字符串 s 的前 n 个字符 返回字符串 runoob 中的前两个字符:SELECT LEFT('runoob',2) -- ru
LOWER(s) 将字符串 s 的所有字母变成小写字母 字符串 RUNOOB 转换为小写:SELECT LOWER('RUNOOB') -- runoob
LPAD(s1,len,s2) 在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len 将字符串 xx 填充到 abc 字符串的开始处:SELECT LPAD('abc',5,'xx') -- xxabc
LTRIM(s) 去掉字符串 s 开始处的空格 去掉字符串 RUNOOB开始处的空格:SELECT LTRIM(" RUNOOB") AS LeftTrimmedString;-- RUNOOB
MID(s,n,len) 从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len) 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT MID("RUNOOB", 2, 3) AS ExtractString; -- UNO
POSITION(s1 IN s) 从字符串 s 中获取 s1 的开始位置 返回字符串 abc 中 b 的位置:SELECT POSITION('b' in 'abc') -- 2
REPEAT(s,n) 将字符串 s 重复 n 次 将字符串 runoob 重复三次:SELECT REPEAT('runoob',3) -- runoobrunoobrunoob
REPLACE(s,s1,s2) 将字符串 s2 替代字符串 s 中的字符串 s1 将字符串 abc 中的字符 a 替换为字符 x:SELECT REPLACE('abc','a','x') --xbc
REVERSE(s) 将字符串s的顺序反过来 将字符串 abc 的顺序反过来:SELECT REVERSE('abc') -- cba
RIGHT(s,n) 返回字符串 s 的后 n 个字符 返回字符串 runoob 的后两个字符:SELECT RIGHT('runoob',2) -- ob
RPAD(s1,len,s2) 在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len 将字符串 xx 填充到 abc 字符串的结尾处:SELECT RPAD('abc',5,'xx') -- abcxx
RTRIM(s) 去掉字符串 s 结尾处的空格 去掉字符串 RUNOOB 的末尾空格:SELECT RTRIM("RUNOOB ") AS RightTrimmedString; -- RUNOOB
SPACE(n) 返回 n 个空格 返回 10 个空格:SELECT SPACE(10);
STRCMP(s1,s2) 比较字符串 s1 和 s2,如果 s1 与 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1 比较字符串:SELECT STRCMP("runoob", "runoob"); -- 0
SUBSTR(s, start, length) 从字符串 s 的 start 位置截取长度为 length 的子字符串 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTR("RUNOOB", 2, 3) AS ExtractString; -- UNO
SUBSTRING(s, start, length) 从字符串 s 的 start 位置截取长度为 length 的子字符串,等同于 SUBSTR(s, start, length) 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTRING("RUNOOB", 2, 3) AS ExtractString; -- UNO
SUBSTRING_INDEX(s, delimiter, number) 返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。 如果 number 是正数,返回第 number 个字符左边的字符串。 如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。 SELECT SUBSTRING_INDEX('a*b','*',1) -- a SELECT SUBSTRING_INDEX('a*b','*',-1) -- b SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a*b*c*d*e','*',3),'*',-1) -- c
TRIM(s) 去掉字符串 s 开始和结尾处的空格 去掉字符串 RUNOOB 的首尾空格:SELECT TRIM(' RUNOOB ') AS TrimmedString;
UCASE(s) 将字符串转换为大写 将字符串 runoob 转换为大写:SELECT UCASE("runoob"); -- RUNOOB
UPPER(s) 将字符串转换为大写 将字符串 runoob 转换为大写:SELECT UPPER("runoob"); -- RUNOOB

MySQL 数字函数

函数名 描述 实例
ABS(x) 返回 x 的绝对值 返回 -1 的绝对值:SELECT ABS(-1) -- 返回1
ACOS(x) 求 x 的反余弦值(单位为弧度),x 为一个数值 SELECT ACOS(0.25);
ASIN(x) 求反正弦值(单位为弧度),x 为一个数值 SELECT ASIN(0.25);
ATAN(x) 求反正切值(单位为弧度),x 为一个数值 SELECT ATAN(2.5);
ATAN2(n, m) 求反正切值(单位为弧度) SELECT ATAN2(-0.8, 2);
AVG(expression) 返回一个表达式的平均值,expression 是一个字段 返回 Products 表中Price 字段的平均值:SELECT AVG(Price) AS AveragePrice FROM Products;
CEIL(x) 返回大于或等于 x 的最小整数 SELECT CEIL(1.5) -- 返回2
CEILING(x) 返回大于或等于 x 的最小整数 SELECT CEILING(1.5); -- 返回2
COS(x) 求余弦值(参数是弧度) SELECT COS(2);
COT(x) 求余切值(参数是弧度) SELECT COT(6);
COUNT(expression) 返回查询的记录总数,expression 参数是一个字段或者 * 号 返回 Products 表中 products 字段总共有多少条记录:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;
DEGREES(x) 将弧度转换为角度 SELECT DEGREES(3.1415926535898) -- 180
n DIV m 整除,n 为被除数,m 为除数 计算 10 除于 5:SELECT 10 DIV 5; -- 2
EXP(x) 返回 e 的 x 次方 计算 e 的三次方:SELECT EXP(3) -- 20.085536923188
FLOOR(x) 返回小于或等于 x 的最大整数 小于或等于 1.5 的整数:SELECT FLOOR(1.5) -- 返回1
GREATEST(expr1, expr2, expr3, ...) 返回列表中的最大值 返回以下数字列表中的最大值:SELECT GREATEST(3, 12, 34, 8, 25); -- 34返回以下字符串列表中的最大值:SELECT GREATEST("Google", "Runoob", "Apple"); -- Runoob
LEAST(expr1, expr2, expr3, ...) 返回列表中的最小值 返回以下数字列表中的最小值:SELECT LEAST(3, 12, 34, 8, 25); -- 3返回以下字符串列表中的最小值:SELECT LEAST("Google", "Runoob", "Apple"); -- Apple
LN 返回数字的自然对数,以 e 为底。 返回 2 的自然对数:SELECT LN(2); -- 0.6931471805599453
LOG(x) 或 LOG(base, x) 返回自然对数(以 e 为底的对数),如果带有 base 参数,则 base 为指定带底数。 SELECT LOG(20.085536923188) -- 3 SELECT LOG(2, 4); -- 2
LOG10(x) 返回以 10 为底的对数 SELECT LOG10(100) -- 2
LOG2(x) 返回以 2 为底的对数 返回以 2 为底 6 的对数:SELECT LOG2(6); -- 2.584962500721156
MAX(expression) 返回字段 expression 中的最大值 返回数据表 Products 中字段 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products;
MIN(expression) 返回字段 expression 中的最小值 返回数据表 Products 中字段 Price 的最小值:SELECT MIN(Price) AS MinPrice FROM Products;
MOD(x,y) 返回 x 除以 y 以后的余数 5 除于 2 的余数:SELECT MOD(5,2) -- 1
PI() 返回圆周率(3.141593) SELECT PI() --3.141593
POW(x,y) 返回 x 的 y 次方 2 的 3 次方:SELECT POW(2,3) -- 8
POWER(x,y) 返回 x 的 y 次方 2 的 3 次方:SELECT POWER(2,3) -- 8
RADIANS(x) 将角度转换为弧度 180 度转换为弧度:SELECT RADIANS(180) -- 3.1415926535898
RAND() 返回 0 到 1 的随机数 SELECT RAND() --0.93099315644334
ROUND(x [,y]) 返回离 x 最近的整数,可选参数 y 表示要四舍五入的小数位数,如果省略,则返回整数。 SELECT ROUND(1.23456) --1 SELECT ROUND(345.156, 2) -- 345.16
SIGN(x) 返回 x 的符号,x 是负数、0、正数分别返回 -1、0 和 1 SELECT SIGN(-10) -- (-1)
SIN(x) 求正弦值(参数是弧度) SELECT SIN(RADIANS(30)) -- 0.5
SQRT(x) 返回x的平方根 25 的平方根:SELECT SQRT(25) -- 5
SUM(expression) 返回指定字段的总和 计算 OrderDetails 表中字段 Quantity 的总和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails;
TAN(x) 求正切值(参数是弧度) SELECT TAN(1.75); -- -5.52037992250933
TRUNCATE(x,y) 返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入) SELECT TRUNCATE(1.23456,3) -- 1.234

MySQL 日期函数

函数名 描述 实例
ADDDATE(d,n) 计算起始日期 d 加上 n 天的日期 SELECT ADDDATE("2017-06-15", INTERVAL 10 DAY); ->2017-06-25
ADDTIME(t,n) n 是一个时间表达式,时间 t 加上时间表达式 n 加 5 秒:SELECT ADDTIME('2011-11-11 11:11:11', 5); ->2011-11-11 11:11:16 (秒)添加 2 小时, 10 分钟, 5 秒:SELECT ADDTIME("2020-06-15 09:34:21", "2:10:5"); -> 2020-06-15 11:44:26
CURDATE() 返回当前日期 SELECT CURDATE(); -> 2018-09-19
CURRENT_DATE() 返回当前日期 SELECT CURRENT_DATE(); -> 2018-09-19
CURRENT_TIME 返回当前时间 SELECT CURRENT_TIME(); -> 19:59:02
CURRENT_TIMESTAMP() 返回当前日期和时间 SELECT CURRENT_TIMESTAMP() -> 2018-09-19 20:57:43
CURTIME() 返回当前时间 SELECT CURTIME(); -> 19:59:02
DATE() 从日期或日期时间表达式中提取日期值 SELECT DATE("2017-06-15"); -> 2017-06-15
DATEDIFF(d1,d2) 计算日期 d1->d2 之间相隔的天数 SELECT DATEDIFF('2001-01-01','2001-02-02') -> -32
DATE_ADD(d,INTERVAL expr type) 计算起始日期 d 加上一个时间段后的日期,type 值可以是:MICROSECONDSECONDMINUTEHOURDAYWEEKMONTHQUARTERYEARSECOND_MICROSECONDMINUTE_MICROSECONDMINUTE_SECONDHOUR_MICROSECONDHOUR_SECONDHOUR_MINUTEDAY_MICROSECONDDAY_SECONDDAY_MINUTEDAY_HOURYEAR_MONTH SELECT DATE_ADD("2017-06-15", INTERVAL 10 DAY); -> 2017-06-25 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL 15 MINUTE); -> 2017-06-15 09:49:21 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL -3 HOUR); ->2017-06-15 06:34:21 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL -3 MONTH); ->2017-03-15 09:34:21
DATE_FORMAT(d,f) 按表达式 f的要求显示日期 d SELECT DATE_FORMAT('2011-11-11 11:11:11','%Y-%m-%d %r') -> 2011-11-11 11:11:11 AM
DATE_SUB(date,INTERVAL expr type) 函数从日期减去指定的时间间隔。 Orders 表中 OrderDate 字段减去 2 天:SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 2 DAY) AS OrderPayDate FROM Orders
DAY(d) 返回日期值 d 的日期部分 SELECT DAY("2017-06-15"); -> 15
DAYNAME(d) 返回日期 d 是星期几,如 Monday,Tuesday SELECT DAYNAME('2011-11-11 11:11:11') ->Friday
DAYOFMONTH(d) 计算日期 d 是本月的第几天 SELECT DAYOFMONTH('2011-11-11 11:11:11') ->11
DAYOFWEEK(d) 日期 d 今天是星期几,1 星期日,2 星期一,以此类推 SELECT DAYOFWEEK('2011-11-11 11:11:11') ->6
DAYOFYEAR(d) 计算日期 d 是本年的第几天 SELECT DAYOFYEAR('2011-11-11 11:11:11') ->315
EXTRACT(type FROM d) 从日期 d 中获取指定的值,type 指定返回的值。 type可取值为: MICROSECONDSECONDMINUTEHOURDAYWEEKMONTHQUARTERYEARSECOND_MICROSECONDMINUTE_MICROSECONDMINUTE_SECONDHOUR_MICROSECONDHOUR_SECONDHOUR_MINUTEDAY_MICROSECONDDAY_SECONDDAY_MINUTEDAY_HOURYEAR_MONTH SELECT EXTRACT(MINUTE FROM '2011-11-11 11:11:11') -> 11
FROM_DAYS(n) 计算从 0000 年 1 月 1 日开始 n 天后的日期 SELECT FROM_DAYS(1111) -> 0003-01-16
HOUR(t) 返回 t 中的小时值 SELECT HOUR('1:2:3') -> 1
LAST_DAY(d) 返回给给定日期的那一月份的最后一天 SELECT LAST_DAY("2017-06-20"); -> 2017-06-30
LOCALTIME() 返回当前日期和时间 SELECT LOCALTIME() -> 2018-09-19 20:57:43
LOCALTIMESTAMP() 返回当前日期和时间 SELECT LOCALTIMESTAMP() -> 2018-09-19 20:57:43
MAKEDATE(year, day-of-year) 基于给定参数年份 year 和所在年中的天数序号 day-of-year 返回一个日期 SELECT MAKEDATE(2017, 3); -> 2017-01-03
MAKETIME(hour, minute, second) 组合时间,参数分别为小时、分钟、秒 SELECT MAKETIME(11, 35, 4); -> 11:35:04
MICROSECOND(date) 返回日期参数所对应的微秒数 SELECT MICROSECOND("2017-06-20 09:34:00.000023"); -> 23
MINUTE(t) 返回 t 中的分钟值 SELECT MINUTE('1:2:3') -> 2
MONTHNAME(d) 返回日期当中的月份名称,如 November SELECT MONTHNAME('2011-11-11 11:11:11') -> November
MONTH(d) 返回日期d中的月份值,1 到 12 SELECT MONTH('2011-11-11 11:11:11') ->11
NOW() 返回当前日期和时间 SELECT NOW() -> 2018-09-19 20:57:43
PERIOD_ADD(period, number) 为 年-月 组合日期添加一个时段 SELECT PERIOD_ADD(201703, 5); -> 201708
PERIOD_DIFF(period1, period2) 返回两个时段之间的月份差值 SELECT PERIOD_DIFF(201710, 201703); -> 7
QUARTER(d) 返回日期d是第几季节,返回 1 到 4 SELECT QUARTER('2011-11-11 11:11:11') -> 4
SECOND(t) 返回 t 中的秒钟值 SELECT SECOND('1:2:3') -> 3
SEC_TO_TIME(s) 将以秒为单位的时间 s 转换为时分秒的格式 SELECT SEC_TO_TIME(4320) -> 01:12:00
STR_TO_DATE(string, format_mask) 将字符串转变为日期 SELECT STR_TO_DATE("August 10 2017", "%M %d %Y"); -> 2017-08-10
SUBDATE(d,n) 日期 d 减去 n 天后的日期 SELECT SUBDATE('2011-11-11 11:11:11', 1) ->2011-11-10 11:11:11 (默认是天)
SUBTIME(t,n) 时间 t 减去 n 秒的时间 SELECT SUBTIME('2011-11-11 11:11:11', 5) ->2011-11-11 11:11:06 (秒)
SYSDATE() 返回当前日期和时间 SELECT SYSDATE() -> 2018-09-19 20:57:43
TIME(expression) 提取传入表达式的时间部分 SELECT TIME("19:30:10"); -> 19:30:10
TIME_FORMAT(t,f) 按表达式 f 的要求显示时间 t SELECT TIME_FORMAT('11:11:11','%r') 11:11:11 AM
TIME_TO_SEC(t) 将时间 t 转换为秒 SELECT TIME_TO_SEC('1:12:00') -> 4320
TIMEDIFF(time1, time2) 计算时间差值 mysql> SELECT TIMEDIFF("13:10:11", "13:10:10"); -> 00:00:01 mysql> SELECT TIMEDIFF('2000:01:01 00:00:00', -> '2000:01:01 00:00:00.000001'); -> '-00:00:00.000001' mysql> SELECT TIMEDIFF('2008-12-31 23:59:59.000001', -> '2008-12-30 01:01:01.000002'); -> '46:58:57.999999'
TIMESTAMP(expression, interval) 单个参数时,函数返回日期或日期时间表达式;有2个参数时,将参数加和 mysql> SELECT TIMESTAMP("2017-07-23", "13:10:11"); -> 2017-07-23 13:10:11 mysql> SELECT TIMESTAMP('2003-12-31'); -> '2003-12-31 00:00:00' mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00'); -> '2004-01-01 00:00:00'
TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) 计算时间差,返回 datetime_expr2 − datetime_expr1 的时间差 mysql> SELECT TIMESTAMPDIFF(DAY,'2003-02-01','2003-05-01'); // 计算两个时间相隔多少天 -> 89 mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01'); // 计算两个时间相隔多少月 -> 3 mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01'); // 计算两个时间相隔多少年 -> -1 mysql> SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55'); // 计算两个时间相隔多少分钟 -> 128885
TO_DAYS(d) 计算日期 d 距离 0000 年 1 月 1 日的天数 SELECT TO_DAYS('0001-01-01 01:01:01') -> 366
WEEK(d) 计算日期 d 是本年的第几个星期,范围是 0 到 53 SELECT WEEK('2011-11-11 11:11:11') -> 45
WEEKDAY(d) 日期 d 是星期几,0 表示星期一,1 表示星期二 SELECT WEEKDAY("2017-06-15"); -> 3
WEEKOFYEAR(d) 计算日期 d 是本年的第几个星期,范围是 0 到 53 SELECT WEEKOFYEAR('2011-11-11 11:11:11') -> 45
YEAR(d) 返回年份 SELECT YEAR("2017-06-15"); -> 2017
YEARWEEK(date, mode) 返回年份及第几周(0到53),mode 中 0 表示周天,1表示周一,以此类推 SELECT YEARWEEK("2017-06-15"); -> 201724

MySQL 高级函数

函数名 描述 实例
BIN(x) 返回 x 的二进制编码,x 为十进制数 15 的 2 进制编码:SELECT BIN(15); -- 1111
BINARY(s) 将字符串 s 转换为二进制字符串 SELECT BINARY "RUNOOB"; -> RUNOOB
CASE expression WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... WHEN conditionN THEN resultN ELSE result END CASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回 result,而当有一个成立之后,后面的就不执行了。 SELECT CASE  WHEN 1 > 0  THEN '1 > 0'  WHEN 2 > 0  THEN '2 > 0'  ELSE '3 > 0'  END ->1 > 0
CAST(x AS type) 转换数据类型 字符串日期转换为日期:SELECT CAST("2017-08-29" AS DATE); -> 2017-08-29
COALESCE(expr1, expr2, ...., expr_n) 返回参数中的第一个非空表达式(从左向右) SELECT COALESCE(NULL, NULL, NULL, 'runoob.com', NULL, 'google.com'); -> runoob.com
CONNECTION_ID() 返回唯一的连接 ID SELECT CONNECTION_ID(); -> 4292835
CONV(x,f1,f2) 返回 f1 进制数变成 f2 进制数 SELECT CONV(15, 10, 2); -> 1111
CONVERT(s USING cs) 函数将字符串 s 的字符集变成 cs SELECT CHARSET('ABC') ->utf-8 SELECT CHARSET(CONVERT('ABC' USING gbk)) ->gbk
CURRENT_USER() 返回当前用户 SELECT CURRENT_USER(); -> guest@%
DATABASE() 返回当前数据库名 SELECT DATABASE(); -> runoob
IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。 SELECT IF(1 > 0,'正确','错误') ->正确
IFNULL(v1,v2) 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。 SELECT IFNULL(null,'Hello Word') ->Hello Word
ISNULL(expression) 判断表达式是否为 NULL SELECT ISNULL(NULL); ->1
LAST_INSERT_ID() 返回最近生成的 AUTO_INCREMENT 值 SELECT LAST_INSERT_ID(); ->6
NULLIF(expr1, expr2) 比较两个字符串,如果字符串 expr1 与 expr2 相等 返回 NULL,否则返回 expr1 SELECT NULLIF(25, 25); ->
SESSION_USER() 返回当前用户 SELECT SESSION_USER(); -> guest@%
SYSTEM_USER() 返回当前用户 SELECT SYSTEM_USER(); -> guest@%
USER() 返回当前用户 SELECT USER(); -> guest@%
VERSION() 返回数据库的版本号 SELECT VERSION() -> 5.6.34

以下是 MySQL 8.0 版本新增的一些常用函数:

函数 描述 实例
JSON_OBJECT() 将键值对转换为 JSON 对象 SELECT JSON_OBJECT('key1', 'value1', 'key2', 'value2')
JSON_ARRAY() 将值转换为 JSON 数组 SELECT JSON_ARRAY(1, 2, 'three')
JSON_EXTRACT() 从 JSON 字符串中提取指定的值 SELECT JSON_EXTRACT('{"name": "John", "age": 30}', '$.name')
JSON_CONTAINS() 检查一个 JSON 字符串是否包含指定的值 SELECT JSON_CONTAINS('{"name": "John", "age": 30}', 'John', '$.name')
ROW_NUMBER() 为查询结果中的每一行分配一个唯一的数字 SELECT ROW_NUMBER() OVER(ORDER BY id) AS row_number, name FROM users
RANK() 为查询结果中的每一行分配一个排名 SELECT RANK() OVER(ORDER BY score DESC) AS rank, name, score FROM students

MySQL Python 连接与使用

MySQL 是最流行的开源关系型数据库之一,而 Python 是当今最受欢迎的编程语言之一。将 Python 与 MySQL 结合使用,可以让我们轻松地开发数据库驱动的应用程序。

本文将详细介绍如何使用 Python 连接和操作 MySQL 数据库,内容包含如下:

  1. 如何安装 MySQL Python 驱动
  2. 建立和关闭数据库连接
  3. 执行各种 SQL 查询
  4. 事务管理和错误处理
  5. 数据库操作的最佳实践

准备工作

安装必要的软件

在开始之前,请确保你已经安装了以下软件:

  • Python (推荐 3.6 或更高版本)
  • MySQL Server (社区版即可)
  • MySQL Connector/Python (Python 的 MySQL 驱动)

安装 MySQL Connector/Python

可以通过 pip 安装 MySQL 官方提供的 Python 驱动:

pip install mysql-connector-python

或者安装 PyMySQL (另一个流行的 MySQL Python 驱动):

pip install pymysql

连接 MySQL 数据库

建立基本连接

以下是使用 mysql-connector-python 建立数据库连接的基本代码:

import mysql.connector

# 创建数据库连接
db = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  password="yourpassword",
  database="yourdatabase"
)

print("数据库连接成功!")

连接参数说明

  • host: MySQL 服务器地址 (本地为 "localhost")
  • user: 数据库用户名
  • password: 用户密码
  • database: 要连接的数据库名称 (可选)

使用 PyMySQL 连接

如果你选择使用 PyMySQL,连接方式略有不同:

import pymysql

# 创建数据库连接
db = pymysql.connect(
  host="localhost",
  user="yourusername",
  password="yourpassword",
  database="yourdatabase"
)

print("数据库连接成功!")

执行 SQL 查询

创建游标对象

在执行 SQL 语句前,我们需要创建一个游标(cursor)对象:

cursor = db.cursor()

执行 SELECT 查询

cursor.execute("SELECT * FROM your_table")

# 获取所有结果
results = cursor.fetchall()

for row in results:
  print(row)

执行 INSERT, UPDATE, DELETE 操作

# 插入数据
sql = "INSERT INTO users (name, age) VALUES (%s, %s)"
values = ("张三", 25)
cursor.execute(sql, values)

# 提交事务
db.commit()

print(cursor.rowcount, "条记录插入成功")

使用参数化查询

为了防止 SQL 注入,应该始终使用参数化查询:

sql = "SELECT * FROM users WHERE name = %s"
name = ("张三",)
cursor.execute(sql, name)

关闭连接

正确关闭连接

完成数据库操作后,应该关闭游标和连接:

cursor.close()
db.close()
print("数据库连接已关闭")

使用 with 语句

Python 的 with 语句可以自动管理资源:

with mysql.connector.connect(
  host="localhost",
  user="yourusername",
  password="yourpassword",
  database="yourdatabase"
) as db:
  with db.cursor() as cursor:
    cursor.execute("SELECT * FROM users")
    results = cursor.fetchall()
    for row in results:
      print(row)
# 离开with块后连接会自动关闭

最佳实践

连接池

对于频繁连接数据库的应用,建议使用连接池:

from mysql.connector import pooling

# 创建连接池
db_pool = pooling.MySQLConnectionPool(
  pool_name="mypool",
  pool_size=5,
  host="localhost",
  user="yourusername",
  password="yourpassword",
  database="yourdatabase"
)

# 从连接池获取连接
db = db_pool.get_connection()

ORM 框架

对于复杂应用,可以考虑使用 ORM (对象关系映射) 框架,如 SQLAlchemy 或 Django ORM。

posted @ 2026-01-30 23:17  Q&25  阅读(4)  评论(0)    收藏  举报