Skip to content

3. 教程

本章通过演示如何使用 mysql 客户端程序创建和使用一个简单的数据库。mysql(有时称为“终端监视器”或简称为“监视器”)是一个交互式程序,使你能够连接到 MySQL 服务器,运行查询并查看结果。MySQL 也可以在批处理模式下使用:你事先将查询放在一个文件中,然后告诉 MySQL 执行文件的内容。这里介绍了使用 mysql 的两种方法。

要查看 mysql 提供的选项列表,请使用 --help 选项调用它:

bash
$> mysql --help

本章假定你的计算机上安装了 mysql,并且有可以连接的 MySQL 服务器。如果不是这样,请联系 MySQL 管理员。(如果你是管理员,则需要查阅本手册的相关部分,如 第 5 章 MySQL 服务器管理)。

本章介绍了设置和使用数据库的整个过程。如果只对访问现有数据库感兴趣,可以跳过介绍如何创建数据库及其包含的表的章节。

由于本章为教程性质,因此省略了许多细节。有关本章主题的更多信息,请参阅手册的相关章节。

3.1. 连接服务器和断开服务器连接

要连接服务器,通常需要在调用 mysql 时提供 MySQL 用户名,很可能还需要密码。如果服务器运行在一台机器上,且不是你登录的那台,你还必须指定一个主机名。请联系管理员,了解连接时应使用的连接参数(即使用什么主机、用户名和密码)。一旦知道了正确的参数,就可以像这样进行连接:

bash
$> mysql -h host -u user -p
Enter password: ********

hostuser 分别代表运行 MySQL 服务器的主机名和 MySQL 账户的用户名。请根据自己的设置替换适当的值。******** 代表密码;在 mysql 显示 Enter password: 提示时输入。

如果成功了,你会看到一些介绍信息,然后是 mysql> 提示符:

bash
$> 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.35-standard

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

mysql>

mysql> 提示符告诉你 mysql 已准备好供你输入 SQL 语句。

如果在运行 MySQL 的同一台机器上登录,可以省略 host,只需使用下面的命令:

bash
$> mysql -u user -p

如果你尝试登录时收到错误消息,如 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2), 这意味着 MySQL 服务器守护进程(Unix)或服务(Windows)未运行。请咨询管理员或参阅 第 2 章 安装和升级 MySQL 中适合你的操作系统的部分。

有关尝试登录时经常遇到的其他问题,请参阅 第 B.3.2 节 "使用 MySQL 程序时的常见错误"

有些 MySQL 安装允许用户以匿名(未命名)用户身份连接本地主机上运行的服务器。如果你的机器属于这种情况,你应该可以通过调用 mysql(不带任何选项)连接到该服务器:

bash
$> mysql

成功连接后,你可以在 mysql> 提示符下输入 QUIT(或 \q)随时断开连接:

bash
mysql> QUIT
Bye

在 Unix 上,也可以按 Ctrl+D 断开连接。

下文中的大多数示例都假定你已连接到服务器。它们通过 mysql> 提示符来说明这一点。

3.2. 输入查询

请确保已连接到服务器,如上一节所述。这样做本身并不选择任何要使用的数据库,但没关系。在这一点上,了解如何发出查询比直接创建表、将数据加载到其中以及从中检索数据更重要。本节介绍输入查询的基本原则,使用几个查询来熟悉 mysql 的工作原理。

下面是一个简单的查询,要求服务器告诉你它的版本号和当前日期。请在 mysql> 提示符下键入如图所示的内容,然后按下 Enter:

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

这个查询说明了关于 mysql 的几件事:

  • 查询通常由一条 SQL 语句和一个分号组成。(但也有省略分号的例外情况。前面提到的 QUIT 就是其中之一。其他情况我们稍后再谈)。
  • 当你发出一个查询时,mysql 会将其发送到服务器进行执行,并显示结果,然后打印另一个 mysql> 提示符,表明它已准备好进行另一个查询。
  • mysql 以表格形式(行和列)显示查询输出。第一行包含列的标签。后面的行就是查询结果。通常,列标签是从数据库表中获取的列名。如果检索的是表达式的值而不是表列(如刚刚显示的示例),mysql 会使用表达式本身来标注列。
  • mysql 会显示返回了多少行以及执行查询花费的时间,从而让你大致了解服务器的性能。这些值并不精确,因为它们代表的是挂钟时间(而不是 CPU 或机器时间),而且会受到服务器负载和网络延迟等因素的影响。(为简洁起见,本章其余示例中有时不显示“rows in set”一行)。

