MySQL 简介

本节内容主要引自 MySQL 8.0 Reference Manual

MySQL 是一款开源的关系数据库管理系统(RDBMS),最早由瑞典公司 MySQL AB 拥有,现在归 Oracle 所有。对于专有使用,有几个付费版本可用,并提供额外的功能。

MySQL 是开源网页应用软件栈 LAMP 的中心组件。MySQL 常被用于许多大型网站。

MySQL 是用 C 和 C++ 语言编写的,可工作于许多系统平台。

当前仍在支持的版本为 5.5、5.6、5.7,最新版本为 8.0。

MySQL 特点

MySQL 提供两个版本:开源社区服务器版和企业专用服务器版。

企业版含有一系列专用的扩展,以服务器插件的形式安装。

  • 为多种编程语言提供了 API,包括 C、Java、PHP、Python、Ruby 等
  • 支持多线程,充分利用 CPU 资源,支持多用户
  • 优化的 SQL 查询算法,有效地提高查询速度
  • 既能够作为一个单独的应用程序在客户端服务器网络环境中运行,也能够作为一个程序库而嵌入到其他的软件中
  • 提供 TCP/IP、ODBC 和 JDBC 等多种数据库连接途径
  • 提供用于管理、检查、优化数据库操作的管理工具
  • 可以处理拥有上千万条记录的大型数据库

应用

与其他的大型数据库例如 Oracle、IBM DB2、MS SQL 等相比,MySQL 自有它的不足之处,如规模小、功能有限等,但是这丝毫也没有减少它受欢迎的程度。对于一般的个人用户和中小型企业来说,MySQL 提供的功能已经绰绰有余,而且由于 MySQL 是开放源代码软件,因此可以大大降低总体拥有成本。

2010 年以前互联网上流行的网站构架方式是 LAMP(Linux Apache MySQL PHP),即使用 Linux 作为操作系统,Apache 作为 Web 服务器,MySQL 作为数据库,PHP(部分网站也使用 Perl 或 Python)作为服务器端脚本解释器。由于这四个软件都是开放源代码软件,因此使用这种方式可以以较低的成本创建起一个稳定、免费的网站系统。

MySQL + PHP 的搭配在互联网上的应用相比 LAMP 来说更为常见,并获得了 “动态配对”(Dynamic Duo)的雅号,大部分 Blog 网站基于的 WordPress 系统即基于此。除了 LAMP 之外,用于 Solaris、Windows 和 Mac 上的网站构架也分别被称为 SAMP、WAMP 和 MAMP。

MySQL 管理

可以使用命令行工具管理 MySQL 数据库(命令为 mysqlmysqladmin),也可以从 MySQL 的网站下载图形管理工具 MySQL Workbench。

Navicat 导航猫 for MySQL 是一套专为 MySQL 设计的强大数据库管理及开发工具。它可以用于任何版本的 MySQL 数据库,并支持大部分 MySQL 的功能,包括触发器、索引、查看等。

phpMyAdmin 是由 PHP 写成的 MySQL 数据库系统管理程序,让管理者可用 Web 接口管理 MySQL 数据库。借由此 Web 接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量数据的导入及导出更为方便。其中一个更大的优势在于由于 phpMyAdmin 跟其他 PHP 程序一样在网页服务器上运行,但是您可以在任何地方使用这些程序产生的 HTML 页面,即远程管理你的 MySQL 数据库。使用 phpMyAdmin 可以方便的创建、修改、删除数据库及数据表。

phpMyBackupPro 也是由 PHP 写成的,可以通过 Web 接口创建和管理数据库。它可以创建伪 cronjobs,可以自动在某个时间或周期性备份 MySQL 数据库。

连接方式

应用程序可通过 ODBC 或 ADO 方式,经由使用 MyODBC 与 MySQL 数据库连接。

