点击上方蓝字关注我,我们一起学编程
如果觉得内容还不错,请帮忙分享一下
有任何疑问或者想看的内容,欢迎私信
微信搜索《编程笔记本》(codingbook2020),获取更多干活。
今天我们来学习一下 MySQL 的基本操作。
MySQL 基础教程
文章目录
- MySQL 基础教程
- 1. 简介
- 2. 安装
- 3. 管理
- 4. PHP 语法
- 5. 连接
- 6. 创建数据库
- 7. 删除数据库
- 8. 选择数据库
- 9. 数据类型
- 10. 创建数据表
- 11. 删除数据表
- 12. 插入数据
- 13. 查询数据
- 14. WHERE 子句
- 15. UPDATE 更新
- 16. DELETE 语句
- 17. LIKE 子句
- 18. UNION 操作符
- 19. 排序
- 20. GROUP BY 语句
- 21. 连接的使用
- 22. NULL 值处理
- 23. 正则表达式
- 24. 事务
- 25. ALTER 命令
- 26. 索引
- 27. 临时表
- 28. 复制表
- 29. 元数据
- 30. 序列使用
- 31. 处理重复数据
- 32. MySQL 及 SQL 注入
- 33. 导出数据
- 34. 导入数据
- 35. MySQL 函数
- 36. 运算符
1. 简介
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。
什么是数据库?
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。
每个数据库都有一个或多个不同的 API 用于创建、访问、管理、搜索和复制所保存的数据。我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。
所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
RDBMS 即关系数据库管理系统(Relational Database Management System)的特点:
- 数据以表格的形式出现
- 每行为各种记录名称
- 每列为记录名称所对应的数据域
- 许多的行和列组成一张表单
- 若干的表单组成 database
RDBMS 术语
在我们开始学习MySQL 数据库前,让我们先了解下RDBMS的一些术语:
- 数据库:数据库是一些关联表的集合。
- 数据表:表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
- 列:一列(数据元素)包含了相同类型的数据,例如邮政编码的数据。
- 行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
- 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
- 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
- 参照完整性:参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
MySQL 数据库
MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
- MySQL 是开源的,所以你不需要支付额外的费用。
- 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 系统。
2. 安装
笔者使用的是 Linux 操作系统,所以仅简单介绍本系统中 MySQL 的安装方式,其他操作系统的安装方式可以在 MySQL 的官网找到相关信息。
Linux/UNIX 上安装 MySQL
sudo apt install mysql-server
sudo apt install mysql-client
由于 MySQL 在 ubuntu 的软件列表中,所以可以直接在线安装。
3. 管理
Linux 上启动及关闭 MySQL 服务器
直接使用 mysql
即可启动服务器,使用 exit
即可关闭服务器:
root@jincheng-PC:~# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 10.1.37-MariaDB-0+deb9u1 Debian 9.6
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> exit
Bye
root@jincheng-PC:~#
常用命令:
USE 数据库名
:
选择要操作的 Mysql 数据库,使用该命令后所有 Mysql 命令都只针对该数据库。
MariaDB [(none)]> USE CODINGBOOK;
Database changed
MariaDB [CODINGBOOK]>
SHOW DATABASES
:
列出 MySQL 数据库管理系统的数据库列表。
MariaDB [CODINGBOOK]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
SHOW TABLES
:
显示指定数据库的所有表,使用该命令前需要使用 use 命令来选择要操作的数据库。
MariaDB [CODINGBOOK]> SHOW TABLES;
Empty set (0.00 sec)
MariaDB [CODINGBOOK]>
由于数据库 CODINGBOOK
刚刚创建,所以里面没有表格,显示为空。下面我们来创建一个表格:tb_test_student
,并插入几条记录:
MariaDB [CODINGBOOK]> CREATE TABLE tb_test_student (
-> id INT,
-> name CHAR(20)
-> );
Query OK, 0 rows affected (0.42 sec)
MariaDB [CODINGBOOK]> INSERT INTO tb_test_student (id, name) VALUES
-> (1, "jincheng"),
-> (2, "zhangyaling");
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW TABLES;
+--------------------+
| Tables_in_CODINGBOOK |
+--------------------+
| tb_test_student |
+--------------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
SHOW COLUMNS FROM 数据表
:
显示数据表的属性、属性类型、主键信息、是否为 NULL、默认值等其他信息。
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM tb_test_student;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(20) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.41 sec)
MariaDB [CODINGBOOK]>
SHOW INDEX FROM 数据表
:
显示数据表的详细索引信息,包括PRIMARY KEY
(主键)。由于我们刚才创建的数据表tb_test_student
没有索引,我们先为其添加索引,再来查看索引:
MariaDB [CODINGBOOK]> CREATE INDEX idx_id ON tb_test_student(id);
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW INDEX FROM tb_test_student;
+-----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb_test_student | 1 | idx_id | 1 | id | A | 2 | NULL | NULL | YES | BTREE | | |
+-----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
4. PHP 语法
MySQL 可应用于多种语言,包括 PERL, C, C++, JAVA 和 PHP。 在这些语言中,Mysql 在 PHP 的 web 开发中是应用最广泛。PHP 提供了多种方式来访问和操作 Mysql 数据库记录。PHP Mysqli 函数格式如下:
mysqli_function(value, value, ...);
以上格式中 function 部分描述了 mysql 函数的功能,如:
mysqli_connect($connect);
mysqli_query($connect,"SQL 语句");
mysqli_fetch_array()
mysqli_close()
以下实例展示了 PHP 调用 mysql 函数的语法:
<?php
$retval = mysqli_function(value, [value,...]);
if( !$retval )
{
die ( "相关错误信息" );
}
// 其他 MySQL 或 PHP 语句
?>
5. 连接
使用 PHP 脚本连接 MySQL:
PHP 提供了 mysqli_connect()
函数来连接数据库。该函数有 6 个参数,在成功链接到 MySQL 后返回连接标识,失败返回 FALSE 。语法为:
mysqli_connect(host, username, password, dbname, port, socket);
其中:
- host:可选。规定主机名或 IP 地址。
- username:可选。规定 MySQL 用户名。
- password:可选。规定 MySQL 密码。
- dbname:可选。规定默认使用的数据库。
- port:可选。规定尝试连接到 MySQL 服务器的端口号。
- socket:可选。规定 socket 或要使用的已命名 pipe
使用 PHP 脚本断开 MySQL 连接:
你可以使用 PHP 的 mysqli_close()
函数来断开与 MySQL 数据库的链接。该函数只有一个参数为 mysqli_connect()
函数创建连接成功后返回的 MySQL 连接标识符。语法为:
bool mysqli_close ( mysqli $link )
本函数关闭指定的连接标识所关联的到 MySQL 服务器的非持久连接。如果没有指定 link_identifier ,则关闭上一个打开的连接。
提示:通常不需要使用 mysqli_close(),因为已打开的非持久连接会在脚本执行完毕后自动关闭。
一个实例:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql 服务器主机地址
$dbuser = 'root'; // mysql 用户名
$dbpass = '\''; // mysql 用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(!$conn)
{
die('Could not connect: ' . mysqli_error());
}
echo "数据库连接成功!\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
数据库连接成功!
root@jincheng-PC:~#
*/
6. 创建数据库
在命令行创建数据库:
我们可以在登陆 MySQL 服务后,使用 create
命令创建数据库,语法如下:
CREATE DATABASE 数据库名;
以下命令简单的演示了创建数据库的过程,数据名为 CODINGBOOK:
MariaDB [(none)]> CREATE DATABASE CODINGBOOK;
Query OK, 1 row affected (0.00 sec)
现在我们使用 SHOW DATABASES
命令查看一下数据库是否创建成功:
MariaDB [CODINGBOOK]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可以看到,数据库 CODINGBOOK
创建成功。
使用 PHP 脚本创建数据库:
PHP 使用 mysqli_query 函数来创建或者删除 MySQL 数据库。该函数有两个参数,在执行成功时返回 TRUE,否则返回 FALSE。语法为:
mysqli_query(connection, query, resultmode);
其中:
- connection:必需。规定要使用的 MySQL 连接。
- query:必需。规定查询字符串。
- resultmode:可选。一个常量,可以是下列值中的任意一个:MYSQLI_USE_RESULT(需要检索大量数据时使用)、MYSQLI_STORE_RESULT(默认)
一个实例:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接错误: ' . mysqli_error($conn));
}
echo "连接成功\n";
$sql = 'CREATE DATABASE CODINGBOOK_2';
$retval = mysqli_query($conn,$sql );
if(! $retval )
{
die('创建数据库失败: ' . mysqli_error($conn));
}
echo "数据库 CODINGBOOK_2 创建成功\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
连接成功
数据库 CODINGBOOK_2 创建成功
root@jincheng-PC:~#
*/
如果数据库已存在,执行后返回如下结果:
连接成功
创建数据库失败:Can't create database 'CODINGBOOK_2'; database exists
现在我们使用 SHOW DATABASES
命令查看一下数据库是否创建成功:
MariaDB [CODINGBOOK]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| CODINGBOOK_2 |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可以看到,可以看到,数据库 CODINGBOOK_2
创建成功。
7. 删除数据库
在命令行删除数据库:
使用 drop
命令删除数据库,语法为:
DROP DATABASE 数据库名;
我们先创建一个数据库,再将其删除:
MariaDB [CODINGBOOK]> CREATE DATABASE CODINGBOOK_3;
Query OK, 1 row affected (0.00 sec)
MariaDB [CODINGBOOK]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| CODINGBOOK_2 |
| CODINGBOOK_3 |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> DROP DATABASE CODINGBOOK_3;
Query OK, 0 rows affected (0.00 sec)
MariaDB [CODINGBOOK]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| CODINGBOOK_2 |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本删除数据库:
与创建数据库的命令相同,使用 mysqli_query
函数删除数据库。
一个实例:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo "连接成功\n";
$sql = 'DROP DATABASE CODINGBOOK_2';
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('删除数据库失败: ' . mysqli_error($conn));
}
echo "数据库 CODINGBOOK_2 删除成功\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
连接成功
数据库 CODINGBOOK_2 删除成功
root@jincheng-PC:~#
*/
再次查看数据库,发现 CODINGBOOK_2
确实已经被删除了。
MariaDB [CODINGBOOK]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
8. 选择数据库
在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库。
从命令行选择数据库:
使用 use
命令选择数据库。
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| CODINGBOOK |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
MariaDB [(none)]> USE CODINGBOOK;
Database changed
MariaDB [CODINGBOOK]>
注意:所有的数据库名,表名,表字段都是区分大小写的。所以你在使用 SQL 命令时需要输入正确的名称,但是 Mysql 命令是不区分大小写的。
使用PHP脚本选择数据库:
PHP 提供了函数 mysqli_select_db
来选取一个数据库。函数在执行成功后返回 TRUE ,否则返回 FALSE 。语法为:
mysqli_select_db(connection,dbname);
其中:
- connection:必需。规定要使用的 MySQL 连接。
- dbname:必需,规定要使用的默认数据库。
一个实例:
以下实例展示了如何使用 mysqli_select_db
函数来选取一个数据库:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo '连接成功';
mysqli_select_db($conn, 'CODINGBOOK');
mysqli_close($conn);
?>
9. 数据类型
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 | -128~127 | 0~255 | 小整数值 |
SMALLINT | 2 | -32768~32767 | 0~65535 | 大整数值 |
MEDIUMINT | 3 | -8388608~8388607 | 0~1677215 | 大整数值 |
INTEGER | 4 | -2147483648~2147483647 | 0~4294967295 | 大整数值 |
BIGINT | 8 | -9223372036854775808~9 223372036854775807 | 0~18446744073709551615 | 极大整数值 |
FLOAT | 4 | -3.402823466E+38-1.175494351E-38,0,1.175494351E-383.402823466351E+38 | 0,1.175494351E-38~3.402823466E+38 | 单精度浮点值 |
DOUBLE | 8 | -1.7976931348623157E+308-2.2250738585072014E-308,0,2.2250738585072014E-3081.7976931348623157E+308 | 0,2.2250738585072014E-308~1.7976931348623157E+308 | 双精度浮点值 |
DECIMAL | 对于 DECIMAL(M,D): 若 M>D ,为 M+2 ,否则为 D+2 | 依赖于 M 和 D 的值 | 依赖于 M 和 D 的值 | 小数值 |
时间/日期类型:
类型 | 大小(字节) | 范围 | 格式 | 用途 |
---|---|---|---|---|
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:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |
字符串类型:
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字节 | 定长字符串 |
VARCHAR | 0-65535 字节 | 变长字符串 |
TINYBLOB | 0-255字节 | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255字节 | 短文本字符串 |
BLOB | 0-65 535字节 | 二进制形式的长文本数据 |
TEXT | 0-65 535字节 | 长文本数据 |
MEDIUMBLOB | 0-16 777 215字节 | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295字节 | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295字节 | 极大文本数据 |
CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。
BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。
BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。
有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。
10. 创建数据表
创建MySQL数据表需要以下信息:
- 表名
- 表一级名
- 定义每个表变量
语法为:
CREATE TABLE table_name (column_name column_type);
通过命令行创建数据表:
以下示例中我们将在 CODINGBOOK 数据库中创建数据表 CODINGBOOK_tbl :
MariaDB [CODINGBOOK]> CREATE TABLE codingbook_tbl(
-> codingbook_id INT NOT NULL AUTO_INCREMENT,
-> codingbook_title VARCHAR(100) NOT NULL,
-> codingbook_author VARCHAR(40) NOT NULL,
-> submission_date DATE,
-> PRIMARY KEY ( codingbook_id )
-> )ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.16 sec)
MariaDB [CODINGBOOK]>
其中:
- 如果您不想分解为 NULL 可以设置细分的属性为 NOT NULL ,在操作数据库时如果输入该分区的数据为 NULL ,就会报错。
- AUTO_INCREMENT 定义列为自增的属性,一般为主键,数值会自动加1。
- 可以使用多列来定义主键,列间以逗号分隔。
- ENGINE 设置存储引擎,CHARSET 设置编码。
- MySQL 命令终止符为分号。
使用PHP脚本创建数据表:
同样地,我们可以使用 PHP 的 mysqli_query()
函数来创建已存在数据库的数据表。
一个实例:
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo "连接成功\n";
$sql = "CREATE TABLE codingbook_tbl( ".
"codingbook_id INT NOT NULL AUTO_INCREMENT, ".
"codingbook_title VARCHAR(100) NOT NULL, ".
"codingbook_author VARCHAR(40) NOT NULL, ".
"submission_date DATE, ".
"PRIMARY KEY ( codingbook_id ))ENGINE=InnoDB DEFAULT CHARSET=utf8; ";
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('数据表创建失败: ' . mysqli_error($conn));
}
echo "数据表创建成功\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
连接成功
数据表创建成功
root@jincheng-PC:~#
*/
现在我们来查看数据表:
MariaDB [CODINGBOOK]> SHOW TABLES;
+--------------------+
| Tables_in_CODINGBOOK |
+--------------------+
| codingbook_tbl |
| tb_test_student |
+--------------------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可见,数据表 codingbook_tbl 创建成功。
11. 删除数据表
MySQL 中删除数据表是非常容易操作的, 但是你再进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失。语法为:
DROP TABLE table_name ;
在命令行中删除数据表:
以下实例删除了数据表 codingbook_tbl:
MariaDB [CODINGBOOK]> SHOW TABLES;
+----------------------+
| Tables_in_CODINGBOOK |
+----------------------+
| codingbook_tbl |
| tb_test_student |
+----------------------+
2 rows in set (0.01 sec)
MariaDB [CODINGBOOK]> DROP TABLE codingbook_tb1;
Query OK, 0 rows affected (0.01 sec)
MariaDB [CODINGBOOK]> SHOW TABLES;
+----------------------+
| Tables_in_CODINGBOOK |
+----------------------+
| tb_test_student |
+----------------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本删除数据表:
PHP 使用 mysqli_query
函数来删除 MySQL 数据表。
一个实例:
以下实例使用了 PHP 脚本删除数据表 codingbook_tbl:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo "连接成功\n";
$sql = "DROP TABLE codingbook_tbl";
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('数据表删除失败: ' . mysqli_error($conn));
}
echo "数据表删除成功\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
连接成功
数据表删除成功
root@jincheng-PC:~#
*/
12. 插入数据
MySQL 表中使用 INSERT INTO
SQL语句来插入数据。语法为:
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value1, value2,...valueN );
如果数据是字符型,必须使用单引号或者双引号,如:“value” 或 ‘value’ 。
通过命令行插入数据:
MariaDB [CODINGBOOK]> INSERT INTO codingbook_tbl
-> (codingbook_title, codingbook_author, submission_date)
-> VALUES
-> ("学习 PHP", "编程笔记本", NOW());
Query OK, 1 row affected, 1 warning (0.00 sec)
MariaDB [CODINGBOOK]> INSERT INTO codingbook_tbl
-> (codingbook_title, codingbook_author, submission_date)
-> VALUES
-> ("学习 MySQL", "编程笔记本", NOW());
Query OK, 1 row affected, 1 warning (0.00 sec)
MariaDB [CODINGBOOK]> INSERT INTO codingbook_tbl
-> (codingbook_title, codingbook_author, submission_date)
-> VALUES
-> ("数据库知识", "编程笔记本", '2020-4-8');
Query OK, 1 row affected, 1 warning (0.00 sec)
MariaDB [CODINGBOOK]>
在以上实例中,我们并没有提供 nowcoder_id 的数据,因为该字段我们在创建表的时候已经设置它为 AUTO_INCREMENT(自动增加)属性。 所以,该字段会自动递增而不需要我们去设置。实例中 NOW()
是一个 MySQL 函数,该函数返回日期和时间。
接下来我们可以通过以下语句查看数据表数据:
select * from nowcoder_tbl;
输出结果为:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 数据库知识 | 编程笔记本 | 2020-04-08 |
+---------------+------------------+-------------------+-----------------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可见,特定数据已被成功插入。
使用 PHP 脚本插入数据:
使用 PHP 的 mysqli_query()
函数来执行 SQL INSERT INTO
命令来插入数据。
一个实例:
以下实例中程序接收用户输入的三个字段数据,并插入数据表中:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo "连接成功\n";
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$codingbook_title = '学习 Python';
$codingbook_author = '编程笔记本';
$submission_date = '2020-3-1';
$sql = "INSERT INTO codingbook_tbl ".
"(codingbook_title, codingbook_author, submission_date) ".
"VALUES ".
"('$codingbook_title','$codingbook_author','$submission_date')";
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法插入数据: ' . mysqli_error($conn));
}
echo "数据插入成功\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
连接成功
数据插入成功
root@jincheng-PC:~#
*/
对于含有中文的数据插入,需要添加 mysqli_query($conn , "set names utf8")
; 语句。
再来查看数据表:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 数据库知识 | 编程笔记本 | 2020-04-08 |
| 4 | 学习 Python | 编程笔记本 | 2020-03-01 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
13. 查询数据
MySQL 数据库使用 SQL SELECT
语句来查询数据。语法为:
SELECT column_name, column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
- 查询语句中你可以使用一个或者多个表,表之间使用逗号(,)分割,并使用 WHERE 语句来设定查询条件。
- SELECT 命令可以读取一条或者多条记录。
- 你可以使用星号(*)来代替其他字段,SELECT 语句会返回表的所有字段数据
- 你可以使用 WHERE 语句来包含任何条件。
- 你可以使用 LIMIT 属性来设定返回的记录数。
- 可以通过 OFFSET 指定 SELECT 语句开始查询的数据偏移量。默认情况下偏移量为 0 。
通过命令行查询数据:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 数据库知识 | 编程笔记本 | 2020-04-08 |
| 4 | 学习 Python | 编程笔记本 | 2020-03-01 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本来获取数据:
使用 PHP 函数的 mysqli_query()
及 SQL SELECT
命令来获取数据。该函数用于执行 SQL 命令,然后通过 PHP 函数 mysqli_fetch_array()
来使用或输出所有查询的数据。mysqli_fetch_array()
函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有,返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。
一个实例:
以下实例为从数据表 codingbook_tbl 中读取所有记录。
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT codingbook_id, codingbook_title,
codingbook_author, submission_date
FROM codingbook_tbl';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 mysqli_fetch_array 测试:\n";
echo "教程\t\t标题\t\t作者\t\t提交日期\n";
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "{$row['codingbook_id']}\t".
"{$row['codingbook_title']}\t".
"{$row['codingbook_author']}\t".
"{$row['submission_date']}\t".
"\n";
}
mysqli_close($conn);
?>
/*
运行结果:
*/root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 mysqli_fetch_array 测试:
教程 标题 作者 提交日期
1 学习 PHP 编程笔记本 2020-04-08
2 学习 MySQL 编程笔记本 2020-04-08
3 数据库知识 编程笔记本 2020-04-08
4 学习 Python 编程笔记本 2020-03-01
root@jincheng-PC:~#
*/
以上实例中,读取的每行记录赋值给变量 $row,然后再打印出每个值。注意:记住如果你需要在字符串中使用变量,请将变量置于花括号。在上面的例子中,PHP mysqli_fetch_array()
函数第二个参数为 MYSQLI_ASSOC, 设置该参数查询结果返回关联数组,你可以使用字段名称来作为数组的索引。
PHP 提供了另外一个函数 mysqli_fetch_assoc()
, 该函数从结果集中取得一行作为关联数组。 返回根据从结果集取得的行生成的关联数组,如果没有更多行,则返回 false。
一个实例:
以下实例使用了 mysqli_fetch_assoc()
函数来输出数据表 nowcoder_tbl 的所有记录:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT codingbook_id, codingbook_title,
codingbook_author, submission_date
FROM codingbook_tbl';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 mysqli_fetch_array 测试:\n";
echo "教程\t\t标题\t\t作者\t\t提交日期\n";
while($row = mysqli_fetch_assoc($retval))
{
echo "{$row['codingbook_id']}\t".
"{$row['codingbook_title']}\t".
"{$row['codingbook_author']}\t".
"{$row['submission_date']}\t".
"\n";
}
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 mysqli_fetch_array 测试:
教程 标题 作者 提交日期
1 学习 PHP 编程笔记本 2020-04-08
2 学习 MySQL 编程笔记本 2020-04-08
3 数据库知识 编程笔记本 2020-04-08
4 学习 Python 编程笔记本 2020-03-01
root@jincheng-PC:~#
*/
也可以使用常量 MYSQLI_NUM 作为 PHP mysqli_fetch_array()
函数的第二个参数,返回数字数组。
一个实例:
以下实例使用 MYSQLI_NUM 参数显示数据表 nowcoder_tbl 的所有记录:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT codingbook_id, codingbook_title,
codingbook_author, submission_date
FROM codingbook_tbl';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 mysqli_fetch_array 测试:\n";
echo "教程\t\t标题\t\t作者\t\t提交日期\n";
while($row = mysqli_fetch_array($retval, MYSQLI_NUM))
{
echo "{$row[0]}\t".
"{$row[1]}\t".
"{$row[2]}\t".
"{$row[3]}\t".
"\n";
}
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 mysqli_fetch_array 测试:
教程 标题 作者 提交日期
1 学习 PHP 编程笔记本 2020-04-08
2 学习 MySQL 编程笔记本 2020-04-08
3 数据库知识 编程笔记本 2020-04-08
4 学习 Python 编程笔记本 2020-03-01
root@jincheng-PC:~#
*/
14. WHERE 子句
我们知道从 MySQL 表中使用 SQL SELECT 语句来读取数据。如需有条件地从表中选取数据,可将 WHERE
子句添加到 SELECT 语句中。语法为:
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
- 查询语句中你可以使用一个或者多个表,表之间使用逗号, 分割,并使用 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。 |
如果我们想在 MySQL 数据表中读取指定的数据,WHERE 子句是非常有用的。**使用主键来作为 WHERE 子句的条件查询是非常快速的。**如果给定的条件在表中没有任何匹配的记录,那么查询不会返回任何数据。
从命令行读取数据:
以下实例将读取 codingbook_tbl 表中 codingbook_id 字段值为 “1” 的所有记录:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl WHERE codingbook_id=1;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
+---------------+------------------+-------------------+-----------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
MySQL 的 WHERE 子句的字符串比较是不区分大小写的。 你可以使用 BINARY 关键字来设定 WHERE 子句的字符串比较是区分大小写的。
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl WHERE codingbook_title='学习 php';
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
+---------------+------------------+-------------------+-----------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl WHERE BINARY codingbook_title='学习 php';
Empty set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本读取数据:
使用 PHP 函数的 mysqli_query()
及相同的 SQL SELECT 带上 WHERE 子句的命令来获取数据。
一个实例:
以下实例将从 codingbook_tbl 表中返回使用 codingbook_title 字段值为 ‘学习 MySQL’ 的记录:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT codingbook_id, codingbook_title,
codingbook_author, submission_date
FROM codingbook_tbl
WHERE codingbook_title="学习 MySQL"';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 WHERE 字句测试:\n";
echo "教程\t\t标题\t\t作者\t\t提交日期\n";
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "{$row['codingbook_id']}\t".
"{$row['codingbook_title']}\t".
"{$row['codingbook_author']}\t".
"{$row['submission_date']}\t".
"\n";
}
// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 WHERE 字句测试:
教程 标题 作者 提交日期
2 学习 MySQL 编程笔记本 2020-04-08
root@jincheng-PC:~#
*/
15. UPDATE 更新
如果我们需要修改或更新 MySQL 中的数据,我们可以使用 SQL UPDATE
命令来操作。语法为:
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
- 可以同时更新一个或多个字段。
- 可以在 WHERE 子句中指定任何条件。
- 可以在一个单独表中同时更新数据。
当你需要更新数据表中指定行的数据时 WHERE 子句是非常有用的。
通过命令行更新数据:
以下我们将在 SQL UPDATE 命令使用 WHERE 子句来更新 codingbook_tbl 表中指定的数据:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 数据库知识 | 编程笔记本 | 2020-04-08 |
| 4 | 学习 Python | 编程笔记本 | 2020-03-01 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> UPDATE codingbook_tbl SET codingbook_author='Jasmine' WHERE codingbook_id=3;
Query OK, 1 row affected (0.71 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 数据库知识 | Jasmine | 2020-04-08 |
| 4 | 学习 Python | 编程笔记本 | 2020-03-01 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本更新数据:
PHP 中使用函数 mysqli_query()
来执行 SQL 语句,你可以在 SQL UPDATE 语句中使用或者不使用 WHERE 子句。注意:不使用 WHERE 子句将数据表的全部数据进行更新,所以要慎重。该函数与在命令行中执行 SQL 语句的效果是一样的。
一个实例:
以下实例将更新 codingbook_id 为 3 的 nowcoder_title 字段的数据。
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'UPDATE codingbook_tbl
SET codingbook_title="学习 C++"
WHERE codingbook_id=3';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法更新数据: ' . mysqli_error($conn));
}
echo "数据更新成功!\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
数据更新成功!
root@jincheng-PC:~#
*/
让我们来查看数据表验证一下:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 学习 C++ | Jasmine | 2020-04-08 |
| 4 | 学习 Python | 编程笔记本 | 2020-03-01 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可以看到,数据更新成功。
16. DELETE 语句
你可以使用 SQL 的 DELETE FROM
命令来删除 MySQL 数据表中的记录。语法为:
DELETE FROM table_name [WHERE Clause]
- 如果没有指定 WHERE 子句,MySQL 表中的所有记录将被删除。
- 可以在 WHERE 子句中指定任何条件
- 可以在单个表中一次性删除记录。
当想删除数据表中指定的记录时 WHERE 子句是非常有用的。
从命令行删除数据:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 学习 C++ | Jasmine | 2020-04-08 |
| 4 | 学习 Python | 编程笔记本 | 2020-03-01 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> DELETE FROM codingbook_tbl WHERE submission_date='2020-03-01';
Query OK, 1 row affected (0.01 sec)
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 MySQL | 编程笔记本 | 2020-04-08 |
| 3 | 学习 C++ | Jasmine | 2020-04-08 |
+---------------+------------------+-------------------+-----------------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本删除数据:
PHP使用 mysqli_query()
函数来执行SQL语句, 你可以在 SQL DELETE 命令中使用或不使用 WHERE 子句。
一个实例:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'DELETE FROM codingbook_tbl
WHERE codingbook_id=2';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法删除数据: ' . mysqli_error($conn));
}
echo "数据删除成功!\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
数据删除成功!
root@jincheng-PC:~#
*/
17. LIKE 子句
我们知道在 MySQL 中使用 SQL SELECT 命令来读取数据, 同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录。WHERE 子句中可以使用等号 = 来设定获取数据的条件,但是有时候我们需要获取字段中含有某些特定字符的所有记录,这时我们就需要在 WHERE 子句中使用 SQL LIKE
子句。
SQL LIKE 子句中使用**百分号 %**字符来表示任意字符,类似于UNIX或正则表达式中的星号 *。如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。
语法为:
SELECT field1, field2,...fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
- 可以在 WHERE 子句中指定任何条件。
- 可以在 WHERE 子句中使用 LIKE 子句。
- 可以使用 LIKE 子句代替等号 =。
- LIKE 通常与 % 一同使用,类似于一个元字符的搜索。
- 可以使用 AND 或者 OR 指定一个或多个条件。
- 可以在 DELETE 或 UPDATE 命令中使用 WHERE…LIKE 子句来指定条件。
在命令行中使用 LIKE 子句:
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl;
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 1 | 学习 PHP | 编程笔记本 | 2020-04-08 |
| 2 | 学习 Go | jincheng | 2020-04-08 |
| 3 | 学习 C++ | Jasmine | 2020-04-08 |
| 4 | 学习 Linux | jincheng | 2020-04-08 |
+---------------+------------------+-------------------+-----------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM codingbook_tbl WHERE codingbook_author LIKE '%cheng';
+---------------+------------------+-------------------+-----------------+
| codingbook_id | codingbook_title | codingbook_author | submission_date |
+---------------+------------------+-------------------+-----------------+
| 2 | 学习 Go | jincheng | 2020-04-08 |
| 4 | 学习 Linux | jincheng | 2020-04-08 |
+---------------+------------------+-------------------+-----------------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
在 PHP 脚本中使用 LIKE 子句:
你可以使用 PHP 函数的 ```mysqli_query()`` 及相同的 SQL SELECT 带上 WHERE…LIKE 子句的命令来获取数据。
该函数用于执行 SQL 命令,然后通过 PHP 函数 mysqli_fetch_array() 来输出所有查询的数据。但是如果是 DELETE 或者 UPDATE 中使用 WHERE…LIKE 子句的 SQL 语句,则无需使用 mysqli_fetch_array() 函数。
一个实例:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT codingbook_id, codingbook_title,
codingbook_author, submission_date
FROM codingbook_tbl
WHERE codingbook_author LIKE "%cheng"';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 WHERE 字句测试:\n";
echo "教程\t\t标题\t\t作者\t\t提交日期\n";
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "{$row['codingbook_id']}\t".
"{$row['codingbook_title']}\t".
"{$row['codingbook_author']}\t".
"{$row['submission_date']}\t".
"\n";
}
// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 WHERE 字句测试:
教程 标题 作者 提交日期
2 学习 Go jincheng 2020-04-08
4 学习 Linux jincheng 2020-04-08
root@jincheng-PC:~#
*/
18. UNION 操作符
MySQL UNION
操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。语法为:
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];
- expression1, expression2, … expression_n: 要检索的列。
- tables: 要检索的数据表。
- WHERE conditions: 可选,检索条件。
- DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
- ALL: 可选,返回所有结果集,包含重复数据。
为了便于演示,我已经提前创建好两个数据表了:
MariaDB [CODINGBOOK]> SELECT * FROM websites;
+------+---------------+-----------------------+---------+
| id | web_name | url | country |
+------+---------------+-----------------------+---------+
| 1 | 百度 | www.baidu.com | CN |
| 2 | 谷歌 | www.google.com | US |
| 3 | Stackoverflow | www.stackoverflow.com | IND |
| 4 | 腾讯 | www.tecent.com | CN |
| 5 | 脸书 | www.facebook.com | US |
+------+---------------+-----------------------+---------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM apps;
+------+----------+----------------+---------+
| id | app_name | url | country |
+------+----------+----------------+---------+
| 1 | 微信 | www.wechat.com | CN |
| 2 | 淘宝 | www.taomao.com | CN |
+------+----------+----------------+---------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
一个实例:
下面的 SQL 语句从 “websites” 和 “apps” 表中选取所有不同的 country(只有不同的值):
MariaDB [CODINGBOOK]> SELECT country FROM websites
-> UNION
-> SELECT country FROM apps
-> ORDER BY country;
+---------+
| country |
+---------+
| CN |
| IND |
| US |
+---------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
注释:UNION 不能用于列出两个表中所有的 country 。如果一些网站和 APP 来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。可以使用 UNION ALL 来选取重复的值。
一个实例:
下面的 SQL 语句使用 UNION ALL 从 “Websites” 和 “apps” 表中选取所有的 country(也有重复的值):
MariaDB [CODINGBOOK]> SELECT country FROM websites
-> UNION ALL
-> SELECT country FROM apps
-> ORDER BY country;
+---------+
| country |
+---------+
| CN |
| CN |
| CN |
| CN |
| IND |
| US |
| US |
+---------+
7 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
一个实例:
下面的 SQL 语句使用 UNION ALL 从 “Websites” 和 “apps” 表中选取所有的中国(CN)的数据(也有重复的值):
MariaDB [CODINGBOOK]> SELECT country, web_name FROM websites
-> WHERE country='CN'
-> UNION ALL
-> SELECT country, app_name FROM apps
-> WHERE country='CN'
-> ORDER BY country;
+---------+----------+
| country | web_name |
+---------+----------+
| CN | 淘宝 |
| CN | 百度 |
| CN | 微信 |
| CN | 腾讯 |
+---------+----------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
19. 排序
我们知道从 MySQL 表中使用 SQL SELECT 语句来读取数据。
如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ````ORDER BY```子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。
语法为:
ELECT field1, field2, ... fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][默认 ASC]], [field2...] [ASC [DESC][默认 ASC]]
- 可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
- 可以设定多个字段来排序。
- 可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列,默认按升序排列。
- 可以添加 WHERE…LIKE 子句来设置条件。
为方面演示,我预先创建了一个数据表:
MariaDB [CODINGBOOK]> SELECT * FROM marks;
+------+-------------+------+
| id | name | mark |
+------+-------------+------+
| 1 | jincheng | 100 |
| 2 | zhangyaling | 90 |
| 3 | jindaxia | 95 |
+------+-------------+------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
在命令行进行排序:
MariaDB [CODINGBOOK]> SELECT * FROM marks ORDER BY mark ASC;
+------+-------------+------+
| id | name | mark |
+------+-------------+------+
| 2 | zhangyaling | 90 |
| 3 | jindaxia | 95 |
| 1 | jincheng | 100 |
+------+-------------+------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM marks ORDER BY mark DESC;
+------+-------------+------+
| id | name | mark |
+------+-------------+------+
| 1 | jincheng | 100 |
| 3 | jindaxia | 95 |
| 2 | zhangyaling | 90 |
+------+-------------+------+
3 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本进行排序:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT * FROM marks
ORDER BY mark ASC';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 ORDER BY 子句测试:\n";
echo "编号\t姓名\t分数\n";
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "{$row['id']}\t".
"{$row['name']}\t".
"{$row['mark']}\t".
"\n";
}
// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 ORDER BY 子句测试:
编号 姓名 分数
2 zhangyaling 90
3 jindaxia 95
1 jincheng 100
root@jincheng-PC:~#
*/
20. GROUP BY 语句
GROUP BY
语句根据一个或多个列对结果集进行分组。在分组的列上我们可以使用 COUNT
、SUM
、AVG
等函数。语法为:
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
一个实例:
MariaDB [CODINGBOOK]> SELECT * FROM websites;
+------+---------------+-----------------------+---------+
| id | web_name | url | country |
+------+---------------+-----------------------+---------+
| 1 | 百度 | www.baidu.com | CN |
| 2 | 谷歌 | www.google.com | US |
| 3 | Stackoverflow | www.stackoverflow.com | IND |
| 4 | 腾讯 | www.tecent.com | CN |
| 5 | 脸书 | www.facebook.com | US |
+------+---------------+-----------------------+---------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT country, SUM(id) AS id_sum FROM websites GROUP BY country WITH ROLLUP;
+---------+--------+
| country | id_sum |
+---------+--------+
| CN | 5 |
| IND | 3 |
| US | 7 |
| NULL | 15 |
+---------+--------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
其中记录 NULL 表示所有人的登录次数。
我们可以使用 coalesce
来设置一个可以取代 NUll 的名称,coalesce
语法:
select coalesce(a,b,c);
说明:如果 anull ,则选择 b ;如果 bnull ,则选择 c ;如果 a!=null ,则选择 a ;如果 a b c 都为 null ,则返回为 null(没意义)。
一个实例:
MariaDB [CODINGBOOK]> SELECT * FROM websites;
+------+---------------+-----------------------+---------+
| id | web_name | url | country |
+------+---------------+-----------------------+---------+
| 1 | 百度 | www.baidu.com | CN |
| 2 | 谷歌 | www.google.com | US |
| 3 | Stackoverflow | www.stackoverflow.com | IND |
| 4 | 腾讯 | www.tecent.com | CN |
| 5 | 脸书 | www.facebook.com | US |
+------+---------------+-----------------------+---------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT coalesce(country, '总数'), SUM(id) AS id_sum FROM websites GROUP BY country WITH ROLLUP;
+-----------------------------+--------+
| coalesce(country, '总数') | id_sum |
+-----------------------------+--------+
| CN | 5 |
| IND | 3 |
| US | 7 |
| 总数 | 15 |
+-----------------------------+--------+
4 rows in set (0.11 sec)
MariaDB [CODINGBOOK]>
21. 连接的使用
下面我将向大家介绍如何使用 MySQL 的 JOIN
在两个或多个表中查询数据。我们可以在 SELECT , UPDATE 和 DELETE 语句中使用 Mysql 的JOIN
来联合多表查询。
JOIN 以功能大致分为如下三类:
INNER JOIN
(内连接,或等值连接):获取两个表中串联匹配关系的记录。LEFT JOIN
(左连接):获取左表所有记录,甚至右表没有对应匹配的记录。RIGHT JOIN
(右连接):与 LEFT JOIN 相反,用于获取右表所有记录,甚至左表没有对应的匹配记录。
使用下面两个数据表进行演示:
MariaDB [CODINGBOOK]> SELECT * FROM group_tbl;
+----------+--------------+
| group_id | group_person |
+----------+--------------+
| 1 | 10 |
| 2 | 5 |
| 3 | 20 |
+----------+--------------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM person_tbl;
+-----------+-------------+----------+
| person_id | person_name | group_id |
+-----------+-------------+----------+
| 1 | jincheng | 1 |
| 2 | zhangyaling | 1 |
| 3 | jindaxia | 2 |
| 4 | haofan | 2 |
| 5 | jasmine | 4 |
+-----------+-------------+----------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
在命令行中使用 INNER JOIN
:
接下来我们就使用 MySQL 的 INNER JOIN
(也可以省略 INNER using JOIN ,效果一样)来连接以上两张表,读取 person_tbl 表中所有 group_id 放置在 group_tbl 表对应的 group_person 细分值:
MariaDB [CODINGBOOK]> SELECT a.group_id, a.person_name, b.group_person FROM person_tbl a INNER JOIN group_tbl b ON a.group_id = b.group_id;
+----------+-------------+--------------+
| group_id | person_name | group_person |
+----------+-------------+--------------+
| 1 | jincheng | 10 |
| 1 | zhangyaling | 10 |
| 2 | jindaxia | 5 |
| 2 | haofan | 5 |
+----------+-------------+--------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
等价于:
MariaDB [CODINGBOOK]> SELECT a.group_id, a.person_name, b.group_person FROM person_tbl a, group_tbl b WHERE a.group_id = b.group_id;
+----------+-------------+--------------+
| group_id | person_name | group_person |
+----------+-------------+--------------+
| 1 | jincheng | 10 |
| 1 | zhangyaling | 10 |
| 2 | jindaxia | 5 |
| 2 | haofan | 5 |
+----------+-------------+--------------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
在命令行中使用 LEFT JOIN
:
MySQL 左联接与联接有所不同。MySQL 左联接会重新读取左边数据表的全部数据,甚至右边表无对应数据。
MariaDB [CODINGBOOK]> SELECT a.group_id, a.person_name, b.group_person FROM person_tbl a LEFT JOIN group_tbl b ON a.group_id = b.group_id;
+----------+-------------+--------------+
| group_id | person_name | group_person |
+----------+-------------+--------------+
| 1 | jincheng | 10 |
| 1 | zhangyaling | 10 |
| 2 | jindaxia | 5 |
| 2 | haofan | 5 |
| 4 | jasmine | NULL |
+----------+-------------+--------------+
5 rows in set (0.11 sec)
MariaDB [CODINGBOOK]>
在命令行中使用 RIGHT JOIN
:
MySQL RIGHT JOIN 会重新读取右侧数据表的全部数据,甚至左侧边表无对应数据。
MariaDB [CODINGBOOK]> SELECT a.group_id, a.person_name, b.group_person FROM person_tbl a RIGHT JOIN group_tbl b ON a.group_id = b.group_id;
+----------+-------------+--------------+
| group_id | person_name | group_person |
+----------+-------------+--------------+
| 1 | jincheng | 10 |
| 1 | zhangyaling | 10 |
| 2 | jindaxia | 5 |
| 2 | haofan | 5 |
| NULL | NULL | 20 |
+----------+-------------+--------------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
在 PHP 脚本中使用 JOIN:
PHP 中使用 mysqli_query()
函数来执行 SQL 语句,您可以使用以上的相同的 SQL 语句作为 mysqli_query()
函数的参数。
一个实例:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
$sql = 'SELECT a.group_id, a.person_name, b.group_person FROM person_tbl a INNER JOIN group_tbl b ON a.group_id = b.group_id';
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本 INNER JOIN 子句测试:\n";
echo "组别\t姓名\t人数\n";
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "{$row['group_id']}\t".
"{$row['person_name']}\t".
"{$row['group_person']}\t".
"\n";
}
// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
?>
/*
运行结果:
*/root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本 INNER JOIN 子句测试:
组别 姓名 人数
1 jincheng 10
1 zhangyaling 10
2 jindaxia 5
2 haofan 5
root@jincheng-PC:~#
*/
22. NULL 值处理
我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
IS NULL
: 当列的值是 NULL ,此运算符返回 true。IS NOT NULL
: 当列的值不为 NULL,运算符返回 true。<=>
: 比较操作符(不同于 = 运算符),当比较的的两个值为 NULL 时返回 true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 “= NULL” 或 “!= NULL” 在列中查找 NULL 值 。在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 false,即 NULL = NULL 返回 false 。MySQL 中处理 NULL 使用 IS NULL
和 IS NOT NULL
运算符。
注意:
select * , columnName1+ifnull(columnName2,0) from tableName;
columnName1,columnName2 为 int 型,当 columnName2 中有值为 null 时,columnName1+columnName2=null, ifnull(columnName2,0) 把 columnName2 中 null 值转为 0。
为演示方便,我预先创建了一个数据表:
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl;
+-------------+------+
| name | mark |
+-------------+------+
| jincheng | 100 |
| zhangyaling | NULL |
| haofan | 95 |
| jasmine | NULL |
+-------------+------+
4 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
在命令行中使用 NULL 值:
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE mark = NULL;
Empty set (0.10 sec)
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE mark != NULL;
Empty set (0.06 sec)
MariaDB [CODINGBOOK]>
可以看到,= 和 != 运算符是不起作用的。
查找数据表中的列是否为 NULL ,必须使用 IS NULL
和 IS NOT NULL
,如下实例:
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE mark IS NULL;
+-------------+------+
| name | mark |
+-------------+------+
| zhangyaling | NULL |
| jasmine | NULL |
+-------------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE mark IS NOT NULL;
+----------+------+
| name | mark |
+----------+------+
| jincheng | 100 |
| haofan | 95 |
+----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 PHP 脚本处理 NULL 值:
PHP 脚本中你可以在 if...else...
语句来处理变量是否为空,并生成相应的条件语句。
一个实例:
以下实例中 PHP 设置了 $mark 变量,然后使用该变量与数据表中的 mark 字段进行比较:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
if( isset( $mark ))
{
$sql = "SELECT * FROM student_tbl WHERE mark = $nowcoder_count";
}
else
{
$sql = "SELECT * FROM student_tbl WHERE mark IS NULL";
}
mysqli_select_db( $conn, 'CODINGBOOK' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo "\n编程笔记本处理 NULL 值测试:\n";
echo "姓名\t分数\n";
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "{$row['name']}\t".
"{$row['mark']}\t".
"\n";
}
// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
?>
/*
运行结果:
*/root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
编程笔记本处理 NULL 值测试:
姓名 分数
zhangyaling
jasmine
root@jincheng-PC:~#
*/
23. 正则表达式
在前面的章节我们已经了解到 MySQL 可以通过 LIKE ...%
来进行模糊匹配。MySQL 同样也支持其他正则表达式的匹配, MySQL 中使用 REGEXP 操作符来进行正则表达式匹配。
下表中的正则模式可应用于 REGEXP 操作符中。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了 RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
. | 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。 |
[…] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^…] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,‘z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
了解以上的正则需求后,我们就可以根据自己的需求来编写带有正则表达式的 SQL 语句。
几个实例:
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE name REGEXP '^j';
+----------+------+
| name | mark |
+----------+------+
| jincheng | 100 |
| jasmine | NULL |
+----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE name REGEXP 'g$';
+-------------+------+
| name | mark |
+-------------+------+
| jincheng | 100 |
| zhangyaling | NULL |
+-------------+------+
2 rows in set (0.01 sec)
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE name REGEXP 'an';
+-------------+------+
| name | mark |
+-------------+------+
| zhangyaling | NULL |
| haofan | 95 |
+-------------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM student_tbl WHERE name REGEXP '^z|n$';
+-------------+------+
| name | mark |
+-------------+------+
| zhangyaling | NULL |
| haofan | 95 |
+-------------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
24. 事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务。
- 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
- 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
- 事务用来管理 insert、update、delete 语句
事务特性:
一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN
或 START TRANSACTION
,或者执行命令 SET AUTOCOMMIT=0
,用来禁止使用当前会话的自动提交。
事务控制语句:
BEGIN
或START TRANSACTION
显式地开启一个事务;COMMIT
也可以使用COMMIT WORK
,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;ROLLBACK
也可以使用ROLLBACK WORK
,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;SAVEPOINT identifier
,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT
;RELEASE SAVEPOINT identifier
删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;ROLLBACK TO identifier
把事务回滚到标记点;SET TRANSACTION
用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。
事务处理方式:
1、用 BEGIN、ROLLBACK、COMMIT 来实现:
- BEGIN 开始一个事务
- ROLLBACK 事务回滚
- COMMIT 事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
- SET AUTOCOMMIT=0 禁止自动提交
- SET AUTOCOMMIT=1 开启自动提交
在命令行使用事务:
MariaDB [CODINGBOOK]> CREATE TABLE transaction_test_tbl (
-> id INT(5)
-> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.49 sec)
MariaDB [CODINGBOOK]> SELECT * FROM transaction_test_tbl;
Empty set (0.00 sec)
MariaDB [CODINGBOOK]> BEGIN;
Query OK, 0 rows affected (0.00 sec)
MariaDB [CODINGBOOK]> INSERT INTO transaction_test_tbl VALUES (5);
Query OK, 1 row affected (0.07 sec)
MariaDB [CODINGBOOK]> INSERT INTO transaction_test_tbl VALUES (8);
Query OK, 1 row affected (0.00 sec)
MariaDB [CODINGBOOK]> COMMIT;
Query OK, 0 rows affected (0.01 sec)
MariaDB [CODINGBOOK]> SELECT * FROM transaction_test_tbl;
+------+
| id |
+------+
| 5 |
| 8 |
+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
在 PHP 中使用事务:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn, "set names utf8");
mysqli_select_db( $conn, 'CODINGBOOK' );
// 设置为不自动提交事务,因为MYSQL默认立即执行
mysqli_query($conn, "SET AUTOCOMMIT=0");
mysqli_begin_transaction($conn); // 开始事务定义
if(!mysqli_query($conn, "INSERT INTO transaction_test_tbl (id) VALUES (9)"))
{
mysqli_query($conn, "ROLLBACK"); // 执行失败时回滚
}
if(!mysqli_query($conn, "INSERT INTO transaction_test_tbl (id) VALUES (3)"))
{
mysqli_query($conn, "ROLLBACK"); // 执行失败时回滚
}
mysqli_commit($conn); //执行事务
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
root@jincheng-PC:~#
*/
现在我们来看一下数据表:
MariaDB [CODINGBOOK]> SELECT * FROM transaction_test_tbl;
+------+
| id |
+------+
| 5 |
| 8 |
| 9 |
| 3 |
+------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
25. ALTER 命令
当我们需要修改数据表名或者修改数据表字段时,就需要使用到 MySQL ALTER
命令。
我们先创建一个数据表:
MariaDB [CODINGBOOK]> CREATE TABLE alter_test_tbl (
-> i INT,
-> c CHAR(1)
-> );
Query OK, 0 rows affected (0.21 sec)
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i | int(11) | YES | | NULL | |
| c | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.18 sec)
MariaDB [CODINGBOOK]>
删除,添加或修改表字段:
如下命令使用了 ALTER 命令及 DROP
子句来删除以上创建表的 i 字段:
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl DROP i;
Query OK, 0 rows affected (0.29 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
如果数据表中只剩余一个字段则无法使用 DROP
来删除字段。
MySQL 中使用 ADD
子句来向数据表中添加列,并定义数据类型:
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl ADD i INT;
Query OK, 0 rows affected (1.86 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
执行以上命令后,i 字段会自动添加到数据表字段的末尾。
如果你需要指定新增字段的位置,可以使用 MySQL 提供的关键字 FIRST
(设定位第一列), AFTER
字段名(设定位于某个字段之后)。
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl ADD i_1 INT FIRST;
Query OK, 0 rows affected (0.49 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c | char(1) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl ADD i_2 INT AFTER c;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c | char(1) | YES | | NULL | |
| i_2 | int(11) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
FIRST
和 AFTER
关键字可用于 ADD 与 MODIFY 子句,所以如果你想重置数据表字段的位置就需要先使用 DROP 删除字段然后使用 ADD 来添加字段并设置位置。
修改字段类型及名称:
如果需要修改字段类型及名称, 你可以在 ALTE R命令中使用 MODIFY
或 CHANGE
子句 。
例如,把字段 c 的类型从 CHAR(1) 改为 CHAR(10),可以执行以下命令:
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl MODIFY c CHAR(10);
Query OK, 0 rows affected (0.24 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c | char(10) | YES | | NULL | |
| i_2 | int(11) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 CHANGE
子句, 语法有很大的不同。 在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型。尝试如下实例:
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl CHANGE c c_3 CHAR(20);
Query OK, 0 rows affected (0.20 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c_3 | char(20) | YES | | NULL | |
| i_2 | int(11) | YES | | NULL | |
| i | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
ALTER TABLE 对 Null 值和默认值的影响:
当你修改字段时,你可以指定是否包含值或者是否设置默认值。
以下实例,指定字段 i 为 NOT NULL 且默认值为 100 。
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c_3 | char(20) | YES | | NULL | |
| i_2 | int(11) | YES | | NULL | |
| i | bigint(20) | NO | | 100 | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
如果你不设置默认值,MySQL 会自动设置该字段默认为 NULL。
修改字段默认值:
你可以使用 ALTER 来修改字段的默认值,尝试以下实例:
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl ALTER i SET DEFAULT 200;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c_3 | char(20) | YES | | NULL | |
| i_2 | int(11) | YES | | NULL | |
| i | bigint(20) | NO | | 200 | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
也可以使用 ALTER 命令及 DROP子句来删除字段的默认值,如下实例:
MariaDB [CODINGBOOK]> SHOW COLUMNS FROM alter_test_tbl;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| i_1 | int(11) | YES | | NULL | |
| c_3 | char(20) | YES | | NULL | |
| i_2 | int(11) | YES | | NULL | |
| i | bigint(20) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
修改数据表类型:
可以使用 ALTER 命令及 TYPE
子句来完成。尝试以下实例,我们将表 alter_test_tbl 的类型修改为 MYISAM :(查看数据表类型可以使用 SHOW TABLE STATUS
语句)
MariaDB [CODINGBOOK]> SHOW TABLE STATUS LIKE 'alter_test_tbl' \G
*************************** 1. row ***************************
Name: alter_test_tbl
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2020-04-08 19:18:49
Update_time: NULL
Check_time: NULL
Collation: utf8mb4_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.12 sec)
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl ENGINE=MYISAM;
Query OK, 0 rows affected (0.24 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW TABLE STATUS LIKE 'alter_test_tbl' \G
*************************** 1. row ***************************
Name: alter_test_tbl
Engine: MyISAM
Version: 10
Row_format: Fixed
Rows: 0
Avg_row_length: 0
Data_length: 0
Max_data_length: 27303072740933631
Index_length: 1024
Data_free: 0
Auto_increment: NULL
Create_time: 2020-04-08 19:22:04
Update_time: 2020-04-08 19:22:04
Check_time: NULL
Collation: utf8mb4_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.01 sec)
MariaDB [CODINGBOOK]>
修改表名:
如果需要修改数据表的名称,可以在 ALTER TABLE 语句中使用 RENAME
子句来实现。
尝试以下实例将数据表 alter_test_tbl 重命名为 alter_tbl:
MariaDB [CODINGBOOK]> ALTER TABLE alter_test_tbl RENAME TO alter_tbl;
Query OK, 0 rows affected (0.13 sec)
MariaDB [CODINGBOOK]> SHOW TABLES;
+----------------------+
| Tables_in_CODINGBOOK |
+----------------------+
| alter_tbl |
| apps |
| codingbook_tbl |
| group_tbl |
| marks |
| person_tbl |
| student_tbl |
| tb_test_student |
| transaction_test_tbl |
| websites |
+----------------------+
10 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
26. 索引
MySQL 索引的建立对于 MySQL 的高效运行是很重要的,索引可以大大提高 MySQL 的检索速度。
索引分单列索引和组合索引:
- 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。
- 组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。建立索引会占用磁盘空间的索引文件。
索引的好处很大,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 INSERT、UPDATE 和 DELETE 。因为更新表时,MySQL 不仅要保存数据,还要保存索引文件。
普通索引:
普通索引的创建方式有以下几种:
- 创建索引:
CREATE INDEX indexName ON mytable(columnName(length));
如果是 CHAR,VARCHAR 类型,length 可以小于字段实际长度;如果是 BLOB 和 TEXT 类型,必须指定 length。 - 修改表结构(添加索引):
ALTER TABLE tableName ADD INDEX indexName(columnName)
- 创建表的时候直接指定:
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (columnName(length))
);
删除索引的语法:
DROP INDEX [indexName] ON mytable;
唯一索引:
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
- 创建索引:
CREATE UNIQUE INDEX indexName ON mytable(columnName(length))
- 修改表结构:
ALTER TABLE mytable ADD UNIQUE [indexName] (columnName(length))
- 创建表的时候直接指定:
CREATE TABLE mytable(
ID INT NOT NULL,
columnName VARCHAR(16) NOT NULL,
UNIQUE [indexName] (columnName(length))
);
使用 ALTER
命令添加和删除索引:
有四种方式来添加数据表的索引:
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)
: 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为 NULL 。ALTER TABLE tbl_name ADD UNIQUE INDEX index_name (column_list)
: 这条语句创建索引的值必须是唯一的(除了 NULL 外,NULL 可能会出现多次)。ALTER TABLE tbl_name ADD INDEX index_name (column_list)
: 添加普通索引,索引值可出现多次。ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list)
:该语句指定了索引为 FULLTEXT ,用于全文索引。
使用 ALTER
命令添加和删除主键:
主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下:
ALTER TABLE tbl_name MODIFY columnName INT NOT NULL;
ALTER TABLE tbl_name ADD PRIMARY KEY (columnName);
你也可以使用 ALTER 命令删除主键:
ALTER TABLE tbl_name DROP PRIMARY KEY;
删除主键时只需指定 PRIMARY KEY ,但在删除索引时,你必须知道索引名。
显示索引信息:
你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。可以通过添加 \G 来格式化输出信息。
一个实例:
MariaDB [CODINGBOOK]> ALTER TABLE alter_tbl ADD INDEX idx_i (i);
Query OK, 0 rows affected (0.42 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SHOW INDEX FROM alter_tbl \G
*************************** 1. row ***************************
Table: alter_tbl
Non_unique: 1
Key_name: idx_i
Seq_in_index: 1
Column_name: i
Collation: A
Cardinality: NULL
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
1 row in set (0.01 sec)
MariaDB [CODINGBOOK]>
27. 临时表
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql 会自动删除表并释放所有空间。如果您使用 PHP 脚本来创建 MySQL 临时表,那每当 PHP 脚本执行完成后,该临时表也会自动销毁。
临时表在 MySQL 3.23 版本中添加,如果你的MySQL版本低于3.23版本就无法使用MySQL的临时表。
MySQL 临时表只在当前连接可见,如果您使用 PHP 脚本来创建 MySQL 临时表,那每当 PHP 脚本执行完成后,该临时表也会自动销毁。如果您使用了其他 MySQL 客户端程序连接 MySQL 数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,当然你也可以手动销毁。
一个实例:
MariaDB [CODINGBOOK]> CREATE TEMPORARY TABLE tmp_tbl (id INT);
Query OK, 0 rows affected (0.17 sec)
MariaDB [CODINGBOOK]> INSERT INTO tmp_tbl VALUES (5);
Query OK, 1 row affected (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM tmp_tbl;
+------+
| id |
+------+
| 5 |
+------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SHOW TABLES;
+----------------------+
| Tables_in_CODINGBOOK |
+----------------------+
| alter_tbl |
| apps |
| codingbook_tbl |
| group_tbl |
| marks |
| person_tbl |
| student_tbl |
| tb_test_student |
| transaction_test_tbl |
| websites |
+----------------------+
10 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
使用 SHOW TABLES
命令显示数据表列表时,无法看到表。
删除临时表
默认情况下,当您自己与数据库的连接后,临时表就会自动被销毁。当然你也可以在当前 MySQL 会话使用 DROP TABLE
命令来手动删除临时表。
MariaDB [CODINGBOOK]> SELECT * FROM tmp_tbl;
+------+
| id |
+------+
| 5 |
+------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> DROP TABLE tmp_tbl;
Query OK, 0 rows affected (0.01 sec)
MariaDB [CODINGBOOK]> SELECT * FROM tmp_tbl;
ERROR 1146 (42S02): Table 'CODINGBOOK.tmp_tbl' doesn't exist
MariaDB [CODINGBOOK]>
28. 复制表
现在为大家介绍如何完整的复制 MySQL 数据表,步骤如下:
- 使用
SHOW CREATE TABLE
命令获取创建数据表(CREATE TABLE)语句,该语句包含了原数据表的结构,索引等。 - 复制以下命令显示的 SQL 语句,修改数据表名,并执行 SQL 语句,通过以上命令 将完全的复制数据表结构。
- 如果你想复制表的内容,你就可以使用
INSERT INTO ... SELECT
语句来实现。
一个实例:
复制数据表 apps 。
- 获取数据表的完整结构:
MariaDB [CODINGBOOK]> SHOW CREATE TABLE apps \G
*************************** 1. row ***************************
Table: apps
Create Table: CREATE TABLE `apps` (
`id` int(11) DEFAULT NULL,
`app_name` varchar(20) DEFAULT NULL,
`url` varchar(50) DEFAULT NULL,
`country` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
- 修改 SQL 语句的数据表名,并执行 SQL 语句:
MariaDB [CODINGBOOK]> CREATE TABLE `clone_apps` (
-> `id` int(11) DEFAULT NULL,
-> `app_name` varchar(20) DEFAULT NULL,
-> `url` varchar(50) DEFAULT NULL,
-> `country` varchar(20) DEFAULT NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.15 sec)
MariaDB [CODINGBOOK]>
- 如果你想拷贝数据表的数据你可以使用
INSERT INTO... SELECT
语句来实现:
MariaDB [CODINGBOOK]> INSERT INTO clone_apps
-> (id, app_name, url, country)
-> SELECT * FROM apps;
Query OK, 2 rows affected (0.11 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM clone_apps;
+------+----------+----------------+---------+
| id | app_name | url | country |
+------+----------+----------------+---------+
| 1 | 微信 | www.wechat.com | CN |
| 2 | 淘宝 | www.taomao.com | CN |
+------+----------+----------------+---------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
执行以上步骤后,你将完整的复制表,包括表结构及表数据。
29. 元数据
你可能想知道 MySQL 以下三种信息:
- 查询结果信息:SELECT、UPDATE 或 DELETE 语句影响的记录数。
- 数据库和数据表的信息:包含了数据库及数据表的结构信息。
- MySQL 服务器信息:包含了数据库服务器的当前状态、版本号等。
在 MySQL 的命令提示符中,我们可以很容易的获取以上服务器信息。 但如果使用 Perl 或 PHP 等脚本语言,你就需要调用特定的接口函数来获取。
获取查询语句影响的记录数:
在 PHP 中,你可以使用 mysqli_affected_rows()
函数来获取查询语句影响的记录数。
$result_id = mysqli_query ($conn_id, $query);
# 如果查询失败返回
$count = ($result_id ? mysqli_affected_rows($conn_id) : 0);
print ("$count 条数据被影响\n");
数据库和数据表列表:
你可以很容易的在 MySQL 服务器中获取数据库和数据表列表。如果你没有足够的权限,结果将返回 NULL 。你也可以使用 SHOW TABLES
或 SHOW DATABASES
语句来获取数据库和数据表列表。
在 PHP 中,以下实例输出 MySQL 服务器上的所有数据库:
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
$db_list = mysqli_query($conn, 'SHOW DATABASES');
while ($db = mysqli_fetch_object($db_list))
{
echo $db->Database . "\n";
}
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
CODINGBOOK
information_schema
mysql
performance_schema
test
root@jincheng-PC:~#
*/
获取服务器元数据:
以下命令语句可以在 MySQL 的命令行使用,也可以在 PHP 脚本中使用。
命令 | 描述 |
---|---|
SELECT VERSION() | 服务器版本信息 |
SELECT DATABASE() | 当前数据库名 (或者返回空) |
SELECT USER() | 当前用户名 |
SHOW STATUS | 服务器状态 |
SHOW VARIABLES | 服务器配置变量 |
30. 序列使用
MySQL 序列是一组整数:1, 2, 3, …,由于一张数据表只能有一个字段自增主键, 如果想实现其他字段也实现自动增加,就可以使用 MySQL 序列来实现。
使用 AUTO_INCREMENT :
MySQL 中最简单使用序列的方法就是使用 MySQL AUTO_INCREMENT
来定义列。
MariaDB [CODINGBOOK]> CREATE TABLE test_1 (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> age INT NOT NULL,
-> PRIMARY KEY (id)
-> );
Query OK, 0 rows affected (0.17 sec)
MariaDB [CODINGBOOK]> INSERT INTO test_1 VALUES
-> (NULL, 18),
-> (NULL, 20),
-> (NULL, 25);
Query OK, 3 rows affected (0.04 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM test_1 ORDER BY id;
+----+-----+
| id | age |
+----+-----+
| 1 | 18 |
| 2 | 20 |
| 3 | 25 |
+----+-----+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
只能有一个自增的列,并且它要被定义成一个键。
获取 AUTO_INCREMENT 值:
在 MySQL 的客户端中你可以使用 SQL中 的 LAST_INSERT_ID()
函数来获取最后的插入表中的自增列的值。在 PHP 脚本中也提供了相应的函数来获取最后的插入表中的自增列的值。
PHP 通过 mysql_insert_id()
函数来获取执行的插入 SQL 语句中 AUTO_INCREMENT 列的值。
/* test.php */
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '\''; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
mysqli_select_db($conn, 'CODINGBOOK' );
$sql = 'INSERT INTO test_1 VALUES (NULL, 36)';
$retval = mysqli_query($conn,$sql);
if(! $retval )
{
die('插入数据失败: ' . mysqli_error($conn));
}
$seq = mysqli_insert_id ($conn);
echo "$seq\n";
mysqli_close($conn);
?>
/*
运行结果:
root@jincheng-PC:~# php /home/jincheng/Desktop/test.php
4
root@jincheng-PC:~#
*/
我们来验证一下:
MariaDB [CODINGBOOK]> SELECT * FROM test_1 ORDER BY id;
+----+-----+
| id | age |
+----+-----+
| 1 | 18 |
| 2 | 20 |
| 3 | 25 |
| 4 | 36 |
+----+-----+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可以看到,最后的插入表中的自增列的值确实为 4 。
重置序列:
如果你删除了数据表中的多条记录,并希望对剩下数据的 AUTO_INCREMENT 列进行重新排列,那么你可以通过删除自增的列,然后重新添加来实现。 不过该操作要非常小心,如果在删除的同时又有新记录添加,有可能会出现数据混乱。操作如下所示:
MariaDB [CODINGBOOK]> SELECT * FROM test_1 ORDER BY id;
+----+-----+
| id | age |
+----+-----+
| 1 | 18 |
| 2 | 20 |
| 3 | 25 |
| 4 | 36 |
+----+-----+
4 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> DELETE FROM test_1 WHERE id=3;
Query OK, 1 row affected (0.20 sec)
MariaDB [CODINGBOOK]> SELECT * FROM test_1;
+----+-----+
| id | age |
+----+-----+
| 1 | 18 |
| 2 | 20 |
| 4 | 36 |
+----+-----+
3 rows in set (0.10 sec)
MariaDB [CODINGBOOK]> ALTER TABLE test_1 DROP id;
Query OK, 3 rows affected (0.23 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM test_1;
+-----+
| age |
+-----+
| 18 |
| 20 |
| 36 |
+-----+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> ALTER TABLE test_1
-> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
-> ADD PRIMARY KEY (id);
Query OK, 0 rows affected (2.20 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM test_1;
+----+-----+
| id | age |
+----+-----+
| 1 | 18 |
| 2 | 20 |
| 3 | 36 |
+----+-----+
3 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
设置序列的开始值:
一般情况下序列的开始数值 1 ,但如果你需要指定一个开始值 100 ,那我们可以通过以下语句来实现:
MariaDB [CODINGBOOK]> CREATE TABLE test_2 (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> age INT NOT NULL,
-> PRIMARY KEY (id)
-> ) AUTO_INCREMENT=100;
Query OK, 0 rows affected (0.48 sec)
MariaDB [CODINGBOOK]> INSERT INTO test_2 VALUES
-> (NULL, 24),
-> (NULL, 36);
Query OK, 2 rows affected (0.40 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM test_2;
+-----+-----+
| id | age |
+-----+-----+
| 100 | 24 |
| 101 | 36 |
+-----+-----+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
或者在表创建成功后,通过以下语句来实现:
ALTER TABLE t AUTO_INCREMENT = 100;
31. 处理重复数据
有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。下面我将为大家介绍如何防止数据表出现重复数据及如何删除数据表中的重复数据。
防止表中出现重复数据:
在 MySQL 数据表中设置指定的字段为 PRIMARY KEY
(主键)或者 UNIQUE
(唯一)索引来保证数据的唯一性。让我们尝试一个实例:下表中无索引及主键,所以该表允许出现多条重复记录。
MariaDB [CODINGBOOK]> CREATE TABLE test_3 (
-> first_name CHAR(20),
-> last_name CHAR(20),
-> age INT
-> );
Query OK, 0 rows affected (0.15 sec)
MariaDB [CODINGBOOK]> INSERT INTO test_3 VALUES
-> ('CHENG', 'JIN', 18),
-> ('CHENG', 'JIN', 20);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
| CHENG | JIN | 20 |
+------------+-----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可以看到,当向表中插入重复数据时,数据被成功保存,且不会产生错误。
如果你想设置表中字段 first_name,last_name 数据不能重复,你可以设置双主键模式来设置数据的唯一性,如果你设置了双主键,那么那个键的默认值不能为 NULL ,可设置为 NOT NULL 。如下所示:
MariaDB [CODINGBOOK]> CREATE TABLE test_4 (
-> first_name CHAR(20) NOT NULL,
-> last_name CHAR(20) NOT NULL,
-> age INT NOT NULL,
-> PRIMARY KEY (first_name, last_name)
-> );
Query OK, 0 rows affected (0.16 sec)
MariaDB [CODINGBOOK]> INSERT INTO test_4 VALUES
-> ('CHENG', 'JIN', 18),
-> ('CHENG', 'JIN', 20);
ERROR 1062 (23000): Duplicate entry 'CHENG-JIN' for key 'PRIMARY'
MariaDB [CODINGBOOK]>
可以看到,设置了双主键以后,插入重复数据时就会报错。
上述的 PRIMARY KEY (first_name, last_name)
,也可以写成 UNIQUE (first_name, last_name)
。
INSERT IGNORE INTO
与 INSERT INTO 的区别就是 INSERT IGNORE 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。
还使用上面创建的数据表:
MariaDB [CODINGBOOK]> SELECT * FROM test_4;
+------------+-----------+-----+
| first_name | last_name | age |
+------------+-----------+-----+
| CHENG | JIN | 18 |
+------------+-----------+-----+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> INSERT IGNORE INTO test_4 VALUE ('CHENG', 'JIN', 18);
Query OK, 0 rows affected, 1 warning (0.00 sec)
MariaDB [CODINGBOOK]> INSERT IGNORE INTO test_4 VALUE ('YALING', 'ZHANG', 20);
Query OK, 1 row affected (0.13 sec)
MariaDB [CODINGBOOK]> SELECT * FROM test_4;
+------------+-----------+-----+
| first_name | last_name | age |
+------------+-----------+-----+
| CHENG | JIN | 18 |
| YALING | ZHANG | 20 |
+------------+-----------+-----+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]>
可以看到,当我们向表中插入重复数据时,没有报错,且提示 “0 rows affected” ,并伴随一条警告信息,表示表中已有该重复数据,忽略本次插入的数据。
INSERT IGNORE INTO
当插入数据时,在设置了记录的唯一性后,如果插入重复数据,将不返回错误,只以警告形式返回。而 REPLACE INTO
如果存在 primary 或 unique 相同的记录,则先删除掉。再插入新记录。
继续使用上述数据表:
MariaDB [CODINGBOOK]> SELECT * FROM test_5;
+------------+-----------+-----+
| first_name | last_name | age |
+------------+-----------+-----+
| CHENG | JIN | 18 |
| YALING | ZHANG | 20 |
+------------+-----------+-----+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> REPLACE INTO test_5 VALUE ('CHENG', 'JIN', 22);
Query OK, 2 rows affected (0.37 sec)
MariaDB [CODINGBOOK]> SELECT * FROM test_5;
+------------+-----------+-----+
| first_name | last_name | age |
+------------+-----------+-----+
| CHENG | JIN | 22 |
| YALING | ZHANG | 20 |
+------------+-----------+-----+
2 rows in set (0.01 sec)
MariaDB [CODINGBOOK]>
为了区别显示,我插入相同的 first_name、last_name 和 不同的 age ,可以看到,数据表中原来的重复数据别替换(删除原数据,插入新数据)成新插入的数据了。
统计重复数据:
以下我们将统计表中 first_name 和 last_name 的重复记录数:
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
| CHENG | JIN | 20 |
+------------+-----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT COUNT(*) AS repetitions, first_name, last_name FROM test_3
-> GROUP BY first_name, last_name
-> HAVING repetitions>1;
+-------------+------------+-----------+
| repetitions | first_name | last_name |
+-------------+------------+-----------+
| 2 | CHENG | JIN |
+-------------+------------+-----------+
1 row in set (0.18 sec)
MariaDB [CODINGBOOK]>
一般情况下,查询重复的值,请执行以下操作:
- 确定哪一列包含的值可能会重复。
- 选择列表使用 COUNT(*) 计数那些列。
- 在 GROUP BY 子句中列出列。
- HAVING 子句设置重复数大于 1 。
过滤重复数据:
如果你需要读取不重复的数据可以在 SELECT 语句中使用 DISTINCT
关键字来过滤重复数据。
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
| CHENG | JIN | 20 |
+------------+-----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT DISTINCT first_name, last_name FROM test_3;
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| CHENG | JIN |
+------------+-----------+
1 row in set (0.01 sec)
MariaDB [CODINGBOOK]>
也可以使用 GROUP BY
来读取数据表中不重复的数据:
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
| CHENG | JIN | 20 |
+------------+-----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT first_name, last_name FROM test_3
-> GROUP BY first_name, last_name;
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| CHENG | JIN |
+------------+-----------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
删除重复数据:
如果你想删除数据表中的重复数据,可以使用如下思路:
- 先从表中选出不重复的数据并依次建立一个新表
- 删除旧表
- 将新表重命名为旧表名
如下所示:
MariaDB [CODINGBOOK]> CREATE TABLE tmp SELECT first_name, last_name, age FROM test_3 GROUP BY first_name, last_name;
Query OK, 1 row affected (0.04 sec)
Records: 1 Duplicates: 0 Warnings: 0
MariaDB [CODINGBOOK]> DROP TABLE test_3;
Query OK, 0 rows affected (0.01 sec)
MariaDB [CODINGBOOK]> ALTER TABLE tmp RENAME TO test_3;
Query OK, 0 rows affected (0.16 sec)
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
+------------+-----------+------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
也可以在数据表中添加 INDEX(索引) 和 PRIMAY KEY(主键)这种简单的方法来删除表中的重复记录。方法如下:
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
| CHENG | JIN | 18 |
+------------+-----------+------+
2 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> ALTER IGNORE TABLE test_3
-> ADD PRIMARY KEY (first_name, last_name);
Query OK, 2 rows affected (0.16 sec)
Records: 2 Duplicates: 1 Warnings: 0
MariaDB [CODINGBOOK]> SELECT * FROM test_3;
+------------+-----------+------+
| first_name | last_name | age |
+------------+-----------+------+
| CHENG | JIN | 18 |
+------------+-----------+------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
32. MySQL 及 SQL 注入
如果您通过网页获取用户输入的数据并将其插入一个 MySQL 数据库,那么就有可能发生 SQL 注入安全的问题。本章节将为大家介绍如何防止 SQL 注入,并通过脚本来过滤 SQL中 注入的字符。
**所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。**我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。
以下实例中,输入的用户名必须为字母、数字及下划线的组合,且用户名长度为 8 到 20 个字符之间:
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches))
{
$result = mysqli_query($conn, "SELECT * FROM users
WHERE username=$matches[0]");
}
else
{
echo "username 输入异常";
}
让我们看下在没有过滤特殊字符时,出现的 SQL 情况:
// 设定$name 中插入了我们不需要的SQL语句
$name = "Qadir'; DELETE FROM users;";
mysqli_query($conn, "SELECT * FROM users WHERE name='{$name}'");
以上的注入语句中,name 中插入了我们不需要的 SQL 语句,将删除 users 表中的所有数据。
在 PHP 中的 mysqli_query()
是不允许执行多个 SQL 语句的,但是在 SQLite 和 PostgreSQL 是可以同时执行多条 SQL 语句的,所以我们对这些用户的数据需要进行严格的验证。
防止 SQL 注入的几个要点:
- 永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双引号进行转换等。
- 永远不要使用动态拼装 sql ,可以使用参数化的 sql 或者直接使用存储过程进行数据查询存取。
- 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
- 不要把机密信息直接存放,加密或者 hash 掉密码和敏感的信息。
- 应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
- sql 注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用 sql 注入检测工具 jsky ,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN 等。采用 MDCSOFT-IPS 可以有效的防御 SQL 注入、XSS 攻击等。
33. 导出数据
MySQL中你可以使用 SELECT ... INTO OUTFILE
语句来简单的导入数据到文本文件上。
使用 SELECT ... INTO OUTFILE
语句导出数据:
以下实例中我们将数据表 websites 数据添加到 /tmp/websites.txt 文件中:
MariaDB [CODINGBOOK]> SELECT * FROM websites;
+------+---------------+-----------------------+---------+
| id | web_name | url | country |
+------+---------------+-----------------------+---------+
| 1 | 百度 | www.baidu.com | CN |
| 2 | 谷歌 | www.google.com | US |
| 3 | Stackoverflow | www.stackoverflow.com | IND |
| 4 | 腾讯 | www.tecent.com | CN |
| 5 | 脸书 | www.facebook.com | US |
+------+---------------+-----------------------+---------+
5 rows in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT * FROM websites INTO OUTFILE '/tmp/websites.txt';
Query OK, 5 rows affected (0.38 sec)
MariaDB [CODINGBOOK]>
我们再去查看以下 websites.txt 的内容:
root@jincheng-PC:~# vim /tmp/websites.txt
1 百度 www.baidu.com CN
2 谷歌 www.google.com US
3 Stackoverflow www.stackoverflow.com IND
4 腾讯 www.tecent.com CN
5 脸书 www.facebook.com US
可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式:
MariaDB [CODINGBOOK]> SELECT * FROM websites INTO OUTFILE '/tmp/websites.txt'
-> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
-> LINES TERMINATED BY '\r\n';
Query OK, 5 rows affected (0.00 sec)
MariaDB [CODINGBOOK]>
我们再去查看以下 websites.txt 的内容:
root@jincheng-PC:~# vim /tmp/websites.txt
"1","百度","www.baidu.com","CN"
"2","谷歌","www.google.com","US"
"3","Stackoverflow","www.stackoverflow.com","IND"
"4","腾讯","www.tecent.com","CN"
"5","脸书","www.facebook.com","US"
SELECT ... INTO OUTFILE
语句具有以下属性:
- 为了将一个数据库的数据写入一个文件,使用
SELECT ...
将数据加载到 INFILE 是SELECT ... INTO OUTFILE
的逆向操作。 SELECT ... INTO OUTFILE 'file_name'
形式的 SELECT 可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有文件权限,才能使用此语法。- 输出不能是一个已存在的文件。防止文件数据被篡改。
- 您需要有一个登陆服务器的帐户来检索文件。否则
SELECT ... INTO OUTFILE
不会起任何作用。 - 在 UNIX 中,该文件被创建后是扩展的,权限由 MySQL 服务器所拥有。这意味着,虽然你就可以读取该文件,但可能无法将其删除。
导出表作为原始数据:
mysqldump 是 mysql 用于转存储数据库的实用程序。它主要产生一个 SQL 脚本,其中包含从头重新创建数据库所必需的命令 CREATE TABLE INSERT 等。
使用 mysqldump 导出数据需要使用 --tab 选项来指定导出文件指定的目录,该目标必须是可写的。
root@jincheng-PC:~# mysqldump --tab=/tmp CODINGBOOK websites
root@jincheng-PC:~#
看看相应目录的文件:
root@jincheng-PC:~# ls /tmp
config-err-FpbCCu
fcitx-socket-:0
lastore-session-helper-source-checked
pulse-2L9K88eMlGn7
pulse-PKdhtXMmr18n
sogou-qimpanel:0.pid
sogou-qimpanel-celljincheng
sogou-qimpaneljincheng
startdde-login-sound-mark
systemd-private-4136fdfa010c43909ab1a7b0133e3996-apache2.service-kvlsHj
systemd-private-4136fdfa010c43909ab1a7b0133e3996-systemd-timesyncd.service-vcnJp9
VMwareDnD
websites.sql
websites.txt
root@jincheng-PC:~#
可以看到,在指定的目录下,已经生成了一个 websites.sql 文件。其具体内容为:
-- MySQL dump 10.16 Distrib 10.1.37-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: CODINGBOOK
-- ------------------------------------------------------
-- Server version 10.1.37-MariaDB-0+deb9u1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `websites`
--
DROP TABLE IF EXISTS `websites`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `websites` (
`id` int(11) DEFAULT NULL,
`web_name` varchar(20) DEFAULT NULL,
`url` varchar(50) DEFAULT NULL,
`country` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-04-09 10:06:29
导出 SQL 格式的数据:
导出 SQL 格式的数据到指定文件,如下所示:
root@jincheng-PC:~# mysqldump CODINGBOOK websites > /tmp/dump.txt
root@jincheng-PC:~#
以上命令创建的文件内容如下:
-- MySQL dump 10.16 Distrib 10.1.37-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: CODINGBOOK
-- ------------------------------------------------------
-- Server version 10.1.37-MariaDB-0+deb9u1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `websites`
--
DROP TABLE IF EXISTS `websites`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `websites` (
`id` int(11) DEFAULT NULL,
`web_name` varchar(20) DEFAULT NULL,
`url` varchar(50) DEFAULT NULL,
`country` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `websites`
--
LOCK TABLES `websites` WRITE;
/*!40000 ALTER TABLE `websites` DISABLE KEYS */;
INSERT INTO `websites` VALUES (1,'百度','www.baidu.com','CN'),(2,'谷歌','www.google.com','US'),(3,'Stackoverflow','www.stackoverflow.com','IND'),(4,'腾讯','www.tecent.com','CN'),(5,'脸书','www.facebook.com','US');
/*!40000 ALTER TABLE `websites` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-04-09 10:15:58
如果需要导出整个数据库的数据,可以使用以下命令:
root@jincheng-PC:~# mysqldump CODINGBOOK > /tmp/database_dump.txt
如果需要备份所有数据库,可以使用以下命令:
root@jincheng-PC:~# mysqldump --all-databases > database_dump.txt
其中,"–all-databases" 选项在 MySQL 3.23.12 及以后版本加入。该方法可用于实现数据库的备份策略。
将数据表及数据库拷贝至其他主机:
如果需要将数据复制到其他的 MySQL 服务器上,可以在 mysqldump 命令中指定数据库名和数据表。
在源主机上执行以下命令,将数据备份至 dump.txt 文件中:
$ mysqldump database_name table_name > dump.txt
如果完整备份数据库,则无需使用特定的表名。
如果您需要将备份的数据库引入到 MySQL 服务器中,可以使用以下命令,使用以下命令您需要确认数据库已经创建:
$ mysql database_name < dump.txt
也可以使用以下命令将导出的数据直接导入到远程的服务器上,但请确保两台服务器是相通的,是可以相互访问的:
$ mysqldump -u root -p database_name | mysql -h other-host.com database_name
以上命令中使用了管道来将导出的数据导入到指定的远程主机上。
34. 导入数据
mysql 命令导入:
# mysql < 要导入的数据库数据
mysql < /tmp/CODINGBOOK.sql
以上命令将备份的整个数据库 CODINGBOOK.sql 导入。
source
命令导入:
mysql> CREATE DATABASE abc; # 创建数据库
mysql> USE abc; # 使用已创建的数据库
mysql> set names utf8; # 设置编码
mysql> source /tmpabc.sql # 导入备份数据库
使用 LOAD DATA
导入数据:
MySQL 中提供了 LOAD DATA INFILE
语句来插入数据。
以下实例中将从当前目录中读取文件 dump.txt ,将该文件中的数据插入到当前数据库的 mytbl 表中。
mysql> LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl;
如果指定 LOCAL 关键词,则表明从客户主机上按路径读取文件。如果没有指定,则文件在服务器上按路径读取文件。你能明确地在 LOAD DATA 语句中指出列值的分隔符和行尾标记,但是默认标记是定位符和换行符。
两个命令的 FIELDS 和 LINES 子句的语法是一样的。两个子句都是可选的,但是如果两个同时被指定,FIELDS 子句必须出现在 LINES 子句之前。如果用户指定一个 FIELDS 子句,它的子句 (TERMINATED BY、[OPTIONALLY] ENCLOSED BY 和 ESCAPED BY)也是可选的,不过,用户必须至少指定它们中的一个。
mysql> LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl
-> FIELDS TERMINATED BY ':'
-> LINES TERMINATED BY '\r\n';
LOAD DATA 默认情况下是按照数据文件中列的顺序插入数据的,如果数据文件中的列与插入表中的列不一致,则需要指定列的顺序。
如,在数据文件中的列顺序是 a,b,c,但在插入表的列顺序为b,c,a,则数据导入语法如下:
mysql> LOAD DATA LOCAL INFILE 'dump.txt'
-> INTO TABLE mytbl (b, c, a);
4、使用 mysqlimport
导入数据:
$ mysqlimport --local mytbl dump.txt
可以指定选项来设置指定格式,命令语句格式如下:
$ mysqlimport --local --fields-terminated-by=":" --lines-terminated-by="\r\n" mytbl dump.txt
使用 --columns 选项来设置列的顺序:
$ mysqlimport --local --columns=b,c,a mytbl dump.txt
35. MySQL 函数
MySQL 有很多内置的函数,这里不做一一介绍,使用到的时候可自行查看手册或者上网查询。
36. 运算符
下面我们介绍 MySQL 的运算符及运算符的优先级。 MySQL 主要有以下几种运算符:
- 算术运算符
- 比较运算符
- 逻辑运算符
- 位运算符
算术运算符:
# 加
MariaDB [CODINGBOOK]> SELECT 1+2;
+-----+
| 1+2 |
+-----+
| 3 |
+-----+
1 row in set (0.12 sec)
# 减
MariaDB [CODINGBOOK]> SELECT 5-3;
+-----+
| 5-3 |
+-----+
| 2 |
+-----+
1 row in set (0.00 sec)
# 乘
MariaDB [CODINGBOOK]> SELECT 2*4;
+-----+
| 2*4 |
+-----+
| 8 |
+-----+
1 row in set (0.00 sec)
# 除
MariaDB [CODINGBOOK]> SELECT 8/2;
+--------+
| 8/2 |
+--------+
| 4.0000 |
+--------+
1 row in set (0.11 sec)
# 商
MariaDB [CODINGBOOK]> SELECT 9 DIV 4;
+---------+
| 9 DIV 4 |
+---------+
| 2 |
+---------+
1 row in set (0.12 sec)
# 取余
MariaDB [CODINGBOOK]> SELECT 9 MOD 4;
+---------+
| 9 MOD 4 |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
在除法运算和模运算中,如果除数为 0 ,将是非法除数,返回结果为 NULL。
比较运算符:
# 等于
MariaDB [CODINGBOOK]> SELECT 2=3;
+-----+
| 2=3 |
+-----+
| 0 |
+-----+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT NULL=NULL;
+-----------+
| NULL=NULL |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
# 不等于(!=)
MariaDB [CODINGBOOK]> SELECT 2<>3;
+------+
| 2<>3 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
# 安全等于(比较 NULL)
MariaDB [CODINGBOOK]> SELECT 2<=>3;
+-------+
| 2<=>3 |
+-------+
| 0 |
+-------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT NULL<=>NULL;
+-------------+
| NULL<=>NULL |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
# 小于
MariaDB [CODINGBOOK]> SELECT 2<3;
+-----+
| 2<3 |
+-----+
| 1 |
+-----+
1 row in set (0.00 sec)
# 大于
MariaDB [CODINGBOOK]> SELECT 2>3;
+-----+
| 2>3 |
+-----+
| 0 |
+-----+
1 row in set (0.00 sec)
# 在两值之间
MariaDB [CODINGBOOK]> SELECT 5 BETWEEN 1 AND 10;
+--------------------+
| 5 BETWEEN 1 AND 10 |
+--------------------+
| 1 |
+--------------------+
1 row in set (0.00 sec)
# 在集合中
MariaDB [CODINGBOOK]> SELECT 2 IN (1, 2, 3);
+----------------+
| 2 IN (1, 2, 3) |
+----------------+
| 1 |
+----------------+
1 row in set (0.00 sec)
# 不在集合中
MariaDB [CODINGBOOK]> SELECT 2 NOT IN (1, 2, 3);
+--------------------+
| 2 NOT IN (1, 2, 3) |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.00 sec)
# 为空
MariaDB [CODINGBOOK]> SELECT 2 IS NULL;
+-----------+
| 2 IS NULL |
+-----------+
| 0 |
+-----------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT NULL IS NULL;
+--------------+
| NULL IS NULL |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
# 不为空
MariaDB [CODINGBOOK]> SELECT 'a' IS NOT NULL;
+-----------------+
| 'a' IS NOT NULL |
+-----------------+
| 1 |
+-----------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT NULL IS NOT NULL;
+------------------+
| NULL IS NOT NULL |
+------------------+
| 0 |
+------------------+
1 row in set (0.00 sec)
# 模糊匹配
MariaDB [CODINGBOOK]> SELECT '12345' LIKE '12%';
+--------------------+
| '12345' LIKE '12%' |
+--------------------+
| 1 |
+--------------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT '12345' LIKE '12_';
+--------------------+
| '12345' LIKE '12_' |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.00 sec)
# 正则表达式匹配
MariaDB [CODINGBOOK]> SELECT 'codingbook' REGEXP 'book';
+----------------------------+
| 'codingbook' REGEXP 'book' |
+----------------------------+
| 1 |
+----------------------------+
1 row in set (0.14 sec)
MariaDB [CODINGBOOK]> SELECT 'codingbook' REGEXP 'mysql';
+-----------------------------+
| 'codingbook' REGEXP 'mysql' |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
逻辑运算符:
逻辑运算符用来判断表达式的真假。如果表达式是真,结果返回 1。如果表达式是假,结果返回 0。
# 与
MariaDB [CODINGBOOK]> SELECT 1 AND 0;
+---------+
| 1 AND 0 |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 AND 2;
+---------+
| 1 AND 2 |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
# 或
MariaDB [CODINGBOOK]> SELECT 1 OR 0;
+--------+
| 1 OR 0 |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 OR 2;
+--------+
| 1 OR 2 |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 0 OR 0;
+--------+
| 0 OR 0 |
+--------+
| 0 |
+--------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 || 0;
+--------+
| 1 || 0 |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
# 非
MariaDB [CODINGBOOK]> SELECT NOT 1;
+-------+
| NOT 1 |
+-------+
| 0 |
+-------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT NOT 0;
+-------+
| NOT 0 |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT !0;
+----+
| !0 |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
# 异或
MariaDB [CODINGBOOK]> SELECT 1 XOR 1;
+---------+
| 1 XOR 1 |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 XOR 2;
+---------+
| 1 XOR 2 |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 XOR 0;
+---------+
| 1 XOR 0 |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 XOR NULL;
+------------+
| 1 XOR NULL |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1 ^ 0;
+-------+
| 1 ^ 0 |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
位运算符:
位运算符是在二进制数上进行计算的运算符。位运算会先将操作数变成二进制数,进行位运算。然后再将计算结果从二进制数变回十进制数。
# 按位与
MariaDB [CODINGBOOK]> SELECT 1&2;
+-----+
| 1&2 |
+-----+
| 0 |
+-----+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]> SELECT 1&3;
+-----+
| 1&3 |
+-----+
| 1 |
+-----+
1 row in set (0.00 sec)
# 按位或
MariaDB [CODINGBOOK]> SELECT 3|5;
+-----+
| 3|5 |
+-----+
| 7 |
+-----+
1 row in set (0.00 sec)
# 按位异或
MariaDB [CODINGBOOK]> SELECT 2^4;
+-----+
| 2^4 |
+-----+
| 6 |
+-----+
1 row in set (0.00 sec)
# 按位取反
MariaDB [CODINGBOOK]> SELECT ~1;
+----------------------+
| ~1 |
+----------------------+
| 18446744073709551614 |
+----------------------+
1 row in set (0.00 sec)
# 按位右移
MariaDB [CODINGBOOK]> SELECT 4>>1;
+------+
| 4>>1 |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
# 按位左移
MariaDB [CODINGBOOK]> SELECT 3<<1;
+------+
| 3<<1 |
+------+
| 6 |
+------+
1 row in set (0.00 sec)
MariaDB [CODINGBOOK]>
运算符优先级:
优先级顺序 | 运算符 |
---|---|
1 | = |
2 | ||, OR, XOR |
3 | &&, AND |
4 | NOT |
5 | BETWEEN, CASE, WHEN, THEN, ELSE |
6 | =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN |
7 | | |
8 | & |
9 | <<, >> |
10 | -, + |
11 | *, /, DIV, %, MOD |
12 | ^ |
13 | -, ~ |
14 | ! |