关键字可以任意大小写输入。以下查询是等价的:

bash
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;

下面是另一个查询。它演示了如何将 mysql 用作一个简单的计算器:

bash
mysql> SELECT SIN(PI()/4), (4+1)*5;
+------------------+---------+
| SIN(PI()/4)      | (4+1)*5 |
+------------------+---------+
| 0.70710678118655 |      25 |
+------------------+---------+
1 row in set (0.02 sec)

目前显示的查询都是相对较短的单行语句。你甚至可以在一行中输入多条语句。只需在每条语句末尾加上分号即可:

bash
mysql> SELECT VERSION(); SELECT NOW();
+-----------+
| VERSION() |
+-----------+
| 8.0.13    |
+-----------+
1 row in set (0.00 sec)

+---------------------+
| NOW()               |
+---------------------+
| 2018-08-24 00:56:40 |
+---------------------+
1 row in set (0.00 sec)

查询不需要全部写在一行上,因此需要多行的冗长查询也不成问题。mysql 通过查找结束分号,而不是输入行的末尾来确定语句的结束位置(换句话说,mysql 接受自由格式的输入:它收集输入行,但在看到分号之前不会执行它们。)

下面是一个简单的多行语句:

bash
mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+---------------+--------------+
| USER()        | CURRENT_DATE |
+---------------+--------------+
| jon@localhost | 2018-08-24   |
+---------------+--------------+

在此示例中,请注意在输入多行查询的第一行后,提示符从 mysql> 变为 ->。这是 mysql 表明它尚未看到完整语句并正在等待其余语句的方式。友好的提示提供了有价值的反馈。如果你理解该反馈的含义,你总是可以知道 mysql 在等待什么。

如果你决定不执行正在输入的查询,请键入 \c 取消查询:

bash
mysql> SELECT
    -> USER()
    -> \c
mysql>

这里也要注意提示符。在你输入 \c 后,它会切换回 mysql>,提供反馈以表明 mysql 已准备好进行新的查询。

下表列出了你可能看到的每个提示,并总结了它们对 mysql 所处状态的含义。