MS.Net Framework 下的程序(例如:C#、VB.NET)可通过 ADO.NET 的方式,经由使用 MySQL.Net 与 MySQL 数据库连接。

C/C++ 可使用 MySQL++ 或是直接使用 MySQL 内置 API 与 MySQL 数据库连接。

PHP 可通过 PHP 的 MySQLi 与 MySQL 数据库连接,具备比 MySQL 模块更好的性能。另外 PHP6 可使用 mysqlnd 与 MySQL 数据库连接。

JAVA 程序可通过 JDBC 方式与 MySQL 进行连接,MySQL 官方提供了 JDBC 驱动程序。

可通过 MySQL 客户端软件与 MySQL 进行连接,如 mysqlfront、mysqlyog、mysqlbrowser 等。

javascript 可以通过使用 fibjs 的内置 mysql 模块与 MySQL 数据库连接。

派生版本

派生版本有 Drizzle、MariaDB、Percona Server 及 OurDelta 等。

MySQL 的安装

选择版本

在 MySQL 官网查询各平台可用版本。

首先要考虑是安装二进制文件还是源代码,其次要考虑是安装开发版本还是一般可用版本(GA,General Availability)。开发版会有些新的功能,但不推荐实际生产使用。GA 版本也称生产版,或稳定版,是为生产准备的。因此推荐安装最新的 GA 版本。

版本命名

版本 8.0 的命名规则为三个数字加上一个可选的后缀,如 mysql-8.0.1-dmr。

三位数字含义:

  • 8 :主版本号
  • 0 :次版本号。主+次版本号组合在一起即发行序列版本号,该版本号决定了其稳定的功能组成。
  • 1 : 序列版本号内的版本号,每次小更新会加 1,多数情况下,某序列版本的最新版本是比较好的选择。

后缀:

后缀为可选,用于表示该版本的稳定级别。

  • dmr : Development Milestone Release,DMR 里程碑版本。MySQL 开发时使用一种里程碑模型,每个里程碑会带来一小组经测试的新功能。从一个里程碑到下一个,功能接口可能会发生改变,甚至可能被删除,均基于社区成员的测试反馈。里程碑版本中的功能可以看作前生产水平。
  • rc : Release Candidate,RC。候选发布版,最终测试版本。该版本比较稳定,通过了所有 MySQL 内部测试。RC 版本中仍有可能加入新功能,但其精力主要集中在修复之前版本功能的 bug。
  • 无后缀 : General Availability,GA。最终稳定版。

文件格式

多数情况下应该选择二进制版本,如 RPM 软件包。

其他情况下,有可能会需要从源代码版本来安装:

  • 需要把 MySQL 安装到特殊位置
  • 需要为 mysqld 配置一些在标准二进制软件包中没有的功能,常用的有:
    • -DWITH_LIBWRAP=1 支持 TCP 包裹
    • -DWITH_ZLIB={system|bundled} 安装基于压缩的功能
    • -DWITH_DEBUG=1 支持调试
  • 需要配置 mysqld 时去掉某些功能
  • 需要阅读或修改 MySQL 的源文件
  • 源代码版本包含更多的测试和范例

MySQL 文件分布

目录 内容
bin mysqld 服务器,客户端,及工具软件
docs 说明文档,info 格式
man man pages
include 头文件
lib 运行库
share 错误消息,词典,数据库安装的 SQL
support-files 其它支持文件

安装 MySQL

安装

sudo yum install mysql-community-server

启动

sudo systemctl start mysqld.service

MySQL Server 初始化

在服务初始化启动时,会发生以下事件:

  • 服务器初始化
  • 生成 SSL 证书与密钥文件
  • 安装并启用密码验证插件
  • 创建超级用户 root',用 sudo grep ‘temporary password’ /var/log/mysqld.log` 查询其初始密码

安装后要第一时间修改超级用户的密码:

$ mysql -u root -p
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';

MySQL 的密码验证插件是默认安装的,它会要求密码至少有一个大写字母、一个小写字母、一位数字、一个特殊符号,至少 8 位。

MySQL 的简单操作

连接到 MySQL 服务器

要想连接到服务器,通常需要 MySQL 用户名和密码,如果要连接到其它主机,还需要主机名。

连接到远程主机

$ mysql -h host -u user -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25338 to server version: 8.0.13-standard

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

连接到本机

$ mysql -u user -p

匿名访问

如果本地主机开启了匿名 MySQL 访问,则无需用户名和密码,直接 mysql 就能进入。

退出

QUIT 注意,该命令后面不需要分号结束。

查询

连接到服务器以后,可以进行数据库的查询。

mysql> SELECT VERSION(), CURRENT_DATE;
+-----------+--------------+
| VERSION() | CURRENT_DATE |
+-----------+--------------+
| 5.8.0-m17 | 2015-12-21   |
+-----------+--------------+
1 row in set (0.02 sec)
mysql>

查询要点

查询语句及关键字 不分大小写

可以在一行键入多个查询语句,中间用分号分隔,如 mysql> SELECT VERSION(); SELECT NOW();

命令太长可以直接回车在下一行继续输入,如果中途要取消输入,可以键入 \c

查询结果

  • 查询通常由 SQL 语句加上 分号 组成
  • 查询时,mysql 将语句发送给服务器执行,回显结果,返回提示符
  • mysql 以 表格的形式 显示查询结果
  • 查询结果的最后会告知返回了 多少行

提示符

不同情况下会显示不同的提示符:

提示符 含义
mysql> 就绪,可以查询
-> 多行输入状态,等待下一行
'> 等待下一行,等待一个单引号开头的字符串的结束
"> 等待下一行,等待一个双引号开头的字符串的结束
`> 等待下一行,等待一个反引号开头的描述符的结束
/*> 等待下一行,等待一个 /* 开头的注释的结束

如果命令行的结尾不是分号,通常就会进入多行输入状态:

mysql> SELECT USER()
    ->

此时如果你确认已经完成了语句的输入,直接键入分号,回车即可。

至于 '>"> 提示符,主要发生在收集字符串期间,即 MySQL 在等待用户完成一个字符串的键入。在 MySQL 中,你可以用单引号或双引号把字符串引用起来,而且允许长字符串跨越多行。当看到 '>"> 提示符时,说明你已经键入了一行以单引号或双引号开头的字符串,但还没有结束引用,只有结束了引用才算完成了字符串的键入。

mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
    '>

第二行的提示符变成了 '>,你才发现忘记给 Smith 结束引号了。此时,能做的只有键入 \c 来取消输入,回到正常提示符再重新输入。

创建和使用数据库

查看当前数据库

通过 SHOW DATABASE 命令来查看当前数据库列表。

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.04 sec)

该命令只能显示当前数据库用户有权访问的数据库。

mysql 数据库用于描述用户访问权限。

创建、选择数据库

创建数据库

创建数据库的命令为 CREATE

mysql> CREATE DATABASE test;

数据库名字是大小写敏感的,要注意。同样,表格名称也是大小写敏感。

无论怎样,建议始终保持有规律的大小写命名规则。

使用数据库

每次开始一个 mqsql 会话时,在使用数据库之前,必须要先选择它,使用 USE 命令:

mysql> USE mysql;
Database changed

USE 命令在行尾也不需要分号。但你非要加也没问题。而且该命令必须 单独在一行执行

另一种选择数据库的方法是在调用 mysql 时就选择:

$ mysql -h host -u user -p test
Enter password:

创建表格

查看表格列表

SHOW TABLES 命令查看当前数据库表格列表

mysql> SHOW TABLES;
Empty set (0.00 sec)
创建表格

CREATE TABLE 命令创建表格。

mysql> CREATE TABLE album (name VARCHAR(30), artist VARCHAR(20),
    -> year DATE, genre VARCHAR(20), comment VARCHAR(90));

为了确认表格创建成功,可以使用 DESCRIBE 命令来查看表格的结构:

mysql> DESCRIBE album;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| name     | varchar(40) | YES  |     | NULL    |       |
| artist   | varchar(20) | YES  |     | NULL    |       |
| year     | date        | YES  |     | NULL    |       |
| genre    | varchar(20) | YES  |     | NULL    |       |
| comment  | varchar(90) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+
5 rows in set (0.01 sec)

为表格填充数据

表格创建以后,要想填充数据,可以使用 LOAD DATAINSERT 命令来完成。

LOAD DATA 导入文件

要想批量导入较多数据,可以事先编辑一个纯文本文件,每一行是一个记录,每个字段用 tab 分隔。

如果该条记录中某字段为空,可以用 \N 表示,即 NULL 空值。

love 1990	LuoDaYou	1994-7-8	\N

导入时用以下方式:

mysql> LOAD DATA LOCAL INFILE '/path/albums.txt' INTO TABLE album;

如果文本文件是在 windows 操作系统中编辑的,其换行符会是 \r\n,因此上面的语句应换成:

mysql> LOAD DATA LOCAL INFILE '/path/albums.txt' INTO TABLE album
    -> LINES TERMINATED BY '\r\n';

如果是在 MACOSX 中编辑的,则要换成 LINES TERMINATED BY '\r'

LOAD DATA LOCAL 的安全隐患

LOAD DATA 语句可以加载 服务器本机 上的文件,也可以用 LOAD DATA LOCAL 来加载 客户端主机 中的文件。

使用 LOAD DATA LOCAL 会有以下风险:

  • 从客户端主机向服务端主机 传送文件 是由 MySQL 服务端发起 的。理论上讲,可以做到服务器通知客户端程序,让其发送由服务端选择的文件,而非由客户端执行的 LOAD DATA 语句指定文件名。这样的服务端可以访问客户端主机中,当前用户有权访问的所有文件。实际上,这样的服务器可以设置成对客户端发送的任何语句都回应一个发送文件的请求,不仅仅针对 LOAD DATA LOCAL 语句。因此,最根本的安全隐患在于,客户端不要连接到不可信的服务器
  • 在网页服务器的环境下,数据库客户端是从网页服务器发起连接的,数据库用户可以通过 LOAD DATA LOCAL 语句,从网页服务器读取任何该网页服务进程有权读取的文件。在这种环境下,对 MySQL 服务端来说,其 客户端实际上是网页服务器,而不是连接到网页服务器上的某个远程用户。
如何启用 LOAD DATA LOCAL

为了防止 LOAD DATA 造成问题,客户端应避免使用 LOCAL,并且应避免连接到不可信的服务器。连接时,应使用 --ssl-mode=VERIFY_IDENTITY 选项,并使用对应的 CA 证书,以验证服务器的身份。

MySQL 的服务端和客户端必须同时启用 LOCAL,客户端才能使用 LOAD DATA LOCAL 语句来导入数据,否则会收到如下错误消息:

ERROR 1148 (42000): The used command is not allowed with this MySQL version

服务端:

需要在 /etc/my.cnf 配置文件中的 [mysqld] 区段设置 local-infile=1,以便启用服务端的 LOCAL 功能。

客户端:

在调用 mysql 时要加上 --local-infile 参数:

mysql --local-infile -u root -p

或者,在 /etc/my.cnf 配置文件中的 [mysql] 区段设置 local-infile=1,启用客户端的 LOCAL 功能。

INSERT 语句添加记录

如果要每次增加一条记录,可以使用 INSERT 语句。

mysql> INSERT INTO album
    -> VALUES ('the Wall', 'Pink Floyd', '1978-01-01','rock',NULL);

字符串和日期都被 引用,可以为无值的字段 直接插入 NULL,无需像编辑文本时用 \N。

从表格中检索信息

通常使用 SELECT 语句从表格中检索信息。

SELECT what
FROM table
WHERE conditions;

what 可以是要检索的列,或用 * 表示所有列

table 要检索哪个表格

WHERE 是可选的,如果有,则用 conditions 来指定检索记录必须满足的条件

选择所有数据

SELECT 语句 查看 表格 所有记录

mysql> SELECT * FROM album;

如果要 删除 表格的 所有记录

mysql> DELETE FROM album;

修改某条记录

mysql> UPDATE album SET title = 'the wall' WHERE title = 'wall'
选择特定行
mysql> SELECT * FROM album WHERE title = 'the wall';

过滤条件中的字符串通常是大小写不敏感的。

mysql> SELECT * FROM album WHERE year >= '1980-1-1';

可以用组合条件来过滤:

mysql> SELECT * FROM album WHERE title = 'the wall' AND artist = 'Pink Floyd';
mysql> SELECT * FROM album WHERE artist = 'Pink Floyd' OR artist = 'Cui Jian';
选择特定列
mysql> SELECT artist, title FROM album;

要想让重复的行只显示一次,可以使用 DISTINCT 参数:

mysql> SELECT DISTINT title FROM album;

条件过滤 配合使用:

mysql> SELECT title, artist WHERE year >= '1999-9-9';
为行排序

ORDER BY 子句来为检索的行排序:

mysql> SELECT title, artist FROM album ORDER BY year;

默认为升序排列,如需降序排列可以在后面加上 DESC

mysql> SELECT title, artist FROM album ORDER BY year DESC;
计算日期

现有表格 pet,记录宠物的基本信息,字段为:nameownerspeciessexbirthdeath

MySQL 提供了几种计算日期的函数。如 TIMESTAMPDIFF 函数可以用两个日期来计算它们之间的年数。

如表格中有宠物名、生日,则可以用该函数来计算每个宠物的年龄:

TIMESTAMPDIFF(YEAR,birth,CURDATE()) 表示计算 birthCURDATE() 这两个日期差了几年。

mysql> SELECT name, birth, CURDATE(),
    -> TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
    -> FROM pet ORDER BY age;
	+----------+------------+------------+------+
	| name     | birth      | CURDATE()  | age  |
	+----------+------------+------------+------+
	| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
	| Puffball | 1999-03-30 | 2003-08-19 |    4 |
	| Whistler | 1997-12-09 | 2003-08-19 |    5 |
	| Slim     | 1996-04-29 | 2003-08-19 |    7 |
	| Claws    | 1994-03-17 | 2003-08-19 |    9 |
	| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
	| Fang     | 1990-08-27 | 2003-08-19 |   12 |
	| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
	| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
	+----------+------------+------------+------+

其中 CURDATE() 为当前日期,age 为计算出来的年龄。这两列都是由 SELECT 语句生成的,不在表格中。

下例为从宠物统计表格中为死去的宠物计算寿命:

mysql> SELECT name, birth, death,
    -> TIMESTAMPDIFF(YEAR,birth,death) AS age
    -> FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name   | birth      | death      | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 |    5 |
+--------+------------+------------+------+

因为 NULL 是一个特殊的值,它不能用 <> 操作符来比较。

检索哪个宠物下月过生日:

mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name  | birth      |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+

MONTH(birth) = 5 表示 birth 日期中的月份为 5。

空值的使用

NULL 做为空值使用。

要测试某字段是否空值,只可以用 IS NULLIS NOT NULL

mysql> SELECT 1 IS NULL, 1 IS NOT NULL;

不能使用 =<<> 这些算术比较符来测试 NULL,因为任何算术比较符与 NULL 比较之后的结果仍是 NULL

在 MySQL 中,0NULL 代表逻辑假,任何其它的都代表逻辑真。布尔操作的真默认用 1 来表示。

事实上,空字符并不等于 NULL

mysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
|         0 |             1 |          0 |              1 |
+-----------+---------------+------------+----------------+
模式匹配

MySQL 使用标准的 SQL 模式匹配,基于扩展正则表达式。

_ 匹配任何单个字符

% 匹配任意数量的字符,包括 0 个字符。

模式匹配中,默认是大小写不敏感的。

匹配的操作符是 LIKENOT LIKE,而不是习惯中的 =<>

通配符

b 开头的名字:

SELECT * FROM pet WHERE name LIKE 'b%';

fy 结尾的名字:

SELECT * FROM pet WHERE name LIKE '%fy';

包含 w 的名字:

SELECT * FROM pet WHERE name LIKE '%w%';

五个字符的名字:

SELECT * FROM pet WHERE name LIKE '_____';

扩展正则表达式

通过 REGEXP_LIE() 函数来匹配正则表达式。

匹配行中的名字以 b 开头:

mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b');

如果需要在匹配时 大小写敏感,可以加上 c 这个匹配控制字符:

SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b', 'c');

匹配行中的名字以 fy 结尾:

mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, 'fy$');

匹配行中的名字中包含 w

mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, 'w');

匹配行中的名字为 5 个字符:

mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^.{5}$');
统计行数
显示所有字段

统计行数时,要显示表格所有字段,则 SELECT 后面不指定字段名。统计表格所有行数:

mysql> SELECT COUNT(*) FROM pet;
显示特定字段

统计行数时,要想显示指定的字段,则必须在 SELECT 语句后指明要显示的字段,同时,还要用该字段来排序,即 GROUP BY 相同的字段。这样才能正常显示。

为检索的信息统计行数:

mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner  | COUNT(*) |
+--------+----------+
| Benny  |        2 |
| Diane  |        2 |
| Gwen   |        3 |
| Harold |        2 |
+--------+----------+
mysql> SELECT species, sex, COUNT(*) FROM pet
    -> WHERE species = 'dog' OR species = 'cat'
    -> GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
+---------+------+----------+
使用多个表格
连接两个不同的表格

pet 表格基础上,再增加一个表格 event,保存宠物的一些经历,如看病记录、生崽记录等。字段为 namedatetyperemakr

假设现在你想了解这些宠物在哪些年龄段会生育,event 表格中有生育的记录,但没有年龄。没关系,我们可以根据生育记录中的日期来计算当时的年龄,因此又需要 pet 表格。这意味着这个查询同时需要两张表格的数据:

mysql> SELECT pet.name,
    -> TIMESTAMPDIFF(YEAR,birth,date) AS age,
    -> remark
    -> FROM pet INNER JOIN event
    ->   ON pet.name = event.name
    -> WHERE event.type = 'litter';
+--------+------+-----------------------------+
| name   | age  | remark                      |
+--------+------+-----------------------------+
| Fluffy |    2 | 4 kittens, 3 female, 1 male |
| Buffy  |    4 | 5 puppies, 2 female, 3 male |
| Buffy  |    5 | 3 puppies, 3 female         |
+--------+------+-----------------------------+

从该查询我们可以学习到:

  • FROM 子句会把两张表格连起来,因为需要同时从两张表格中提取数据。
  • 要想把两张表格中对应的数据连起来,必须要指定一张表格中的记录要如何匹配另一表格中的记录。因为两张表格共同的字段为 name,因此我们基于 name 的值,使用 ON 子句来匹配两张表中同一名字对应的记录。
  • 使用 INNER JOIN 连接两张表。然后通过 ON 子句来指明,必须在两张表中同时存在该字段的同一个值,该行才被匹配。
  • 因为 name 在两张表中都有,为了区分不同表的字段,在 name 前面用表格名称做前缀 pet.name
连接同一个表格

不是非要两个不同的表格才能进行连接,有时候甚至可以连接自己。

如果想要比较同一表格中的不同记录,就可以连接同一表格。

例如,想要在同一种宠物间匹配一对来生育:

mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
    -> FROM pet AS p1 INNER JOIN pet AS p2
    ->   ON p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name   | sex  | name   | sex  | species |
+--------+------+--------+------+---------+
| Fluffy | f    | Claws  | m    | cat     |
| Buffy  | f    | Fang   | m    | dog     |
| Buffy  | f    | Bowser | m    | dog     |
+--------+------+--------+------+---------+

重要一点是要在 FROM 子句中为表格起两个不同的别名,然后用不同的别名来匹配。

查看数据库和表格的信息

查看当前 在用的数据库

mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+

如果当前没有使用任何数据库,返回结果为 NULL

查看在用数据库包含哪些表:

mysql> SHOW TABLES;
+---------------------+
| Tables_in_menagerie |
+---------------------+
| event               |
| pet                 |
+---------------------+

查看表格的结构:

mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

key 表示该字段是否被索引

Default 表示该字段的默认值

Extra 表示该字段的特殊信息。如果建表时使用了 AUTO_INCREMENT 选项,该值将是 auto_increment

MySQL 批处理模式

除了以交互模式运行 MySQL 外,还可以以批处理模式来运行。可以把语句保存到文件中,然后让 mysql 云读取:

$ mysql < batch-file

也可以指定一些连接的参数:

$ mysql -h host -u user -p < batch-file

如果希望执行脚本期间即使遇到错误也继续执行,可以用 --force 选项。

使用脚本的好处

  • 如果需要频繁地进行查询,做成脚本可以省去很多敲命令的时间
  • 可以很方便从现有查询中复制,修改成新的查询
  • 对于多条语句的查询,发现错误,在脚本里很快就能修改,不用重复敲命令
  • 如果查询的输出特别多,在批处理模式中可以借助管道逐页查看,或干脆重定向到文件中
  • 脚本便于分享
  • 可以用于 cron

批处理的选项

使用批处理模式时,默认其输出会更加简洁,去掉了表格装饰线条。如果希望输出同交互式输出一样,可以使用 mysql -t 选项。

使用 mysql -v 来回显每条语句。

另一种运行批处理的方法

也可以在 mysql 提示符中,使用 source 命令 或 \. 来运行脚本:

mysql> source filename;
mysql> \. filename

与 Apache 配合使用 MySQL

有一些程序需要使用 MySQL 数据库来进行用户的验证,或者把日志文件写入 MySQL 表。

通过修改 Apache 配置文件,我们可以修改其日志的格式,以便更利于被 MySQL 读取。

可以用以下语句把 Apache 日志文件导入 MySQL:

LOAD DATA INFILE '/local/access_log' INTO TABLE tbl_name
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'

当然,提前做好一个空表,把字段与日志文件相对应。