提示符含义
mysql>为新查询做好准备
->等待下一行多行查询
'>等待下一行,等待完成以单引号(')开头的字符串
">等待下一行,等待完成以双引号(") 开头的字符串
`>等待下一行,等待完成以反引号(`)开头的标识符
/*>等待下一行,等待完成以 /* 开头的注释

当你打算发出单行语句查询时,但忘记结束分号时,通常会导致其变为多行语句。mysql 会等待更多的输入:

bash
mysql> SELECT USER()
    ->

如果这种情况发生在你身上(你认为你已经输入了一个语句,但唯一的响应是一个 -> 提示符),则很可能 mysql 正在等待分号。如果你没有注意到提示符给你的反馈,你可能会坐在那里一段时间才意识到你需要做什么。输入分号来完成语句,mysql 会执行它:

bash
mysql> SELECT USER()
    -> ;
+---------------+
| USER()        |
+---------------+
| jon@localhost |
+---------------+

'>"> 提示符出现在字符串收集过程中(另一种说法是 MySQL 正在等待字符串的完成)。在 MySQL 中,你可以写以 '" 字符包围的字符串(例如,'hello'"goodbye"),而且 mysql 还允许你输入跨多行的字符串。当你看到 '>"> 提示时,这意味着你已经输入了一行包含以 '" 引号字符开头的字符串,但尚未输入终止字符串的匹配引号。这通常表示你无意间漏掉了一个引号字符。例如:

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

如果输入这条 SELECT 语句,然后按下 Enter 并等待结果,则什么也不会发生。不要奇怪为什么这个查询要花这么长时间,而是注意 '> 提示符提供的线索。它告诉你 mysql 期望看到未终止字符串的其余部分。(你看到语句中的错误了吗?字符串 'Smith 缺少第二个单引号。)

这时,你该怎么办?最简单的办法就是取消查询。但是,在这种情况下你不能直接输入 \c,因为 mysql 会把它理解为正在收集的字符串的一部分。取而代之的是,输入结束引号字符(这样 mysql 就知道你已经完成了字符串),然后键入 \c

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

提示符变回 mysql>,表示 mysql 已准备好进行新查询。

`> 提示符类似于 '>"> 提示符,但表示你已经开始但尚未完成反引号标识符。

了解 '>">`> 提示符的含义很重要,因为如果错误地输入了一个未结束的字符串,mysql 将忽略你输入的任何其他行,包括 QUIT。这可能会让人相当困惑,特别是如果你不知道在取消当前查询之前需要提供结束符。

注意

从现在起,多行语句将不使用辅助(-> 或其他)提示,以便于更轻松地复制和粘贴语句供自己尝试。

3.3. 创建和使用数据库

一旦你知道如何输入 SQL 语句,你就可以访问数据库了。

假设你家里有几只宠物(你的动物园),你想记录它们的各种信息。为此,你可以创建表格来保存数据,并在其中加载所需的信息。然后,你就可以通过检索表格中的数据来回答有关动物的各种问题。本节将向你展示如何执行以下操作:

  • 创建数据库
  • 创建表
  • 将数据加载到表中
  • 以各种方式从表中检索数据
  • 使用多个表

动物园数据库很简单(有意为之),但不难想到在现实世界中可能使用类似类型的数据库。例如,像这样的数据库可以被农民用来跟踪牲畜,或者被兽医用来跟踪患者的记录。可以从 MySQL 网站获得包含以下部分中使用的一些查询和示例数据的动物园发行版。在 https://dev.mysql.com/doc/ 上可以找到压缩的 tar 和 zip 格式文件。

使用 SHOW 语句查找服务器上当前存在哪些数据库:

bash
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+

mysql 数据库描述了用户访问权限。test 数据库通常可用作用户进行试验的工作区。

语句显示的数据库列表在你的计算机上可能有所不同;如果你没有 SHOW DATABASES 权限,SHOW DATABASES 不会显示你没有权限访问的数据库。请参阅 第 13.7.7.14 节 “SHOW DATABASES 语句”

如果 test 数据库存在,请尝试访问它:

bash
mysql> USE test
Database changed

USEQUIT 一样,不需要分号。(如果你愿意,可以用分号来结束此类语句;这样做没有坏处)。USE 语句还有一个特殊之处:它必须在一行中给出。

你可以在下面的示例中使用 test 数据库(如果你有访问权限的话),但你在该数据库中创建的任何内容都可能被有访问权限的其他人删除。因此,你最好向 MySQL 管理员申请使用自己的数据库。假设你想调用你的动物园。管理员需要执行如下语句:

bash
mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';

其中 your_mysql_name 是分配给你的 MySQL 用户名,your_client_host 是你连接服务器的主机。

3.3.1 创建和选择数据库

如果管理员在设置权限时为你创建了数据库,你就可以开始使用它了。否则,你需要自己创建:

bash
mysql> CREATE DATABASE menagerie;

在 Unix 下,数据库名称区分大小写(与 SQL 关键字不同),因此必须始终将数据库称为 menagerie,而不是 MenagerieMENAGERIE 或其他变体。表名也是如此。(在 Windows 下,这一限制并不适用,不过在整个查询过程中,你必须使用相同的字母大小写来称呼数据库和表。不过,由于各种原因,建议的最佳做法是始终使用创建数据库时使用的相同大小写)。

注意

如果出现类似 ERROR 1044 (42000) : Access denied for user 'micah'@'localhost' to database 'menagerie' when attempting to create a database,这意味着用户账户不具备创建数据库所需的权限。请与管理员讨论,或参阅 第 6.2 节 “访问控制和账户管理”

创建数据库时不会默认设定它为当前数据库;你必须明确地执行此操作。要将 menagerie 作为当前数据库,请使用此语句:

bash
mysql> USE menagerie
Database changed

你的数据库只需创建一次,但每次开始 mysql 会话时都必须重新设定它为当前数据库。如示例所示,你可以通过使用 USE 语句来做到这一点。或者,也可以在调用 mysql 时通过命令行选择数据库。只需在可能需要提供的任何连接参数后指定数据库名称即可。例如:

bash
$> mysql -h host -u user -p menagerie
Enter password: ********

重要

命令行中的 menagerie 并不是你的密码。如果要在 -p 选项后的命令行中输入密码,必须在输入时不留空格(例如,输入 -ppassword,而不是 -p password)。不过,我们不建议在命令行上输入密码,因为这样做会使密码暴露给计算机上的其他用户。

注意

你可以随时使用 SELECT DATABASE() 查看当前选择的数据库。

Released under the GPL-3.0 License.