精通-PHPMyAdmin-3-4-高效-MySQL-管理-全-

精通 PHPMyAdmin 3.4 高效 MySQL 管理(全)

原文:zh.annas-archive.org/md5/3B102B7D75B6F6D265E7C3CE6613ECC1

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

phpMyAdmin 是一个处理 MySQL 管理的开源 Web 界面。它可以执行各种任务,如创建、修改或删除数据库、表、列或行。它还可以执行 SQL 语句或管理用户及其权限。即使是经验丰富的开发人员和系统管理员,在充分利用 phpMyAdmin 的潜力时,也会寻找教程来完成他们的任务。

《精通 phpMyAdmin 3.4 以实现有效的 MySQL 管理》是一本易于阅读的,逐步实用的指南,将带领您了解这个传奇工具 phpMyAdmin 的每个方面,并带您迈出一步,充分利用其潜力。本书充满了例证性的例子,将帮助您详细了解 phpMyAdmin 的每个功能。

本书首先介绍了安装和配置 phpMyAdmin,然后深入研究了 phpMyAdmin 的功能。接着是在 phpMyAdmin 中配置身份验证,并设置影响整体界面的参数,包括新的用户偏好功能。您将首先创建两个基本表,然后编辑、删除数据、表和数据库。由于备份对于项目至关重要,您将创建最新的备份,然后研究导入您已导出的数据。您还将探索各种搜索机制,并跨多个表进行查询。

现在您将学习一些高级功能,例如定义表间关系,包括关系视图和设计师面板。一些查询超出了界面的范围;您将输入 SQL 命令来完成这些任务。

您还将学习如何同步不同服务器上的数据库,并管理 MySQL 复制以提高性能和数据安全性。您还将将查询存储为书签以便快速检索。在本书的最后,您将学习如何记录数据库,跟踪对数据库的更改,并使用 phpMyAdmin 服务器管理功能管理用户帐户。

这本书是对之前版本的升级,之前版本涵盖了 phpMyAdmin 3.3 版。3.4.x 版本引入了一些新功能,例如用户偏好模块,关系模式导出到多种格式,ENUM/SET 列编辑器,简化的导出和导入界面,某些页面上的 AJAX 界面,图表生成以及可视化查询构建器。

本书内容

第一章,“使用 phpMyAdmin 入门”,介绍了我们应该使用 phpMyAdmin 来管理 MySQL 数据库的原因。然后涵盖了下载和安装 phpMyAdmin 的程序。还介绍了安装 phpMyAdmin 配置存储。

第二章,“配置身份验证和安全”,概述了 phpMyAdmin 中使用的各种身份验证类型。然后涵盖了与 phpMyAdmin 相关的安全问题。

第三章,“界面概述”,为我们提供了 phpMyAdmin 界面的概述。它包括登录面板,带有 Light 和 Full 模式的导航和主面板,以及查询窗口。新的用户偏好模块也在本章中进行了讨论。

第四章,“创建和浏览表”,主要讲述了数据库的创建。它教会我们如何创建表,如何手动插入数据,以及如何对数据进行排序。它还涵盖了如何从数据生成图表。

第五章,“更改数据和结构”,涵盖了 phpMyAdmin 中的数据编辑方面。它教会我们如何处理 NULL 值,多行编辑和数据删除。最后,它探讨了更改表结构的主题,重点是编辑列属性(包括新的 ENUM/SET 编辑器)和索引管理。

第六章,“导出结构和数据(备份)”,涉及备份和导出。它列出了触发导出的各种方式、可用的导出格式、与导出格式相关的选项,以及导出文件可能发送的各种位置。

第七章,“导入结构和数据”,告诉我们如何将为备份和传输目的创建的导出数据带回。它涵盖了 phpMyAdmin 中可用的各种导入数据的选项,以及导入 SQL 文件、CSV 文件和其他格式所涉及的不同机制。最后,它涵盖了导入文件可能面临的限制以及克服这些限制的方法。

第八章,“搜索数据”,介绍了对每个表或整个数据库进行有效搜索的机制。

第九章,“执行表和数据库操作”,涵盖了执行影响整个表或整个数据库的一些操作的方法。最后,它涉及表维护操作,如表修复和优化。

第十章,“从关系系统中受益”,是我们开始介绍 phpMyAdmin 高级功能的地方。本章解释了如何定义表间关系以及这些关系如何在浏览表、输入数据或搜索数据时帮助我们。

第十一章,“输入 SQL 语句”,帮助我们输入自己的 SQL 命令。本章还涵盖了查询窗口——用于编辑 SQL 查询的窗口。最后,它还帮助我们获取输入命令的历史记录。

第十二章,“生成多表查询”,涵盖了多表查询生成器,允许我们生成这些查询而不实际输入它们。还介绍了可视化查询构建器。

第十三章,“同步数据和支持复制”,教会我们如何在同一服务器上或从一个服务器到另一个服务器上同步数据库。然后涵盖了如何管理 MySQL 复制。

第十四章,“使用查询书签”,涵盖了 phpMyAdmin 配置存储的一个功能。它展示了如何记录书签以及如何操作它们。最后,它涵盖了向书签传递参数。

第十五章,“系统文档”,概述了如何使用 phpMyAdmin 提供的工具生成解释数据库结构的文档。

第十六章,“使用 MIME 转换数据”,解释了如何在查看时对数据应用转换以自定义其格式。

第十七章,“支持 MySQL 5 中添加的功能”,涵盖了 phpMyAdmin 对 MySQL 5.0 和 5.1 中的新功能的支持,如视图、存储过程和触发器。

第十八章,“跟踪更改”,教会我们如何记录从 phpMyAdmin 界面进行的结构和数据更改。

第十九章,“管理 MySQL 服务器”,讨论了 MySQL 服务器的管理,重点放在用户帐户和权限上。本章讨论了系统管理员如何使用 phpMyAdmin 的服务器管理功能进行日常用户帐户维护、服务器验证和服务器保护。

附录 A,故障排除和支持,解释了如何通过进行简单验证来排除 phpMyAdmin 的故障。它还解释了如何与开发团队互动,以获取支持、错误报告和贡献。

本书所需内容

您需要访问已安装以下内容的服务器或工作站:

  • 具有 PHP 5.2 或更高版本的 Web 服务器

  • MySQL 5.0 或更高版本

本书的受众对象

如果您是开发人员、系统管理员或网页设计师,希望高效管理 MySQL 数据库和表,那么本书适合您。本书假定您已经熟悉 MySQL 基础知识。对于每个希望充分利用这一杰出应用程序的 phpMyAdmin 用户来说,本书都是必读之作。

约定

在本书中,您会发现一些文本样式,用于区分不同类型的信息。以下是一些样式的示例,以及它们的含义解释。

文本中的代码词显示如下:"如果这些信息不可用,一个很好的替代选择是localhost。"

代码块设置如下:

$i++;
$cfg['Servers'][$i]['host'] = '';
$cfg['Servers'][$i]['port'] = '';
$cfg['Servers'][$i]['socket'] = '';

当我们希望引起您对代码块的特定部分的注意时,相关行或项目将以粗体显示:

UPDATE `marc_book`.`book` SET `some_bits` = b '101' 
WHERE `book`.`isbn` = '1-234567-89-0' LIMIT 1;

任何命令行输入或输出都以以下形式书写:

 tar -xzvf phpMyAdmin-3.4.5-all-languages.tar.gz

新术语重要单词以粗体显示。您在屏幕上看到的单词,例如菜单或对话框中的单词,会在文本中以这种方式出现:"在下载部分有各种文件可用。"

注意

警告或重要提示会以这种形式出现在方框中。

提示

技巧和窍门会以这种形式出现。

读者反馈

我们始终欢迎读者的反馈。请告诉我们您对本书的看法——您喜欢或不喜欢的地方。读者的反馈对我们开发能让您真正受益的书籍至关重要。

要向我们发送一般反馈,只需发送电子邮件至<feedback@packtpub.com>,并在消息主题中提及书名。

如果您在某个专题上有专业知识,并且有兴趣撰写或为一本书做出贡献,请参阅我们的作者指南www.packtpub.com/authors

客户支持

现在您是 Packt 书籍的自豪所有者,我们有一些事情可以帮助您充分利用您的购买。

勘误

尽管我们已经尽一切努力确保内容的准确性,但错误是难免的。如果您在我们的书中发现错误——可能是文本或代码中的错误——我们将不胜感激地希望您向我们报告。通过这样做,您可以帮助其他读者避免挫折,并帮助我们改进本书的后续版本。如果您发现任何勘误,请访问www.packtpub.com/support报告,选择您的书,点击勘误提交表链接,并输入您的勘误详情。一旦您的勘误经过验证,您的提交将被接受,并且勘误将被上传到我们的网站上,或者添加到该标题的勘误部分的任何现有勘误列表中。

盗版

互联网上的版权盗版是所有媒体的持续问题。在 Packt,我们非常重视对我们的版权和许可的保护。如果您在互联网上发现我们作品的任何非法副本,请立即向我们提供位置地址或网站名称,以便我们采取补救措施。

请通过<copyright@packtpub.com>与我们联系,并附上涉嫌盗版材料的链接。

我们感谢您帮助我们保护我们的作者和我们提供有价值的内容的能力。

问题

如果您在阅读本书的过程中遇到任何问题,请联系我们<questions@packtpub.com>,我们将尽力解决。

第一章:开始使用 phpMyAdmin

我在这本书中对你表示热烈的欢迎!本章的目标是:

  • 了解这个软件产品在 Web 领域中的位置

  • 了解它的所有功能

  • 熟练安装和配置它

PHP 和 MySQL:领先的开源组合

当我们看当前主机提供商提供的 Web 应用平台时,我们会发现最普遍的是 PHP/MySQL 组合。

得到各自主页的大力支持—www.php.netwww.mysql.com —这对组合使开发人员能够构建许多现成的开源 Web 应用程序,最重要的是,使内部开发人员能够快速建立稳固的 Web 解决方案。

MySQL,大多符合 SQL:2003 标准,是一个以其速度、稳健性和小的连接开销而闻名的数据库系统。在 Web 环境中,页面必须尽快提供的情况下,这一点非常重要。

PHP 通常安装在 Web 服务器内部作为一个模块,是一种流行的脚本语言,用于编写与 MySQL(或其他数据库系统)后端和浏览器前端通信的应用程序。具有讽刺意味的是,这个首字母缩略词的意义随着 Web 的发展而演变,从个人主页专业主页再到其当前的递归定义——PHP:超文本预处理器。有关连续名称更改的博客文章可在blog.roshambo.org/how-the-php-acronym-was-reborn上找到。PHP 可以在数百万个 Web 域上使用,并为 Facebook、Yahoo!、YouTube 和 Wikipedia 等知名网站提供动力。

什么是 phpMyAdmin?

phpMyAdmin(官方主页在www.phpmyadmin.net)是一个用 PHP 编写的 Web 应用程序;它包含(像大多数 Web 应用程序一样)XHTML、CSS 和 JavaScript 客户端代码。该应用程序为管理 MySQL 数据库提供了完整的 Web 界面,并被广泛认为是该领域的领先应用程序。

自诞生以来就是开源的,得到了全球众多开发人员和翻译人员的支持(在撰写本书时已被翻译成 65 种语言)。该项目目前托管在 SourceForge.net 上,并由 phpMyAdmin 团队利用他们的设施进行开发。

全球各地的主机提供商都通过在他们的服务器上安装 phpMyAdmin 来表现对其的信任。流行的 cPanel(一个网站控制应用程序)包含 phpMyAdmin。此外,只要我们的提供商服务器满足最低要求(请参阅本章后面的系统要求部分),我们就可以在我们自己的 Web 服务器上安装我们自己的 phpMyAdmin 副本。

phpMyAdmin 的目标是提供对 MySQL 服务器和数据的完整基于 Web 的管理,并跟上 MySQL 和 Web 标准的发展。虽然产品不断发展,但它支持所有标准操作以及额外的功能。

开发团队根据报告的错误和请求的功能不断调整产品,定期发布新版本。

phpMyAdmin 提供了涵盖基本 MySQL 数据库和表操作的功能。它还有一个内部系统,用于维护元数据以支持高级功能。最后,系统管理员可以从 phpMyAdmin 管理用户和权限。重要的是要注意,phpMyAdmin 选择的可用操作取决于用户在特定 MySQL 服务器上的权限。

项目文档

有关 phpMyAdmin 的更多信息,请参阅主页文档页面,位于www.phpmyadmin.net/home_page/docs.php。此外,开发团队在社区的帮助下维护着一个维基,位于wiki.phpmyadmin.net

安装 phpMyAdmin

是时候安装产品并进行最少的首次使用配置了。

我们安装 phpMyAdmin 的原因可能是以下之一:

  • 我们的主机提供商没有安装中央副本

  • 我们的提供商安装了它,但安装的版本不是最新的

  • 我们直接在企业的 Web 服务器上工作

请注意,如果我们选择安装通常包括 phpMyAdmin 作为其产品的一部分的 AMP 产品之一,我们可以省去 phpMyAdmin 安装步骤。更多详细信息请参见en.wikipedia.org/wiki/List_of_AMP_packages

所需信息

一些主机提供商提供了集成的 Web 面板,我们可以在其中管理帐户,包括 MySQL 帐户,还有一个文件管理器,可以用来上传 Web 内容。根据这一点,我们用于将 phpMyAdmin 源文件传输到我们的 Web 空间的机制可能会有所不同。在开始安装之前,我们需要一些以下特定信息:

  • Web 服务器的名称或地址。在这里,我们假设它是www.mydomain.com

  • 我们的网页服务器帐户信息(用户名,密码)。此信息将用于 FTP 或 SFTP 传输,SSH 登录或 Web 控制面板登录。

  • MySQL 服务器的名称或 IP 地址。如果没有这些信息,一个很好的备选选择是localhost,这意味着 MySQL 服务器位于与 Web 服务器相同的机器上。我们假设这是localhost

  • 我们的 MySQL 服务器帐户信息(用户名,密码)。

系统要求

特定 phpMyAdmin 版本的最新要求始终在附带的Documentation.html中说明。对于 phpMyAdmin 3.4,所需的最低 PHP 版本是带有session支持的 PHP 5.2,标准 PHP 库(SPL)JSON支持。此外,Web 服务器必须能够访问 MySQL 服务器(5.0 版本或更高版本)-可以是本地的,也可以是远程的。强烈建议在 cookie 身份验证模式下提高性能时,Web 服务器必须具有PHP mcrypt扩展(有关此内容,请参见第二章)。实际上,在 64 位服务器上,这个扩展是必需的。

在浏览器端,无论我们使用哪种身份验证模式,都必须激活 cookie 支持。

下载文件

www.phpmyadmin.net下载部分提供了各种文件。这里可能提供了多个版本,最好下载最新的稳定版本。我们只需要下载一个文件,无论平台(浏览器,Web 服务器,MySQL 或 PHP 版本)如何,都可以使用。对于 3.4 版本,有两组文件-englishall-languages。如果我们只需要英文界面,可以下载文件名包含english的文件,例如phpMyAdmin-3.4.5-english.zip。另一方面,如果我们需要至少另一种语言,选择all-languages是合适的。

如果我们使用的是仅支持 PHP 4 的服务器-自 2007 年 12 月 31 日 PHP 团队停止支持以来,最新的稳定版本的 phpMyAdmin 不是一个好选择。我们可以使用 2.11.x 版本,这是支持 PHP 4 的最新分支,尽管 phpMyAdmin 团队也停止支持这个版本。

提供的文件具有各种扩展名:.zip,.tar.bz2,.tar.gz,.tar.xz 和.7z。下载具有您具有相应提取器的扩展名的文件。在 Windows 世界中,.zip是最通用的文件格式,尽管它比.gz.bz2(在 Linux/Unix 世界中常见)要大。.7z扩展名表示 7-Zip 文件,这是一种比其他提供的格式具有更高压缩比的格式;提取器可在www.7-zip.org上找到。在以下示例中,我们将假定所选文件是phpMyAdmin-3.4.5-all-languages.zip

单击适当的文件后,SourceForge.net 会选择最近的镜像站点。文件将开始下载,我们可以将其保存在我们的计算机上。

在不同平台上安装

下一步取决于您使用的平台。以下各节详细介绍了一些常见平台的程序。您可以直接转到相关部分。

在 Windows 客户端上安装到远程服务器

使用 Windows 资源管理器,在 Windows 客户端上双击刚刚下载的phpMyAdmin-3.4.5-all-languages.zip文件。文件提取器应该会启动,显示主目录phpMyAdmin-3.4.5-all-languages中的所有脚本和目录。

使用文件提取器提供的任何机制将所有文件(包括子目录)保存到工作站上的某个位置。在这里,我们选择了C:\。因此,提取器创建了一个C:\phpMyAdmin-3.4.5-all-languages目录。

现在,是时候将整个目录结构C:\phpMyAdmin-3.4.5-all-languages传输到我们网页空间中的 Web 服务器了。我们可以使用我们喜欢的 SFTP 或 FTP 软件,或者使用 Web 控制面板进行传输。

我们传输 phpMyAdmin 的确切目录可能会有所不同。它可以是我们的public_html目录或我们通常传输 Web 文档的其他目录。有关要使用的确切目录或传输目录结构的最佳方法的进一步说明,我们可以咨询我们的主机提供商的帮助台。

传输完成后,这些文件可以从我们的 Windows 机器上删除,因为它们不再需要了。

在本地 Linux 服务器上安装

假设我们选择了phpMyAdmin-3.4.5-all-languages.tar.gz并直接下载到 Linux 服务器上的某个目录。我们将其移动到我们的 Web 服务器文档根目录(例如/var/www/html)或其子目录之一(例如/var/www/html/utilities)。然后,我们使用以下 shell 命令或使用窗口管理器提供的任何图形文件提取器进行提取:

tar -xzvf phpMyAdmin-3.4.5-all-languages.tar.gz 

我们必须确保目录和文件的权限和所有权适合我们的 Web 服务器。Web 服务器用户或组必须能够读取它们。

在本地 Windows 服务器(Apache,IIS)上安装

这里的步骤与“在 Windows 客户端上安装到远程服务器”部分中描述的类似,只是目标目录将位于我们的DocumentRoot(对于 Apache)或我们的wwwroot(对于 IIS)下。当然,在对config.inc.php进行修改后,我们不需要传输任何内容(在下一节中描述),因为目录已经在 Web 空间中。

Apache 通常作为服务运行。因此,我们必须确保运行服务的用户具有正常的读取权限,以访问我们新创建的目录。相同的原则适用于使用IUSR_machinename用户的 IIS。该用户必须对目录具有读取权限。您可以在目录属性的安全/权限选项卡中调整权限。

配置 phpMyAdmin

在这里,我们学习如何准备和使用包含连接到 MySQL 的参数的配置文件,并且可以根据我们的要求进行自定义。

在配置之前,我们可以将目录phpMyAdmin-3.4.5-all-languages重命名为phpMyAdmin或其他更容易记住的名称。这样,我们和我们的用户可以访问一个容易记住的 URL 来启动 phpMyAdmin。在大多数服务器上,URL 的目录部分是区分大小写的,因此我们应该向用户传达确切的 URL。如果我们的服务器支持此功能,我们还可以使用符号链接。

在以下示例中,我们将假设该目录已重命名为phpMyAdmin

config.inc.php 文件

这个文件包含有效的 PHP 代码,定义了大部分参数(由 PHP 变量表示),我们可以更改以调整 phpMyAdmin 以满足我们自己的需求。文件中还有普通的 PHP 注释,我们可以注释我们的更改。

提示

注意不要在文件开头或结尾添加任何空行;这会妨碍 phpMyAdmin 的执行。

请注意,phpMyAdmin 在第一级目录中寻找此文件——与index.php位于同一目录。

包含一个config.sample.inc.php文件,可以复制并重命名为config.inc.php,作为起点。然而,建议您使用基于 Web 的安装脚本(在本章中解释)来代替,以获得更舒适的配置界面。

还有另一个文件——layout.inc.php——包含一些配置信息。由于 phpMyAdmin 提供主题管理,这个文件包含特定主题的颜色和设置。每个主题都有一个layout.inc.php文件,位于themes/<themename>,例如themes/pmahomme。我们将在第四章中介绍修改其中一些参数。

避免关于 config.inc.php 权限的虚假错误消息

在正常情况下,phpMyAdmin 会验证此文件的权限是否允许任何人修改。这意味着该文件不应该被世界写入。如果权限不正确,它还会显示警告。然而,在某些情况下(例如在非 Windows 服务器上挂载的 NTFS 文件系统),权限检测会失败。在这些情况下,您应该将以下配置参数设置为false:

$cfg['CheckConfigurationPermissions'] = false;

以下各节将解释在config.inc.php中添加或更改参数的各种方法。

配置原则

phpMyAdmin 不维护自己的用户帐户;相反,它使用 MySQL 的权限系统。

注意

现在可能是浏览dev.mysql.com/doc/refman/5.1/en/privilege-system.html的时候了,了解 MySQL 权限系统的基础知识。

由于缺少配置文件,phpMyAdmin 默认显示基于 cookie 的登录面板(有关此内容的更多详细信息,请参阅第二章),其中解释了默认配置下,无法使用空密码登录:

配置原则

我们可以通过打开浏览器并访问http://www.mydomain.com/phpMyAdmin来验证这一事实,并替换域部分和目录部分的正确值。

如果我们能够登录,这意味着在与 Web 服务器相同的主机上有一个运行中的 MySQL 服务器(localhost),我们刚刚连接到它。然而,没有创建配置文件意味着我们将无法通过我们的 phpMyAdmin 安装管理其他主机。此外,许多高级的 phpMyAdmin 功能(例如查询书签、完整的关系支持、列转换等)将无法激活。

注意

基于 cookie 的身份验证方法使用 Blowfish 加密来存储浏览器 cookie 中的凭据。当没有配置文件存在时,会生成并存储一个 Blowfish 秘钥在会话数据中,这可能会导致安全问题。这就是为什么会显示以下警告消息的原因:

配置文件现在需要一个秘密的密码(blowfish_secret)

此时,我们有以下选择:

  • 在没有配置文件的情况下使用 phpMyAdmin

  • 使用基于 Web 的设置脚本生成config.inc.php文件

  • 手动创建config.inc.php文件

这两个后续选项在以下部分中介绍。我们应该注意,即使使用基于 Web 的设置脚本,我们也应该熟悉config.inc.php文件的格式,因为设置脚本并没有涵盖所有可能的配置选项。

基于 Web 的设置脚本

强烈建议使用基于 Web 的设置机制,以避免手动创建配置文件可能导致的语法错误。此外,由于这个文件必须遵守 PHP 的语法,新用户在安装过程中可能会遇到问题。

注意

这里需要注意一点:当前版本的设置界面只有有限数量的翻译语言。

要访问设置脚本,我们必须访问www.mydomain.com/phpMyAdmin/setup。在初始执行时,会出现以下截图:

基于 Web 的设置脚本

在大多数情况下,每个参数旁边的图标指向相应的 phpMyAdmin 官方维基和文档,为您提供有关此参数及其可能值的更多信息。

如果出现显示隐藏消息并点击此链接,之前可能显示的消息将被显示出来。

这里有三个警告。由于处理第一条消息需要更多操作,我们稍后再处理。第二个警告鼓励您使用ForceSSL选项,在使用 phpMyAdmin 时自动切换到 HTTPS(与设置阶段无关)。

让我们来看看第三条消息——不安全的连接。如果我们通过不安全的协议 HTTP 访问 Web 服务器,就会出现这个消息。由于我们可能会在设置阶段输入机密信息,比如用户名和密码,建议至少在这个阶段使用 HTTPS 进行通信。HTTPS 使用 SSL(安全套接字层)来加密通信,使窃听线路变得不可能。如果我们的 Web 服务器支持 HTTPS,我们可以简单地按照建议的链接进行操作。这将重新启动设置过程,这次是通过 HTTPS 进行的。

第一个警告告诉我们,phpMyAdmin 没有找到一个名为config的可写目录。这是正常的,因为在下载的套件中没有这个目录。此外,由于目录还不存在,我们注意到界面中的保存、加载删除按钮是灰色的。在这个config目录中,我们可以:

  • 在设置过程中保存工作版本的配置文件

  • 加载之前准备好的config.inc.php文件

我们并不一定需要创建这个配置目录,因为我们可以将设置过程生成的config.inc.php文件下载到客户端机器上。然后,我们可以通过与上传 phpMyAdmin 相同的机制(比如 FTP)将其上传到 phpMyAdmin 的一级目录中。在这个练习中,我们将创建这个目录。

这里的原则是 Web 服务器必须能够写入这个目录。有多种方法可以实现这一点。以下是在 Linux 服务器上可以使用的一种方法——在这个目录上为每个人添加读、写和执行权限。

cd phpMyAdmin
mkdir config
chmod 777 config 

完成这些操作后,我们在浏览器中刷新页面,会看到一个类似以下截图的屏幕:

基于 Web 的设置脚本

在配置对话框中,下拉菜单允许用户选择适当的行尾格式。我们应该选择与我们将在后来使用文本编辑器打开config.inc.php文件的平台(UNIX/Linux 或 Windows)相对应的格式。

一个 phpMyAdmin 的副本可以用来管理许多 MySQL 服务器,但是现在我们将定义描述我们的第一个 MySQL 服务器的参数。我们单击新服务器,然后显示服务器配置面板。

这些参数的完整解释可以在本章的以下部分找到。现在,我们注意到设置过程已检测到 PHP 支持mysqli扩展。因此,默认选择此扩展。此扩展是 PHP 用于与 MySQL 通信的编程库。

我们假设我们的 MySQL 服务器位于localhost上。因此,我们保持此值和所有建议的值不变,除了以下内容:

  • 基本设置 | 该服务器的详细名称 —我们输入 我的服务器

  • 认证 | 用于配置认证的用户 —我们删除root并将其留空,因为默认的认证类型是cookie,它会忽略在此输入的用户名

您可以看到任何更改为其默认值的参数都以不同的颜色显示。此外,会出现一个小箭头,其目的是将字段恢复为其默认值。因此,您可以放心地尝试更改参数,知道您可以轻松恢复到建议的值。此时,基本设置面板应该类似于以下屏幕截图:

基于 Web 的设置脚本

然后我们单击保存,并返回到概述面板。此保存操作尚未将任何内容保存到磁盘;更改已保存在内存中。我们收到警告,生成了一个 Blowfish 秘钥。但是,我们不必记住它,因为在登录过程中不需要输入它,而是在内部使用。对于好奇的人,您可以切换到功能面板,然后单击安全选项卡,以查看生成的秘钥。让我们回到概述面板。现在,我们的设置过程已知道一个 MySQL 服务器,并且有一些链接,使我们能够像下面的屏幕截图中显示的那样编辑删除这些服务器设置:

基于 Web 的设置脚本

我们可以使用显示按钮查看生成的配置行;然后,我们可以使用本章后面的一些配置参数的描述部分中给出的解释来分析这些参数。

此时,此配置仍仅存储在内存中,因此我们需要保存它。这是通过概述面板上的保存按钮完成的。它将config.inc.php保存在我们之前创建的特殊config目录中。这是一个严格用于配置目的的目录。如果由于任何原因无法创建此config目录,您只需通过单击下载按钮将文件下载并上传到安装了 phpMyAdmin 的 Web 服务器目录。

最后一步是将config.inc.phpconfig目录复制到顶级目录 —— 包含index.php的目录。通过复制此文件,它将由用户拥有,而不是由 Web 服务器拥有,从而确保可以进行进一步的修改。可以通过 FTP 或通过以下命令进行此复制:

cd config
cp config.inc.php .. 

作为安全措施,直到配置步骤完成之前,建议更改config目录的权限,例如使用以下命令:

chmod ugo-rwx config 

这是为了阻止在此目录中进行任何未经授权的读写操作。

其他配置参数可以使用这些基于 Web 的设置页面进行设置。要这样做,我们需要:

  1. 启用对config目录的读写访问权限。

  2. config.inc.php复制到那里。

  3. 确保为 Web 服务器提供了对该文件的读写访问权限。

  4. 启动基于 Web 的设置工具。

配置步骤完成后,建议完全删除config目录,因为这个目录只被基于 Web 的安装脚本使用。如果 phpMyAdmin 检测到这个目录仍然存在,它会在主页上显示以下警告(参见第三章):

目录 config,被安装脚本使用,仍然存在于您的 phpMyAdmin 目录中。一旦 phpMyAdmin 配置完成,您应该删除它

您可以浏览剩余的菜单,了解可用的配置可能性,无论是现在还是在我们涵盖相关主题时。

为了使本书的文本更轻,我们将在接下来的章节中只提到参数的文本值。

手动创建 config.inc.php

我们可以使用我们喜欢的文本编辑器从头开始创建这个文本文件,或者使用config.sample.inc.php作为起点。确切的步骤取决于我们使用的客户端操作系统。我们可以参考下一节获取更多信息。

所有可能的配置参数的默认值都在libraries/config.default.php中定义。我们可以查看此文件,了解使用的语法以及有关配置的进一步注释。请参见本章升级 phpMyAdmin部分中关于此文件的重要说明。

在 Windows 客户端上编辑 config.inc.php 的提示

这个文件包含特殊字符(Unix 风格的行尾)。因此,我们必须使用理解这种格式的文本编辑器打开它。如果我们使用错误的文本编辑器,这个文件将显示非常长的行。最好的选择是标准的 PHP 编辑器,如 NetBeans 或 Zend Studio for Eclipse。另一个选择是 WordPad,Metapad 或 UltraEdit。

每次修改config.inc.php文件,都必须再次将其传输到我们的网络空间。这种传输是通过 FTP 或 SFTP 客户端完成的。您可以选择使用独立的 FTP/SFTP 客户端,如 FileZilla,或者如果您的 PHP 编辑器支持此功能,也可以直接通过 FTP/SFTP 保存。

一些配置参数的描述

在本章和下一章中,我们将集中讨论与连接和身份验证相关的参数。其他参数将在解释相应功能的章节中讨论。

PmaAbsoluteUri

我们将首先查看的参数是$cfg['PmaAbsoluteUri'] = '';

有时,phpMyAdmin 需要发送 HTTP Location头,并且必须知道其安装点的绝对 URI。在这种情况下,使用绝对 URI 是 RFC 2616 第 14.30 节要求的。

在大多数情况下,我们可以将此项留空,因为 phpMyAdmin 会尝试自动检测正确的值。如果我们稍后浏览表,然后编辑一行,并单击保存,我们将收到来自浏览器的错误消息,例如此文档不存在。这意味着 phpMyAdmin 为了到达预期页面而构建的绝对 URI 是错误的,表明我们必须手动在此参数中放入正确的值。

例如,我们会将其更改为:

$cfg['PmaAbsoluteUri'] = 'http://www.mydomain.com/phpMyAdmin/';

特定于服务器的部分

文件的下一部分包含特定于服务器的配置,每个配置都以以下代码片段开头:

$i++;
$cfg['Servers'][$i]['host'] = '';

如果我们只检查正常的服务器参数(其他参数在本章的安装 phpMyAdmin 配置存储部分中有介绍),我们会看到每个服务器的以下代码块:

$i++;
$cfg['Servers'][$i]['host'] = '';
$cfg['Servers'][$i]['port'] = '';
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['compress'] = FALSE;
$cfg['Servers'][$i]['controluser'] = '';
$cfg['Servers'][$i]['controlpass'] = '';
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['user'] = '';
$cfg['Servers'][$i]['password'] = '';
$cfg['Servers'][$i]['only_db'] = '';
$cfg['Servers'][$i]['hide_db'] = '';
$cfg['Servers'][$i]['verbose'] = '';

在这一部分,我们必须输入$cfg['Servers'][$i]['host'],MySQL 服务器的主机名或 IP 地址,例如,mysql.mydomain.comlocalhost。如果此服务器在非标准端口或套接字上运行,我们在$cfg['Servers'][$i]['port']$cfg['Servers'][$i]['socket']中填入正确的值。有关套接字的更多详细信息,请参见connect_type, sockets, and port部分。

在 phpMyAdmin 界面中显示的服务器名称将是'host'中输入的名称,除非我们在以下参数中输入非空值,例如:

$cfg['Servers'][$i]['verbose'] = 'Test server';

因此,这个功能可以用来在登录面板和主页面上显示用户所看到的不同服务器主机名,尽管真实的服务器名称可以作为用户定义的一部分(例如,在主页面上是root@localhost)。

扩展

PHP 与 MySQL 服务器通信的传统机制,在 PHP 5 之前可用的是mysql扩展。这个扩展在 PHP 5 中仍然可用。然而,一个名为mysqli的新扩展已经开发出来,并且应该在 PHP 5 中优先使用,因为它具有改进的性能并支持 MySQL 4.1.x 系列的全部功能。这个扩展被设计用于与 MySQL 版本 4.1.3 及更高版本一起使用。由于 phpMyAdmin 支持这两个扩展,我们可以为特定服务器选择其中一个。我们在$cfg['Servers'][$i]['extension']中指定我们想要使用的扩展。默认使用的值是mysqli

connect_type、socket 和 port

mysqlmysqli扩展在连接到localhost上的 MySQL 时会自动使用套接字。考虑以下配置:

$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['port'] = '';
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysql';

connect_type的默认值是tcp。然而,扩展将使用套接字,因为它认为这样更有效率,因为hostlocalhost。所以在这种情况下,我们可以使用tcpsocket作为connect_type。要强制使用真正的 TCP 连接,可以在host参数中指定127.0.0.1而不是localhost。因为socket参数为空,扩展将尝试使用默认套接字。如果php.ini中定义的默认套接字与分配给 MySQL 服务器的真实套接字不对应,我们必须在$cfg['Servers'][$i]['socket']中放置套接字名称(例如/tmp/mysql.sock)。

如果主机名不是localhost,将发生 TCP 连接;在这种情况下,使用特殊端口3307。然而,将端口值留空将使用默认的3306端口:

$cfg['Servers'][$i]['host'] = 'mysql.mydomain.com';
$cfg['Servers'][$i]['port'] = '3307';
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysql';

压缩

PHP 与 MySQL 之间通信所使用的协议允许压缩模式。使用此模式可以提高效率。要利用此模式,只需指定:

$cfg['Servers'][$i]['compress'] = TRUE;

持久连接

另一个重要的参数(不是特定于服务器的,但适用于所有服务器定义)是$cfg['PersistentConnections']。对于使用mysql扩展连接的每个服务器,当设置为TRUE时,此参数指示 PHP 保持与 MySQL 服务器的连接打开。这加快了 PHP 与 MySQL 之间的交互。然而,在config.inc.php中默认设置为FALSE,因为持久连接经常是服务器资源耗尽的原因(您会发现 MySQL 拒绝新连接)。因此,对于mysqli扩展,甚至不提供此选项。因此,如果您使用此扩展进行连接,则在这里将其设置为TRUE将不起作用。

控制用户

定义控制用户有以下两个目的:

  • 在运行--skip-show-database的 MySQL 服务器上,控制用户允许使用多用户身份验证,尽管使用此选项运行的服务器并不常见。这一方面在第二章中有描述。

  • 在所有版本的 MySQL 服务器上,这个用户是必需的,才能使用 phpMyAdmin 的高级功能。

为了认证目的,controluser是一个特殊用户(我们选择的通常名称是pma),他有权读取mysql数据库中的一些字段(其中包含所有用户定义)。phpMyAdmin 仅为认证的特定需求发送带有这个特殊controluser的查询,而不是正常操作。创建控制用户的命令可以在 phpMyAdmin 的Documentation.html中找到,并且可能会因版本而异。这份文档包含了最新的命令。

当我们在 MySQL 服务器中创建controluser时,我们填写参数如下示例中的内容,将xxx替换为一个适当复杂的密码:

$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'xxx';

这里适用标准密码指南。请参考en.wikipedia.org/wiki/Password_strength获取建议。

安装 phpMyAdmin 配置存储

除了基本的 MySQL 数据库维护外,phpMyAdmin 还提供了高级功能,我们将在接下来的章节中发现。这些功能需要安装 phpMyAdmin 配置存储。

配置存储的目标

配置存储由 phpMyAdmin 在幕后使用的一组表组成。它们保存元数据,其中包含支持特殊功能的信息,例如查询书签和数据转换。此外,对于使用不支持外键的存储引擎的表,表之间的关系保存在这个配置存储中。元数据是根据我们在界面上的操作由 phpMyAdmin 生成和维护的。

配置存储的位置

有两个可能的地方来存储这些表:

  • 用户的数据库-以方便每个网页开发人员拥有一个数据库以从这些功能中受益。

  • 一个名为 pmadb(phpMyAdmin 数据库)的专用数据库。在多用户安装中,这个数据库可能对许多用户可见,同时保持元数据私有。

由于这个存储默认情况下不存在,并且 phpMyAdmin 团队希望推广它,界面在主页上显示以下通知消息:

配置存储的位置

这条消息可以通过以下参数禁用(默认情况下设置为FALSE):

$cfg['PmaNoRelation_DisableWarning'] = TRUE;

执行安装

即使只有部分配置存储缺失,先前的错误消息也会显示。当然,在新安装中,所有部分都缺失-我们的数据库还没有听说过 phpMyAdmin,并且需要配备这个配置存储。在前一个截图中点击“here”链接会弹出一个面板,解释pmadb以及应该是其中一部分的表要么缺失要么未定义。

重要的是要意识到,只有满足以下两个条件,配置存储才能正常运行:

  • config.inc.php中存在适当的定义

  • 相应的表(也许是数据库)被创建

为了创建与我们当前版本的 phpMyAdmin 匹配的必要结构,phpMyAdmin 安装目录的scripts子目录中提供了一个名为create_tables.sql的命令文件。但是,在了解可能的选择-单用户安装或多用户安装之前,我们不应该盲目执行它。

注意

在后续章节中,我们将假设选择了多用户安装。

为单个用户安装

即使我们只有一个数据库的权限,我们仍然可以使用 phpMyAdmin 的所有高级功能。在这种设置中,我们将使用我们现有的数据库来存储元数据表。

我们需要修改scripts/create_tables.sql文件的本地副本,以便用所需的所有表填充我们的数据库。它们将具有前缀pma_以便于识别。我们需要删除以下行:

CREATE DATABASE IF NOT EXISTS `phpmyadmin`
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
USE phpmyadmin;

这样做是因为我们不会使用phpmyadmin数据库,而是我们自己的。接下来,我们应该在 phpMyAdmin 中打开我们自己的数据库。现在我们准备执行脚本了。有两种方法可以做到这一点:

  • 由于我们已经在编辑器中有脚本,我们可以只需复制这些行并粘贴到SQL页面的查询框中。更多细节请参阅第十一章。

  • 另一种方法是使用第七章中展示的导入技术。我们选择刚刚修改的create_tables.sql脚本。

创建后,导航面板会显示特殊的pma_表和我们的普通表。

现在是时候调整config.inc.php中所有与配置存储相关的参数了。这可以通过本章中的设置脚本轻松完成,也可以通过从config.sample.inc.php文件中粘贴适当的行来完成。数据库是我们自己的,表名是刚刚创建的表名:

$cfg['Servers'][$i]['pmadb'] = 'mydatabase';
$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
$cfg['Servers'][$i]['relation'] = 'pma_relation';
$cfg['Servers'][$i]['table_info'] = 'pma_table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma_column_info';
$cfg['Servers'][$i]['history'] = 'pma_history';
$cfg['Servers'][$i]['tracking'] = 'pma_tracking';
$cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
$cfg['Servers'][$i]['userconfig'] = 'pma_userconfig';

注意

由于表名区分大小写,我们必须使用与安装脚本创建的表相同的名称。我们可以自由更改表名(参见列出的配置指令的右侧部分),只要我们相应地在数据库中进行更改。

pmadb和每个表都有一个特定的功能,如下所列:

功能 描述 解释
pmadb 定义所有表所在的数据库 本章
bookmarktable 包含查询书签 第十四章
relation 定义表间关系,用于 phpMyAdmin 的许多功能 第十章
table_info 包含显示字段 第十章
table_coordspdf_pages 包含绘制 PDF 格式关系图所需的元数据 第十五章
column_info 用于列注释和基于 MIME 的转换 第十六章
history 包含 SQL 查询历史信息 第十一章
tracking 包含与被跟踪表相关的元数据和实际的 SQL 语句 第十八章
designer_coords 保存Designer功能使用的坐标 第十章
userconfig 保存用户的偏好设置 第三章

在每个 phpMyAdmin 版本之间,基础设施可能会得到增强——这些变化在Documentation.html中有解释。这就是为什么 phpMyAdmin 有各种检查来确定表的结构。如果我们知道我们使用的是最新结构,可以将$cfg['Servers'][$i]['verbose_check']设置为FALSE以避免检查,从而稍微提高 phpMyAdmin 的速度。

为多个用户安装

在这个设置中,我们将有一个独立的数据库pmadb来存储元数据表。我们的控制用户将有特定的权限访问这个数据库。每个用户将使用自己的登录名和密码来访问自己的数据库。然而,当 phpMyAdmin 本身访问pmadb以获取一些元数据时,它将使用控制用户的权限。

注意

设置多用户安装只有 MySQL 系统管理员才能做,他有权限给另一个用户(这里是pma用户)分配权限。

我们首先确保控制用户pma已经创建,并且在config.inc.php中的定义是合适的。然后我们将scripts/create_tables.sql复制到我们的本地工作站并进行编辑。我们替换以下行:

-- GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO
-- 'pma'@localhost;

使用这些,删除注释字符(双破折号):

GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO
'pma'@localhost;

然后通过导入执行此脚本(参见[第七章)](ch07.html "第七章。导入结构和数据")。其净效果是创建phpmyadmin数据库,为用户pma分配适当的权限,并用所有必要的表填充数据库。

最后一步是调整config.inc.php中与关系特性相关的所有参数。请参阅为单个用户安装部分,除了pmadb参数中的数据库名称,该名称将如下代码片段所示:

$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';

安装现在已经完成。我们将在接下来的章节中测试功能。我们可以通过退出 phpMyAdmin,然后登录并显示主页来进行快速检查;警告消息应该消失。

升级 phpMyAdmin

通常,升级只是将新版本安装到一个单独的目录,并将先前版本的config.inc.php复制到新目录。

注意

升级路径或首次安装路径,不应采用的方法是将libraries/config.default.php复制到config.inc.php。这是因为默认配置文件是特定版本的,并不能保证适用于将来的版本。

从版本到版本会出现新参数。它们在Documentation.html中有文档记录,并在libraries/config.default.php中定义。如果配置参数在config.inc.php中不存在,则将使用libraries/config.default.php中的值。因此,如果默认值适合我们,我们就不必在config.inc.php中包含它。

必须特别注意传播我们可能对layout.inc.php文件所做的更改,这取决于所使用的主题。如果我们向结构中添加了自定义主题,我们将不得不复制我们的自定义主题子目录。

总结

本章介绍了 PHP/MySQL 在 Web 应用程序中的流行程度。该章还概述了为什么 phpMyAdmin 被认为是从 Web 界面访问 MySQL 的领先应用程序。然后讨论了安装 phpMyAdmin 的常见原因,从主要网站下载它的步骤,基本配置,将 phpMyAdmin 上传到我们的 Web 服务器以及升级。

基本安装已完成,下一章将深入探讨配置主题,探索认证和安全方面。

第二章:配置身份验证和安全

在 phpMyAdmin 中配置身份验证有许多种方式 - 取决于我们的目标、其他应用程序的存在以及我们需要的安全级别。本章探讨了可用的可能性。

通过 phpMyAdmin 登录 MySQL

当我们输入用户名和密码时,尽管看起来我们是在登录 phpMyAdmin,但实际上我们并没有!我们只是使用 phpMyAdmin(运行在 web 服务器上)作为一个界面,将我们的用户名和密码信息发送到 MySQL 服务器。严格来说,我们并没有登录phpMyAdmin,而是通过phpMyAdmin。

注意

这就是为什么在关于 phpMyAdmin 的用户支持论坛中,询问身份验证帮助的人经常被引荐回他们的 MySQL 服务器管理员,因为丢失的 MySQL 用户名或密码不是 phpMyAdmin 的问题。

本节解释了 phpMyAdmin 提供的各种身份验证模式。

在没有密码的情况下登录账户

MySQL 的默认安装会使服务器容易受到入侵,因为它创建了一个名为root的 MySQL 账户,而不设置密码 - 除非 MySQL 分发商已经设置了密码。对于这种安全性弱点的推荐解决方法是为root账户设置密码。如果我们无法设置密码或不想设置密码,我们将不得不对 phpMyAdmin 进行配置更改。事实上,存在一个特定于服务器的配置参数,$cfg['Servers'][$i]['AllowNoPassword']。它的默认值是false,这意味着不允许没有密码的账户登录。通常,这个指令应该保持为false,以避免通过 phpMyAdmin 进行这种访问,因为黑客正在积极地探测 web 上的不安全的 MySQL 服务器。查看保护 phpMyAdmin部分,了解有关保护服务器的其他想法。

注意

如果AllowNoPassword参数保持为false,并且尝试登录而没有密码,则会显示拒绝访问消息。

使用config身份验证对单个用户进行身份验证

我们可能需要通过固定的用户名和密码自动连接到 MySQL 服务器,而无需甚至被要求。这就是config身份验证类型的确切目标。

对于我们的第一个示例,我们将使用config身份验证。然而,在身份验证多个用户部分,我们将看到更强大和多功能的身份验证方式。

注意

使用config身份验证类型会使我们的 phpMyAdmin 容易受到入侵,除非我们像本章的保护 phpMyAdmin部分所解释的那样保护它。

在这里,我们要求config身份验证,并为这个 MySQL 服务器输入我们的用户名和密码:

$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'marc';
$cfg['Servers'][$i]['password'] = 'xxx';

然后我们可以保存我们在config.inc.php中所做的更改。

测试 MySQL 连接

现在是时候启动 phpMyAdmin 并尝试使用我们配置的值连接到它。这将测试以下内容:

  • 我们在config文件或基于 web 的设置中输入的值

  • PHP 组件在 web 服务器内的设置,如果我们进行了手动配置

  • web 和 MySQL 服务器之间的通信

我们启动浏览器,并将其指向我们安装 phpMyAdmin 的目录,如www.mydomain.com/phpMyAdmin/。如果这不起作用,我们尝试www.mydomain.com/phpMyAdmin/index.php。(这意味着我们的 web 服务器没有配置为将index.php解释为默认的起始文档。)

如果仍然出现错误,请参考附录 A 进行故障排除和支持。现在我们应该看到 phpMyAdmin 的主页。第三章概述了现在看到的面板。

身份验证多个用户

我们可能希望允许一份 phpMyAdmin 副本被一组人使用,每个人都有自己的 MySQL 用户名和密码,并且只能看到他们有权限的数据库。或者我们可能更喜欢避免在config.inc.php中以明文形式存储我们的用户名和密码。

phpMyAdmin 不再依赖于config.inc.php中存储的用户名和密码,而是与浏览器通信,并从中获取认证数据。这使得所有在特定 MySQL 服务器中定义的用户都可以进行真正的登录,而无需在配置文件中定义它们。有三种模式可以允许通过 phpMyAdmin 对 MySQL 进行受控登录——http,cookiesignon。我们将不得不选择适合我们特定情况和环境的模式(稍后会详细介绍)。httpcookie模式可能需要我们首先定义一个控制用户,如第一章中所述。

使用 HTTP 进行身份验证

这种模式—http—是 HTTP 中提供的传统模式,其中浏览器请求用户名和密码,将它们发送到 phpMyAdmin,并一直发送直到所有浏览器窗口关闭。

要启用这种模式,我们只需使用以下行:

$cfg['Servers'][$i]['auth_type'] = 'http';

我们还可以通过$cfg['Servers'][$i]['auth_http_realm']定义 HTTP 的基本认证领域en.wikipedia.org/wiki/Basic_access_authentication),这是在登录时向用户显示的消息,这可以帮助指示此服务器的目的。

这种模式有以下限制:

  • 根据版本不同,PHP 可能不支持所有类型的 Web 服务器的 HTTP 身份验证。

  • 如果我们想要用.htaccess文件保护 phpMyAdmin 的目录(参考本章的Securing phpMyAdmin部分),这将干扰 HTTP 身份验证类型;我们不能同时使用两者。

  • 浏览器通常会存储认证信息以节省重新输入凭据的时间,但请记住这些凭据是以未加密的格式保存的。

  • HTTP 协议中没有适当的注销支持;因此我们必须关闭所有浏览器窗口才能再次使用相同的用户名登录。

cookie身份验证模式在提供的功能方面优于http。这种模式允许真正的登录和注销,并且可以与任何类型的 Web 服务器上运行的 PHP 一起使用。它在 phpMyAdmin 内部呈现登录面板(如下面的截图所示)。这可以根据应用程序源代码进行自定义。然而,正如你可能已经猜到的,对于cookie身份验证,浏览器必须接受来自 Web 服务器的 cookie——但无论如何,这对所有身份验证模式都是如此。

这种模式将登录屏幕中输入的用户名存储为我们浏览器中的永久 cookie,而密码则存储为临时 cookie。在多服务器配置中,与每个服务器对应的用户名和密码是分开存储的。为了防止针对 cookie 内容的攻击方法泄露用户名和密码的机密性,它们使用 Blowfish 密码进行加密。因此,要使用这种模式,我们必须在config.inc.php中定义(一次)一个秘密字符串,该字符串将用于安全加密从此 phpMyAdmin 安装中存储为 cookie 的所有密码。

这个字符串是通过blowfish_secret指令设置的:

$cfg['blowfish_secret'] = 'jgjgRUD875G%/*';

在上面的例子中,使用了一串任意的字符;这个字符串可以非常复杂,因为没有人需要在登录面板上输入它。如果我们未能配置这个指令,phpMyAdmin 将生成一个随机的秘密字符串,但它只会持续当前的工作会话。因此,一些功能,比如在登录面板上回忆上一个用户名,将不可用。

然后,对于每个特定服务器的部分,使用以下内容:

$cfg['Servers'][$i]['auth_type'] = 'cookie';

下次启动 phpMyAdmin 时,我们将看到如下截图所示的登录面板:

使用 cookie 值进行身份验证

默认情况下,phpMyAdmin 在登录面板中显示上次成功登录到该特定服务器的用户名,从永久 cookie 中检索。如果这种行为不可接受(同一工作站上的其他用户不应该看到上一个用户名),我们可以将以下参数设置为FALSE

$cfg['LoginCookieRecall'] = FALSE;

有一个安全功能,可以为密码的有效性添加特定的时间限制。这个功能有助于保护工作会话。成功登录后,我们的密码(加密)与计时器一起存储在 cookie 中。phpMyAdmin 中的每个操作都会重置计时器。如果我们在一定数量的秒内保持不活动,就会被断开连接,必须重新登录,这个数量在$cfg['LoginCookieValidity']中定义。增加这个参数并不总是有效,因为 PHP 自己的session.gc_maxlifetime指令可能会有阻碍。请参考php.net/manual/en/session.configuration.php来了解这个指令。因此,如果 phpMyAdmin 检测到session.gc_maxlifetime的值小于配置的$cfg['LoginCookieValidity'],则会在主页上显示警告。默认值为 1440 秒;这与php.inisession.gc_maxlifetime参数的默认值相匹配。

注意

用于保护用户名和密码的 Blowfish 算法需要进行许多计算。为了实现最佳速度,我们的 Web 服务器上必须安装 PHP 的mcrypt扩展及其相应的库。

为了帮助用户意识到这个扩展是非常重要的,当 phpMyAdmin 检测到其缺失时,会在主页上显示一条消息。$cfg['McryptDisableWarning']指令控制这条消息。默认情况下,false的值意味着显示这条消息。

使用登录模式进行身份验证

在工作会话期间,用户可能会遇到来自不同 Web 应用程序的多个身份验证请求。原因是这些应用程序之间不会相互通信,这种情况会给大多数用户带来不便。

signon模式使我们能够使用另一个应用程序的凭据来跳过 phpMyAdmin 的身份验证阶段。为了使其工作,这个其他应用程序必须将正确的凭据存储到 PHP 的会话数据中,以便稍后由 phpMyAdmin 检索。

注意

根据 PHP 手册,将凭据存储在 PHP 会话中并不一定安全:php.net/manual/en/session.security.php

要启用这种模式,我们从以下指令开始:

$cfg['Servers'][$i]['auth_type'] = 'signon';

假设认证应用程序已经使用名为FirstApp的会话来存储凭据。我们通过添加以下代码行告诉 phpMyAdmin:

$cfg['Servers'][$i]['SignonSession'] = 'FirstApp';

我们必须注意那些在其他应用程序之前尝试访问 phpMyAdmin 的用户;在这种情况下,phpMyAdmin 将用户重定向到认证应用程序。这是通过以下方式完成的:

$cfg['Servers'][$i]['SignonURL'] = 'http://www.mydomain.com/FirstApp';

认证应用程序如何以 phpMyAdmin 能够理解的格式存储凭据?一个示例包含在scripts/signon.php中。在这个脚本中,有一个简单的 HTML 表单来输入凭据和初始化会话的逻辑——我们将使用FirstApp作为会话名称,并将用户、密码、主机和端口信息创建到这个会话中,如下所示:

$_SESSION['PMA_single_signon_user'] = $_POST['user'];
$_SESSION['PMA_single_signon_password'] = $_POST['password'];
$_SESSION['PMA_single_signon_host'] = $_POST['host'];
$_SESSION['PMA_single_signon_port'] = $_POST['port'];

注意

请注意,认证的第一个应用程序不需要向用户询问 MySQL 的凭据。这些可以在应用程序内部硬编码,因为它们是机密的,或者这个应用程序的凭据与 MySQL 的凭据之间有已知的对应关系。

要将附加的配置参数传递给signon模块,$_SESSION['PMA_single_signon_cfgupdate']可以接收一个包含在$cfg['Servers'][$i]中允许的任何附加服务器参数的数组。

然后,认证应用程序使用自己选择的方式——链接或按钮——让其用户启动 phpMyAdmin。如果在登录过程中发生错误(例如,拒绝访问),signon模块将适当的错误消息保存到$_SESSION['PMA_single_signon_error_message']中。

在另一个示例中,scripts/openid.php展示了如何使用流行的 OpenID 机制进行登录。

配置多服务器支持

config.inc.php文件至少包含一个特定服务器部分;但是,我们可以添加更多部分,使单个 phpMyAdmin 副本能够管理多个 MySQL 服务器。让我们看看如何配置更多服务器。

在配置文件中定义服务器

config.inc.php文件的特定服务器部分,我们看到了每个服务器的$cfg['Servers'][$i]的引用行。在这里,变量$i被使用,以便可以轻松地剪切和粘贴整个配置文件的部分来配置更多服务器。在复制这些部分时,我们应该注意复制$i++指令,这是在每个部分之前并且对于界定服务器部分至关重要的。

然后,在各个部分的末尾,以下行控制启动:

$cfg['ServerDefault'] = 1;

默认值1表示 phpMyAdmin 将默认使用第一个定义的服务器。我们可以指定任何数字,对应于特定服务器的部分。我们还可以输入值0,表示没有默认服务器;在这种情况下,登录时将呈现可用服务器的列表。

这个配置也可以通过基于 web 的设置来完成。这里给出了一个多服务器定义的示例,其中默认服务器设置为让用户选择:

在配置文件中定义服务器

如果没有定义默认服务器,phpMyAdmin 将呈现服务器选择:

在配置文件中定义服务器

通过任意服务器进行身份验证

如果我们想要能够连接到未定义的 MySQL 服务器,可以使用另一种机制。首先,我们必须设置以下参数:

$cfg['AllowArbitraryServer'] = TRUE;

我们还需要将$cfg['ServerDefault']的默认值设置回1。然后,我们需要使用cookie认证类型。我们将能够选择服务器并输入用户名和密码。

注意

允许任意服务器意味着可以通过 phpMyAdmin 连接到我们的网页服务器可访问的任何 MySQL 服务器。因此,这个功能应该与加强的安全机制一起使用(参考Securing phpMyAdmin部分)。

正如在这里所看到的,我们仍然可以在服务器选择中选择一个已定义的服务器。此外,我们还可以输入一个任意的服务器名称、用户名和密码。

通过任意服务器进行身份验证

登出

有一个机制可以告诉 phpMyAdmin 用户注销后应该到达哪个 URL。这个功能可以方便地与其他应用程序集成,并适用于所有允许注销的认证类型。这里是一个例子:

$cfg['Servers'][$i]['LogoutURL'] = 'http://www.mydomain.com';

这个指令必须包含一个绝对 URL,包括协议。

保护 phpMyAdmin

安全性可以在以下不同的级别进行检查:

  • 如何保护 phpMyAdmin 安装目录

  • 哪些工作站可以访问 phpMyAdmin

  • 合法用户可以看到哪些数据库

在目录级别保护 phpMyAdmin

假设有人未经授权尝试使用我们的 phpMyAdmin 副本。如果我们使用简单的config认证类型,任何知道我们的 phpMyAdmin URL 的人都将具有与我们相同的数据访问权限。在这种情况下,我们应该使用网页服务器提供的目录保护机制(例如,.htaccess,以点开头的文件名)来增加一层保护。更多细节请参阅en.wikipedia.org/wiki/Basic_access_authentication

如果我们决定使用httpcookie身份验证类型,我们的数据将足够安全。但是,我们应该对密码采取正常的预防措施(包括定期更改密码)。

phpMyAdmin 安装目录包含敏感数据。不仅配置文件,而且存储在那里的所有脚本都必须受到保护,以防止更改。我们应该确保除了我们之外,只有 Web 服务器有效用户可以读取该目录中包含的文件,并且只有我们可以对其进行写入。

注意

phpMyAdmin 的脚本永远不必修改此目录中的任何内容,除非我们使用将导出文件保存到服务器功能(在第六章中有解释)。

另一个建议是将默认的phpMyAdmin目录重命名为不太明显的名称;这可以阻止对我们服务器的探测。这被称为混淆安全,可以非常有效,但避免选择其他明显的名称,如admin

另一个可能的攻击来自与我们在同一 Web 服务器上拥有帐户的其他开发人员。在这种攻击中,某人可以尝试打开我们的config.inc.php文件。由于 Web 服务器可以读取此文件,因此某人可以尝试从其 PHP 脚本中包含我们的文件。这就是为什么建议使用 PHP 的open_basedir功能,可能将其应用于可能发起此类攻击的所有目录。更多细节可以在php.net/manual/en/ini.core.php#ini.open-basedir找到。

显示错误消息

phpMyAdmin 使用 PHP 的自定义错误处理机制。这个错误处理程序的好处之一是避免路径泄露,这被认为是一种安全弱点。与此相关的默认设置是:

$cfg['Error_Handler'] = array();
$cfg['Error_Handler']['display'] = false;

除非您正在开发新的 phpMyAdmin 功能并希望看到所有 PHP 错误和警告,否则应该让显示的默认值为false

使用基于 IP 的访问控制进行保护

可以实施额外的保护级别,这次验证接收请求的机器的Internet Protocol (IP)地址。为了实现这种保护级别,我们构建允许或拒绝访问的规则,并指定这些规则将被应用的顺序。

定义规则

规则的格式是:

<'allow' | 'deny'> <username> [from] <source>

from关键字是可选的;以下是一些示例:

规则 描述
allow Bob from 1.2.3/24 用户Bob允许从匹配网络1.2.3的任何地址访问(这是 CIDR IP 匹配,更多细节请参见en.wikipedia.org/wiki/CIDR_notation))。
deny Alice from 4.5/16 当用户Alice位于网络4.5时,无法访问。
allow Melanie from all 用户Melanie可以从任何地方登录。
deny % from all all可以等同于0.0.0.0/0,表示任何主机。在这里,%符号表示任何用户。

通常我们会有几个规则。假设我们希望有以下两个规则:

allow Marc from 45.34.23.12
allow Melanie from all

我们必须将它们放在config.inc.php(在相关的特定服务器部分)中,如下所示:

$cfg['Servers'][$i]['AllowDeny']['rules'] =
array('allow Marc from 45.34.23.12', 'allow Melanie from all');

在定义单个规则或多个规则时,使用 PHP 数组。我们必须遵循其语法,将每个完整规则括在单引号中,并用逗号分隔每个规则。因此,如果我们只有一个规则,仍然必须使用数组来指定它。下一个参数解释了规则解释的顺序。

规则解释的顺序

默认情况下,此参数为空:

$cfg['Servers'][$i]['AllowDeny']['order'] = '';

这意味着不进行基于 IP 的验证。

假设我们希望默认情况下允许访问,只拒绝对某些用户名/IP 对的访问,我们应该使用:

$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';

在这种情况下,所有deny规则将首先应用,然后是allow规则。如果规则中没有提到的情况,将允许访问。为了更加严格,我们希望默认情况下拒绝。我们可以使用:

$cfg['Servers'][$i]['AllowDeny']['order'] = 'allow,deny';

这次,所有allow规则首先应用,然后是deny规则。如果规则中没有提到的情况,访问将被拒绝。指定规则顺序的第三种(也是最严格的)方式是:

$cfg['Servers'][$i]['AllowDeny']['order'] = 'explicit';

现在,deny规则会在allow规则之前应用。用户名/IP 地址对必须在allow规则中列出,并且不能在deny规则中列出,才能获得访问权限。

阻止 root 访问

由于root用户几乎存在于所有的 MySQL 安装中,因此经常成为攻击目标。一个参数允许我们轻松地阻止 MySQL 的root账户的所有 phpMyAdmin 登录,使用以下设置:

$cfg['Servers'][$i]['AllowRoot'] = FALSE;

一些系统管理员更喜欢在 MySQL 服务器级别禁用root账户,创建另一个不太明显的账户,拥有相同的权限。这样做的好处是阻止了来自所有来源的root访问,而不仅仅是来自 phpMyAdmin。

保护传输中的数据

HTTP 本身并不免疫网络嗅探(从传输中获取敏感数据)。因此,如果我们不仅想保护用户名和密码,而且想保护在 Web 服务器和浏览器之间传输的所有数据,那么我们必须使用 HTTPS。

为此,假设我们的 Web 服务器支持 HTTPS,我们只需在 URL 中使用https而不是http来启动 phpMyAdmin,如下所示:

https://www.mydomain.com/phpMyAdmin/

如果我们正在使用PmaAbsoluteUri自动检测,如下所示:

$cfg['PmaAbsoluteUri'] = '';

phpMyAdmin 将看到我们在 URL 中使用了 HTTPS,并做出相应的反应。

如果没有,我们必须按照以下方式在此参数中加入https部分:

$cfg['PmaAbsoluteUri'] = 'https://www.mydomain.com/phpMyAdmin';

我们可以通过以下设置自动将用户切换到 HTTPS 连接:

$cfg['ForceSSL'] = TRUE;

摘要

本章概述了如何使用单个副本的 phpMyAdmin 来管理多个服务器,以及使用认证类型来满足用户组的需求,同时保护认证凭据。本章还涵盖了保护我们的 phpMyAdmin 安装的方法。

在下一章中,我们将看一下 phpMyAdmin 用户界面中包括的所有面板和窗口。

第三章:概述界面

在进入以任务为导向的章节之前,例如搜索等,有必要先看一下 phpMyAdmin 界面的一般组织。我们还将看到影响整个界面的配置参数和设置。

概述面板和窗口

phpMyAdmin 界面由各种面板和窗口组成,每个面板都有特定的功能。我们将首先简要概述每个面板,然后在本章后面进行详细查看。

登录面板

出现的登录面板取决于所选择的身份验证类型。对于http类型,它将采用浏览器的 HTTP 身份验证弹出屏幕的形式。对于cookie类型,将显示 phpMyAdmin 特定的登录面板(在第二章中介绍)。对于外部身份验证(signon),登录面板由外部应用程序本身处理。默认情况下,此面板上有服务器选择对话框和语言选择器。

然而,如果我们使用config身份验证类型,则不会显示登录面板,第一个显示的界面包含导航和主面板。

导航和主面板

这些面板一起显示,并在我们使用 phpMyAdmin 的大部分工作会话期间显示。导航面板是我们在数据库和表之间的指南。主面板是数据管理和结果显示的工作区。其确切布局取决于从导航面板和执行的操作序列中所做的选择。对于大多数从左到右书写的语言,导航面板位于左侧,主面板位于右侧,但对于从右到左书写的语言,如希伯来语,这些面板是相反的。

导航和主面板

首页

主面板可以采用起始页的形式。起始页将包含与 MySQL 操作或 phpMyAdmin 信息相关的各种链接,一个语言选择器,可能还有主题/样式选择器。

视图

在主面板中,我们可以看到数据库视图——在这里我们可以对特定数据库执行各种操作,或者视图——在这里我们可以访问许多管理表的功能。还有一个服务器视图,对系统管理员和非管理员用户都有用。所有这些视图都有一个顶部菜单,它以选项卡的形式呈现,导航到不同的页面,用于呈现按常见功能(表结构、权限等)重新组织的信息。

查询窗口

这是一个独立的窗口,通常从导航面板打开,有时也从主面板编辑 SQL 查询时打开。它的主要目的是方便查询工作,并在主面板上显示结果。

起始页

当我们启动 phpMyAdmin 时,我们将看到以下面板中的一个(取决于config.inc.php中指定的身份验证类型,以及其中是否定义了多个服务器):

  • 其中一个登录面板

  • 导航和主面板显示在主面板中的起始页

自定义一般设置

本节描述了对许多面板产生影响的设置。这些设置修改了窗口标题的外观,信息图标的外观,以及表格列表的排序方式。所有页面的视觉风格都由主题系统控制,该系统也在本节中介绍。本节还涉及如何限制用户看到的数据库列表。

配置窗口标题

当导航和主面板显示时,窗口标题会更改以反映哪个 MySQL 服务器、数据库和表是活动的。这些指令控制要显示的信息量:$cfg['TitleDefault'], $cfg['TitleServer'], $cfg['TitleDatabase']$cfg['TitleTable']

如果没有选择服务器,则$cfg['TitleDefault']控制标题。当选择了服务器(但没有选择数据库)时,$cfg['TitleServer']控制标题栏中显示的内容。然后如果选择了数据库,则$cfg['TitleDatabase']起作用。最后,如果选择了表,则$cfg['TitleTable']生效。

这些指令包含控制显示哪些信息的格式字符串。例如,这是其中一个指令的默认值:

$cfg['TitleTable'] = '@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@';

可能的格式字符串及其含义在Documentation.html的 FAQ 6.27 中有描述。

数据库和表名的自然排序

通常,计算机按词法顺序对项目进行排序,这会导致对表列表的以下结果:

table1
table10
table2
table3

phpMyAdmin 默认实现自然排序,由$cfg['NaturalOrder']设置为TRUE来指定。因此导航和主面板中的数据库和表列表按以下方式排序:

table1
table2
table3
table10

创建特定网站的页眉和页脚

一些用户可能希望在phpMyAdmin界面上显示公司标志、公司帮助台的链接或其他信息。为此,在主phpMyAdmin目录中,我们可以创建两个脚本—config.header.inc.phpconfig.footer.inc.php。我们可以在这些脚本中放入我们自己的 PHP 或 XHTML 代码,它将出现在cookie登录和主面板页面的开头(页眉)或结尾(页脚)。

例如,创建一个包含以下内容的config.footer.inc.php

<hr />
<em>All the information on this page is confidential.</em>

在页脚中使用这样的句子将在所有页面上产生预期的消息,如下截图所示:

创建特定网站的页眉和页脚

主题

phpMyAdmin 中提供了一个主题系统。颜色参数和各种图标位于themes子目录下的目录结构中。对于每个可用的主题,都有一个以主题命名的子目录。它包含:

  • 主题参数的layout.inc.php

  • 包含各种 CSS 脚本的css目录

  • 包含任何图标或其他图像(例如标志)的img目录

  • screen.png,这个主题的屏幕截图

下载的套件包含两个主题,但在phpmyadmin.net/home_page/themes.php上还有更多可用的主题。安装新主题只需下载相应的.zip文件并将其解压缩到themes子目录中。

注意

如果有人想要构建一个包含 JavaScript 代码的自定义主题,请注意所有 phpMyAdmin 3.4 页面都包含 jQuery 库。

配置主题

config.inc.php中,$cfg['ThemePath']参数默认包含'./themes',指示所需结构位于的子目录。这可以更改为指向另一个目录,其中包含您公司特定的 phpMyAdmin 主题。

默认选择的主题在$cfg['ThemeDefault']中指定,并设置为'pmahomme'。如果用户没有主题选择,将使用此主题。

选择主题

在主页上,我们可以向用户提供一个主题选择器。将$cfg['ThemeManager']设置为TRUE(默认值)会显示如下截图所示的选择器:

选择主题

为了帮助选择合适的主题,主题/样式链接显示一个面板,其中包含可用主题的屏幕截图和获取更多主题链接。然后我们可以在想要的主题下点击take it。所选主题的引用将存储在一个 cookie 中,并且默认情况下将应用于我们连接的所有服务器。

为了使 phpMyAdmin 记住每个 MySQL 服务器的一个主题,我们将$cfg['ThemePerServer']设置为TRUE

选择语言

登录面板(如果有)和主页上会出现一个语言选择器。phpMyAdmin 的默认行为是使用浏览器偏好设置中定义的语言,如果有对应版本的语言文件的话。

如果程序无法检测到语言,则使用的默认语言在config.inc.php中的$cfg['DefaultLang']参数中定义为'en'(英语)。这个值是可以改变的。语言名称的可能值在libraries/select_lang.lib.php脚本中的PMA_langDetails()函数中定义。

即使默认语言已经定义,每个用户(特别是在多用户安装中)都可以从选择器中选择自己喜欢的语言。用户的选择将在可能的情况下保存在 cookie 中。

我们还可以通过设置$cfg['Lang']参数的值(比如'fr'表示法语)来强制使用单一语言。另一个参数$cfg['FilterLanguages']也是可用的。假设我们想要缩短可用语言列表,只显示英语法语,因为这些是 phpMyAdmin 实例的用户专门使用的语言。这可以通过构建一个正则表达式来实现,指示我们想要显示的语言基于这些语言的 ISO 639 代码。继续我们的例子,我们会使用:

$cfg['FilterLanguages'] = '^(fr|en)';

在这个表达式中,插入符(^)表示“以…开头”,竖线(|)表示“或”。这个表达式表示我们将语言列表限制在对应的 ISO 代码以fren开头的语言。

默认情况下,这个参数是空的,意味着没有对可用语言列表应用任何过滤器。

滑块

在一些页面上,你会看到一个小加号,后面跟着一个控制标签——要么是选项,要么是详情。点击标签会打开一个滑块,显示界面的一个部分,这部分在日常工作中很少使用。由于很少有人愿意立即看到整个界面而牺牲屏幕空间,因此有一个配置参数来控制滑块的初始设置方式:

$cfg['InitialSlidersState'] = 'closed';

closed的默认值意味着滑块必须通过点击标签来打开;你可能已经猜到了相反的值是open。第三个值disabled可以被滑块过敏的用户使用。

限制数据库列表

有时候,避免在导航面板中显示用户可以访问的所有数据库是有用的。phpMyAdmin 提供了两种限制的方式——only_dbhide_db

为了指定可以看到的内容列表,使用only_db参数。它可以包含一个数据库名称或一个数据库名称列表。只有这些数据库将在导航面板中显示:

$cfg['Servers'][$i]['only_db'] = 'payroll';
$cfg['Servers'][$i]['only_db'] = array('payroll', 'hr);

数据库名称可以包含 MySQL 通配符,比如_%。这些通配符在dev.mysql.com/doc/refman/5.1/en/account-names.html中有描述。如果使用数组来指定多个数据库,它们将按照数组中的顺序在界面上显示。

only_db的另一个特性是,你可以使用它来不限制列表,而是强调将显示在列表顶部的某些名称。在这里,myspecial数据库名称将首先显示,然后是所有其他名称:

$cfg['Servers'][$i]['only_db'] = array('myspecial', '*');

我们还可以使用hide_db参数指定哪些数据库名称必须被隐藏。它包含一个正则表达式(en.wikipedia.org/wiki/Regular_expression),表示要排除的内容。如果我们不希望用户看到任何以'secret'开头的数据库,我们会使用:

$cfg['Servers'][$i]['hide_db'] = '^secret';

这些参数适用于此服务器特定配置的所有用户。

注意

这些机制不会取代 MySQL 权限系统。用户对其他数据库的权限仍然适用,但他们不能使用 phpMyAdmin 的导航面板来访问他们的其他数据库或表。

停用 Ajax

某些页面使用异步JavaScript 来改善用户体验。我们可以通过将$cfg['AjaxEnable']设置为false来停用此行为;在这种情况下,已经编程为非 Ajax 行为的页面将停止使用 Ajax,而是执行完全刷新。用户可能会感觉这样的体验不够流畅。

字符集和排序规则

字符集描述了特定语言或方言的符号是如何编码的。排序规则包含了比较和排序字符集中字符的规则。用于存储我们的数据的字符集可能与用于显示它的字符集不同,导致数据不一致。因此,需要进行数据转换。

自从 MySQL 4.1.x 以来,MySQL 服务器为我们进行字符重编码工作。此外,MySQL 使我们能够指示每个数据库、每个表甚至每个字段的字符集和排序规则。数据库的默认字符集适用于其每个表,除非在表级别被覆盖。相同的原则适用于每一列。

有效的字符集和排序规则

在主页上,我们可以看到MySQL 字符集信息和MySQL 连接排序规则选择器。这是MySQL 字符集信息:

有效的字符集和排序规则

字符集信息(在MySQL 字符集之后所见)用于生成 HTML 信息,告诉浏览器页面的字符集是什么。

我们还可以使用MySQL 连接排序规则对话框选择连接到 MySQL 服务器时要使用的字符集和排序规则。这将传递给 MySQL 服务器。MySQL 然后将要发送到我们的浏览器的字符转换为此字符集。MySQL 还根据字符集信息解释从浏览器接收到的内容。请记住,所有表和列都有描述其数据编码方式的字符集信息。

有效的字符集和排序规则

通常情况下,默认值应该有效。但是,如果我们使用不同的字符集输入一些字符,我们可以在此对话框中选择适当的字符集。

以下参数定义了默认连接排序规则和字符集:

$cfg['DefaultConnectionCollation'] = 'utf8_unicode_ci';

导航面板

导航面板包含以下元素:

  • 标志

  • 服务器列表(如果$cfg['LeftDisplayServers']设置为TRUE

  • 主页链接或图标(返回到 phpMyAdmin 主页)

  • 注销链接或图标(如果可以注销)

  • 指向查询窗口的链接或图标

  • 显示 phpMyAdmin 和 MySQL 文档的图标

  • 重新加载链接或图标(仅刷新此面板)

  • 表名过滤器(在某些条件下,请参见表名过滤器部分)

  • 数据库和表的名称

如果$cfg['MainPageIconic']设置为TRUE(默认值),我们会看到图标。但是,如果设置为FALSE,我们会看到链接。

导航面板可以通过点击并移动垂直分隔线来调整大小,以向首选方向显示更多数据,以防数据库或表名对于默认导航面板大小太长。

我们可以自定义此面板的外观。许多与外观相关的参数位于themes/<themename>/layout.inc.php中。$cfg['NaviWidth']参数包含导航面板的默认宽度(以像素为单位)。背景颜色在$cfg['NaviBackground']中定义。$cfg['NaviPointerColor']参数定义了指针颜色。要激活正在使用的任何主题的导航指针,config.inc.php中存在一个主设置$cfg['LeftPointerEnable']。其默认值为TRUE

配置标志

标志显示行为由多个参数控制。首先,$cfg['LeftDisplayLogo']必须设置为TRUE,才能启用标志的任何显示。默认情况下是true。单击此标志将界面带到$cfg['LeftLogoLink']参数中列出的页面,通常是 phpMyAdmin 的主页面(默认值main.php),但可以更改为任何 URL。最后,$cfg['LeftLogoLinkWindow']参数指示单击标志后新页面出现在哪个窗口。默认情况下,它在主页面上(值为main)。但是,通过使用值new,它可以在全新的窗口上。

logo_left.png 文件本身来自于每个特定主题目录结构中的位置。

数据库和表列表

以下示例显示尚未选择任何数据库:

数据库和表列表

也可能看到没有数据库消息,而不是数据库列表。这意味着我们当前的 MySQL 权限不允许我们查看任何现有数据库。

注意

MySQL 服务器始终至少有一个数据库(名为mysql),但可能存在我们无权查看它的情况。此外,从 MySQL 5.0.2 开始,除非通过$cfg['Servers'][$i]['only_db']$cfg['Servers'][$i]['hide_db']机制隐藏,否则数据库列表中始终会出现一个名为information_schema的特殊数据库。它包含一组描述已登录用户可见的元数据的视图。

我们可能有权创建一个,如第四章中所述。

轻模式

导航面板可以以两种方式显示——轻模式完整模式。轻模式是默认使用的,由$cfg['LeftFrameLight']中的TRUE值定义。此模式显示可用数据库的下拉列表,并且仅显示当前选择数据库的表。它比完整模式更有效;原因在本章后面的完整模式部分中解释。在下面的屏幕截图中,我们选择了mysql数据库:

轻模式

单击数据库名称或选择它会在Database视图中打开主面板,单击表名会在Table视图中打开主面板以浏览此表。(有关详细信息,请参阅主面板部分。)

数据库名称的树形显示

例如,用户可能被允许只在一个数据库上工作marc。一些系统管理员通过允许用户marc创建许多数据库,前提是所有数据库的名称都以marc开头,例如marc_airlinemarc_car,提供了更灵活的方案。在这种情况下,导航面板可以设置为显示这些数据库名称的树,如下面的屏幕截图所示:

数据库名称的树形显示

此功能由以下参数控制:

$cfg['LeftFrameDBTree'] = TRUE;
$cfg['LeftFrameDBSeparator'] = '_';

$cfg['LeftFrameDBTree']中的TRUE的默认值确保了此功能的激活。分隔符的常用值是'_'。如果我们需要多个字符集作为分隔符,我们只需使用一个数组:

$cfg['LeftFrameDBSeparator'] = array('_', '+');

表名过滤器

如果数据库中有太多表,我们可能只想显示其中的一部分,基于过滤文本字符串。仅在轻模式下,如果当前选择了数据库,则会显示一个表名过滤器,前提是表的数量超过了$cfg['LeftDisplayTableFilterMinimum']的值,默认值为30。当我们在此过滤器中输入表名的子集时,表的列表将减少以匹配此子集。要尝试此功能,我们将指令的值设置为15,并在过滤字段中输入time

表名过滤器

完整模式

先前的示例是在 Light 模式下显示的,但是将$cfg['LeftFrameLight']参数设置为FALSE会使用可折叠菜单(如果浏览器支持)完整布局我们的数据库和表格,如下截图所示:

全模式

默认情况下,未选择全模式;如果我们当前的权限允许我们访问大量数据库和表格,它可能会增加网络流量和服务器负载。必须在导航面板中生成链接,以启用对表格的访问和快速访问每个表格。

表格简略统计

将光标移动到表格名称上会显示关于该表格的注释(如果有的话),以及当前其中的行数,如下截图所示:

表格简略统计

表格快速访问图标

已经确定,表格上最常见的操作必须是浏览。因此,单击表格名称本身会以浏览模式打开它。每个表格名称旁边的图标是在每个表格上执行另一个操作的快捷方式,默认情况下,它会将我们带到“结构”视图。

表格快速访问图标

$cfg['LeftDefaultTabTable']参数控制此操作。它的默认值是'tbl_structure.php',这是显示表格结构的脚本。此参数的其他可能值在Documentation.html中列出。如果我们更喜欢设置,其中单击表格名称会在结构页面中打开它,而单击快速访问图标会导航到浏览页面,我们必须设置这些指令:

$cfg['LeftDefaultTabTable'] = 'sql.php';
$cfg['DefaultTabTable'] = 'tbl_structure.php';

数据库中表格的嵌套显示

MySQL 的数据结构基于两个级别——数据库和表格。这不允许对表格进行项目划分。要按项目工作,用户必须依靠拥有多个数据库,但这并不总是由他们的提供商允许。为了帮助他们解决这个问题,phpMyAdmin 支持基于表格命名的嵌套级别功能。

假设我们可以访问db1数据库,并且我们想要表示两个项目,营销工资单。在项目名称和表格名称之间使用特殊分隔符(默认为双下划线),我们创建marketing, payroll__employeespayroll__jobs表格,实现如下截图所示的视觉效果:

数据库中表格的嵌套显示

此功能是通过$cfg['LeftFrameTableSeparator'](此处设置为'__')进行参数化,以选择标记每个级别更改的字符,以及$cfg['LeftFrameTableLevel'](此处设置为'1')用于子级的数量。

注意

嵌套级别功能仅用于改进导航面板的外观。在 MySQL 语句中引用表格的正确方法保持不变,例如,db1.payroll__jobs

单击导航面板上的项目名称(这里是payroll)会在主面板中打开此项目,仅显示与该项目关联的表格。

计算表格数量

默认情况下,$cfg['Servers'][$i]['CountTables']设置为false,以加快显示速度,不统计每个数据库的表格数量。如果设置为true,则在导航面板中显示此计数,显示在每个数据库名称旁边。

从服务器列表中选择

如果我们必须从同一个 phpMyAdmin 窗口管理多个服务器,并且经常需要在服务器之间切换,始终在导航面板中具有服务器列表是有用的。

从服务器列表中选择

为此,必须将$cfg['LeftDisplayServers']参数设置为TRUE。服务器列表可以有两种形式——下拉列表或链接。显示哪种形式取决于$cfg['DisplayServersList']。默认情况下,此参数设置为FALSE,因此我们看到服务器的下拉列表。将$cfg['DisplayServersList']设置为TRUE会生成到所有定义的服务器的链接列表。

处理多个数据库或表格

本节描述了一些应对持有大量数据库和表的服务器的技术。

界面上的限制

如果我们可以访问数百甚至数千个数据库,或者在同一个数据库中有数百个表,那么要使用界面将会很困难。这里显示了两个参数及其默认值,它们通过添加页面选择器和导航链接来限制显示的数据库和表的数量:

$cfg['MaxDbList'] = 100;
$cfg['MaxTableList'] = 250;

$cfg['MaxTableList']设置为5的效果可以在导航面板上看到,如下所示,对于具有超过五个表的数据库:

界面上的限制

页面选择器和导航链接也出现在主面板中。

提高获取速度

三个配置参数会影响数据库名称检索和表计数的速度。第一个是:

$cfg['Servers'][$i]['ShowDatabasesCommand'] = 'SHOW DATABASES';

每当 phpMyAdmin 需要从服务器获取数据库列表时,它都会使用此参数中列出的命令。默认命令SHOW DATABASES在普通情况下是可以的。但是,在具有许多数据库的服务器上,通过尝试其他命令,例如以下之一,可以观察到速度的提高:

SHOW DATABASES LIKE '#user#\_%'
SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA

在第一个示例中,#user#被当前用户名替换。

在极端情况下(成千上万个数据库),安装自己的 phpMyAdmin 副本的用户应该在此参数中放入false。这将阻止任何数据库名称的获取,并要求将$cfg['Servers'][$i]['only_db']参数填充为此用户的数据库列表。

最后,一些用户在从INFORMATION_SCHEMA中检索信息时(至少在 MySQL 5.1 下)遇到速度问题。因此,$cfg['Servers'][$i]['DisableIS']指令,默认值为TRUE,禁用了 phpMyAdmin 代码的大部分部分使用INFORMATION_SCHEMA。对于您的服务器,将其设置为FALSE可能值得一试,以查看响应时间是否有所改善。

主面板

主面板是主要的工作区域,所有可能的视图都在以下部分中解释。它的外观可以自定义。背景颜色在$cfg['MainBackground']中定义。

首页

主页的链接数量可能会根据登录模式和用户权限而有所不同。导航面板上的首页链接用于显示此页面。它显示了 phpMyAdmin 和 MySQL 的版本,MySQL 服务器名称以及登录用户。为了减少有关我们的 Web 服务器和 MySQL 服务器的信息,我们可以将$cfg['ShowServerInfo']设置为FALSE。另一个设置$cfg['ShowPhpInfo'],如果我们想在主页上看到显示 PHP 信息链接,可以将其设置为TRUE——默认情况下其值为FALSE。在某些情况下,这里可能会出现无权限消息;如何解决此问题以及如何修复此条件在第四章中有介绍。

在此示例中,普通用户可以通过使用更改密码链接从界面更改他/她的密码,从而带来以下对话框:

首页

我们可以通过两次输入新密码或使用生成按钮(仅在启用 JavaScript 的浏览器中可用)来选择新密码;在这种情况下,新密码将显示在一个清晰的字段中,供我们好好记下,并自动填入更改密码的对话框中。强烈建议以这种方式生成密码,因为它们很可能比人为选择的密码更安全。要禁止从主页上的更改密码链接,我们将$cfg['ShowChgPassword']设置为FALSE。特权用户在主页上有更多选项。他们有更多链接来管理整个服务器,例如权限链接(有关此内容,请参见第十九章)。

数据库视图

每次我们从导航面板点击数据库名称时,phpMyAdmin 都会进入“数据库”视图(如下截图所示)。

这里我们可以看到数据库的概述——现有的表,创建表的对话框,到“数据库”视图页面的选项卡,以及我们可能在此数据库上执行的一些特殊操作,以生成文档和统计信息。每个表旁边都有一个复选框,用于对该表执行全局操作(在第九章中介绍)。通过复选框或单击行背景的任何位置来选择表。如果$cfg['ShowStats']设置为TRUE,我们还可以看到每个表的大小。此参数还控制“表”视图中表特定统计信息的显示。

这里出现的初始屏幕是数据库的结构页面。我们注意到几乎每个列标题——如表,记录大小——都是链接,可以用来对应的列进行排序(第第四章介绍了排序)。虽然按降序表名排序可能不太有用,但按降序大小排序绝对是我们应该偶尔做的事情。

数据库视图

当进入“数据库”视图时,我们可能希望出现不同的初始页面。这由$cfg['DefaultTabDatabase']参数控制,在配置文件中的注释中给出了可用选项。

行数是使用快速方法获取的,即SHOW TABLE STATUS语句,而不是使用SELECT COUNT(*) FROM TABLENAME。这种快速方法通常是准确的,但对于InnoDB表来说,它返回的是近似记录数。为了帮助获取正确的记录数,即使对于InnoDB,也可以使用$cfg['MaxExactCount']参数。如果近似记录数低于此参数的值——默认为 20000——将使用较慢的SELECT COUNT(*)方法。

不要为MaxExactCount参数设置过高的值。如果您的InnoDB表中有成千上万行数据,您将得到正确的结果,但需要等待几分钟。要查看显示的InnoDB行数,请参阅第十章,在那里我们实际上有一个InnoDB表可以使用。

当在“大小”和“开销”列中看到术语KiB时,用户可能会感到惊讶。phpMyAdmin 采用了国际电工委员会(IEC)的二进制前缀(参见en.wikipedia.org/wiki/Binary_prefix))。显示的值在每个语言文件中定义。

表视图

这是一个常用的视图,可以访问所有特定于表的页面。默认情况下,初始屏幕是表的浏览屏幕,显示此表数据的第一页。请注意,此屏幕的标题始终显示当前数据库和表名称。我们还可以看到为表设置的注释,显示在表名旁边:

表视图

$cfg['DefaultTabTable']参数定义了“表”视图的初始页面。一些用户可能希望避免看到第一页的数据,因为在生产中他们通常运行保存的查询或进入搜索页面(在第八章中解释)。

服务器视图

每次返回主页时都会进入此视图。当然,特权用户在“服务器”视图中会看到更多选项。创建“服务器”视图面板是为了将相关的服务器管理页面分组,并在它们之间实现轻松导航。

服务器视图

默认的“服务器”页面由$cfg['DefaultTabServer']参数控制。此参数定义了初始起始页面。对于多用户安装,建议保持默认值(main.php),显示传统的主页。我们可以选择通过将此参数更改为server_status.php来显示服务器统计信息,或者通过server_privileges.php来查看用户列表。其他可能的选择在配置文件中有解释,并且服务器管理页面在第十九章中有介绍。

主页和菜单选项卡的图标

一个配置参数$cfg['MainPageIconic']控制主面板各处图标的外观:

  • 在主页上

  • 在列出“服务器,数据库”和“表”信息时的页面顶部

  • 在“数据库,表”和“服务器”视图的菜单选项卡上

当参数设置为TRUE时,默认情况下,您将看到以下截图:

主页和菜单选项卡的图标

打开新的 phpMyAdmin 窗口

有时我们希望同时比较两个表的数据或者有其他需要使用多个 phpMyAdmin 窗口的情况。几乎每个页面的底部都有一个小图标,可以打开另一个带有当前面板内容的 phpMyAdmin 窗口。此外,此图标还可以用于创建一个指向当前 phpMyAdmin 页面的浏览器书签(但我们应该登录以访问数据)。

打开新的 phpMyAdmin 窗口

用户偏好

一个 phpMyAdmin 实例可以安装为多个用户提供服务;但是,在 3.4.0 版本之前,这些用户必须接受由负责此实例的人选择的参数值。

确实,界面上的一些页面允许调整特定参数,并且其中一些参数被记住在 cookie 中,例如所选语言;但这个版本是第一个提供全局机制来调整和记住每个用户的偏好。

即使在实例只有一个用户的情况下,从界面微调偏好比操作配置文件更方便。

访问用户偏好

从主页,我们点击“更多设置”。从“服务器”视图中的任何页面,我们点击“设置”菜单选项卡。进入“设置”面板后,我们看到“管理您的设置”子页面:

访问用户偏好

这个子页面是我们全局处理偏好的地方。其他子页面,如“功能”和“主框架”,用于更改特定偏好-请参考“更改设置”部分。

“导入”和“导出”对话框将在“保存偏好的可能位置”部分中介绍。 “更多设置”对话框提醒我们,config.inc.php是配置所有可能性的地方,例如指定服务器和认证模式超出了用户偏好的范围。

“重置”对话框使我们可以一键返回所有用户偏好的默认值。

保存偏好的可能位置

有三个可能的位置可以保存用户偏好。每个位置都有优缺点;本节涵盖了这些模式。

在 phpMyAdmin 配置存储中保存

要启用此模式,必须使用包含这些偏好的表的名称对$cfg['Servers'][$i]['userconfig']进行配置,并且该表必须存在。这个保存位置非常有用,因为设置在登录后立即应用于运行的实例;此外,它会跟随用户在任何浏览器上使用。

如果未配置此存储,设置页面会显示以下消息:

“您的偏好将仅保存当前会话。要永久保存它们,需要进行 phpMyAdmin 配置存储”。

保存在文件中

我们始终有可能将我们的设置导出到文件中,然后再导入。该文件遵循 JSON 格式(参见json.org))。在以下情况下,这种方法可能很方便:

  • 我们计划在另一个 phpMyAdmin 实例上使用这些设置

  • 我们希望保留我们的设置历史记录;因此,不时地将它们保存在几个文件中

保存在浏览器的本地存储中

最近的浏览器,例如 Firefox 6 和 Internet Explorer 9,提供了一种在会话之间持久存在的本地存储机制。第一次进入管理您的设置子页面时,我们会在从浏览器的存储中导入对话框中看到您没有保存的设置!消息。然而,将设置导出到浏览器的本地存储后,导入部分会告诉我们使用此机制上次保存设置的日期和时间。

此外,当在浏览器的存储中找到 phpMyAdmin 设置并且 phpMyAdmin 配置存储不可用时,每个 phpMyAdmin 页面顶部都有以下消息:

您的浏览器为此域名配置了 phpMyAdmin。您想要为当前会话导入吗?是/否

使用此方法的一个缺点是,我们的设置仅在使用此浏览器时才可用;此外,如果我们更改工作站时我们的浏览器设置不跟随我们,那么设置将绑定到此特定工作站(并适用于在其上运行 phpMyAdmin 的任何其他用户)。

更改设置

在进入特定偏好的子页面时,例如主框架子页面,我们会看到与此主题相关的第三级菜单:

更改设置

如果偏好已从其默认值更改,则复选框或数据字段具有不同的背景颜色,并且旁边显示了一个回收图标,以便快速将此偏好重置为其默认值。对每个指令都提供了快速解释,并且链接指向文档和官方维基。作为一般建议,我们需要在切换到不同的子页面之前保存我们在页面上所做的任何更改;然而,在这个例子中,我们可以在启动和其他第三级菜单之间切换,如浏览模式,而不会丢失我们的更改。

禁止特定偏好

负责config.inc.php的人对用户偏好中可以更改哪些设置有最终决定权。为了禁止某些设置,我们使用$cfg['UserprefsDisallow']指令。我们将一个包含代表要禁止的$cfg中的键的数组放入其中。例如,我们将此指令设置为:

$cfg['UserprefsDisallow'] = array('AjaxEnable', 'MaxDbList');

这会产生如下截图所示的警告:

禁止特定偏好

显示开发人员设置

某些设置是敏感的,仅供开发 phpMyAdmin 的人员使用。例如,显示所有错误的可能性,包括 PHP 通知,可能会导致公开 phpMyAdmin 实例的完整路径。因此,在功能子选项卡中,只有在$cfg['UserprefsDeveloperTab']设置为true时,才会显示开发人员菜单。

查询窗口

通常情况下,我们可以在一个独立的窗口中输入和调整查询,并且与主面板同步是非常方便的。这个窗口被称为查询窗口。我们可以通过使用小的SQL图标或导航面板的图标或链接区域中的查询窗口链接来打开此窗口。此功能仅适用于启用 JavaScript 的浏览器。

查询窗口本身有子页面,并且如下截图所示,它出现在主面板上方:

查询窗口

我们可以使用$cfg['QueryWindowWidth']$cfg['QueryWindowHeight']选择此窗口的尺寸(以像素为单位)。第十一章更详细地解释了查询窗口,包括可用的 SQL 查询历史记录功能。

总结

本章涵盖了:

  • 语言选择系统

  • 导航和主面板的目的

  • 导航面板的内容,包括轻模式和完整模式

  • 主面板的内容,根据上下文的不同有不同的视图

  • 用户偏好功能

  • 查询窗口

下一章将指导您通过简单的步骤来完成一个新安装的 phpMyAdmin——初始表创建、数据插入和检索。

第四章:创建和浏览表

在看到了 phpMyAdmin 的整体布局之后,我们准备创建一个数据库,创建我们的第一个表,向其中插入一些数据,并浏览它。这些第一步是故意简单的,但它们将为您提供更复杂操作的基础。在本章结束时,我们将拥有两个基本表,这是后续练习的基础。

创建数据库

在创建表之前,我们必须确保我们有一个数据库,MySQL 服务器的管理员已经给了我们CREATE权限。存在以下可能性:

  • 管理员已经为我们创建了一个数据库,并且我们在导航面板中看到了它的名称;我们没有权利创建额外的数据库。

  • 我们有权从 phpMyAdmin 创建数据库。

  • 我们在一个共享主机上,主机提供商已经安装了一个通用的网络界面(例如 cPanel)来创建 MySQL 数据库和账户;在这种情况下,我们现在应该访问这个网络界面,确保我们至少创建了一个数据库和一个 MySQL 账户。

Server视图中的数据库面板是查找数据库创建对话框的地方。请注意,配置参数$cfg['ShowCreateDb']控制创建新数据库对话框的显示。默认情况下,它设置为true,显示对话框。

无权限

如果您没有创建数据库的权限,面板在创建新数据库标签下显示无权限消息。这意味着您必须使用已为您创建的数据库,或者要求 MySQL 服务器的管理员给您必要的CREATE权限。

注意

如果您是 MySQL 服务器的管理员,请参阅第十九章。

第一个数据库创建已被授权

如果 phpMyAdmin 检测到我们有权创建数据库,则对话框将显示如下截图所示:

第一个数据库创建已被授权

在输入字段中,如果$cfg['SuggestDBName']参数设置为TRUE,则会出现建议的数据库名称,这是默认设置。建议的数据库名称是根据我们拥有的权限构建的。

如果我们受限于使用前缀,前缀可能会在输入字段中建议。在这种情况下,前缀后面可能会跟着一个省略号,由 phpMyAdmin 添加。我们应该删除这个省略号,并用适当的名称完成输入字段。

第一个数据库创建已被授权

排序选择现在可以保持不变。通过这个对话框,我们可以为这个数据库选择一个默认的字符集和排序规则。这个设置可以稍后更改(参考第九章了解更多信息)。

我们假设我们有权创建一个名为marc_book的数据库。我们在输入字段中输入marc_book并点击创建。一旦数据库创建完成,我们将看到以下屏幕:

第一个数据库创建已被授权

请注意以下内容:

  • 主面板的标题已经更改,以反映我们现在位于这个数据库中

  • 显示有关创建的确认消息

  • 导航面板已更新;我们看到marc_book

  • 默认情况下,phpMyAdmin 向服务器发送的用于创建数据库的 SQL 查询以彩色显示

注意

phpMyAdmin 显示它生成的查询,因为$cfg['ShowSQL']设置为TRUE。查看生成的查询可以是学习 SQL 的好方法。

由于生成的查询可能很大并且占用屏幕空间很多,$cfg['MaxCharactersInDisplayedSQL']充当一个限制。其默认值为1000应该是在查看查询时看到太少或太多查询之间的一个良好平衡,特别是在进行大量导入时。

检查 phpMyAdmin 的反馈以确定我们通过界面进行的操作的有效性是很重要的。这样,我们可以检测到错误,比如名称中的拼写错误,或者在错误的数据库中创建表。phpMyAdmin 从 MySQL 服务器检索错误消息并在界面上显示它们。

创建我们的第一个表

现在我们有了一个新的数据库,是时候在其中创建一个表了。我们将创建的示例表名为book

选择列

在创建表之前,我们应该计划我们想要存储的信息。这通常是在数据库设计期间完成的。在我们的情况下,简单的分析导致我们想要保留以下与书籍相关的数据:

  • 国际标准图书编号(ISBN)

  • 标题

  • 页数

  • 作者识别

现在,对于我们的book表来说,拥有完整的列列表并不重要。我们将通过原型设计结构,然后稍后进行修改。在本章结束时,我们将添加第二个表author,其中包含有关每个作者的信息。

创建表

我们已经选择了我们的表名,并且知道了列的数量。我们在“创建表”对话框中输入这些信息,然后点击“Go”开始创建表。此时,列的数量是否完全知道并不重要,因为后续的面板将允许我们在创建表时添加列。

创建表

然后我们看到一个指定列信息的面板。因为我们要求四列,所以我们得到了四个输入行。每一行都指的是一个特定列的信息。下面的屏幕截图代表了这个面板的左侧:

创建表

接下来的内容代表右侧:

创建表

MySQL 文档解释了表和列名的有效字符(如果我们搜索“合法名称”)。这可能会根据 MySQL 版本而有所不同。通常,文件名中允许的任何字符(除了点和斜杠)在表名中都是可以接受的,名称的长度不能超过 64 个字符。列名也存在 64 个字符的限制,但我们可以使用任何字符。

我们在“列”列下输入我们的列名。每个列都有一个类型,最常用的类型位于下拉列表的开头。

当列的内容是字母数字时,VARCHAR(可变字符)类型被广泛使用,因为内容只会占用所需的空间。这种类型需要一个最大长度,我们需要指定。如果忘记这样做,当我们保存时会有一个小弹出消息提醒我们。对于页面计数和作者识别,我们选择了INT类型(整数),如下面的屏幕截图所示:

创建表

列还有其他属性,但在这个例子中我们将它们留空。您可能会注意到屏幕底部的“添加 1 列”对话框。我们可以使用它通过输入适当的值并点击“Go”来向这个创建表面板添加一些列。输入行的数量会根据新的列数而改变,但已经输入的关于前四列的信息不变。在保存页面之前,让我们定义一些键。

选择键

表通常应该有一个主键(具有唯一内容的列,代表每一行)。拥有主键对于行标识、更好的性能和可能的跨表关系是推荐的。在这里一个很好的值是 ISBN;因此,在索引对话框中,我们选择PRIMARY作为isbn列的索引类型。索引类型的其他可能性包括INDEX, UNIQUEFULLTEXT(在第五章中有更多关于此的内容)。

注意

索引管理(也称为键管理)可以在初始表创建时进行,也可以在Table视图的结构页面中进行。

为了提高我们将通过author_id进行的查询的速度,我们应该在该列上添加一个索引。我们屏幕右侧现在的样子如下截图所示:

选择键

此时,我们可以从相应的下拉菜单中选择不同的存储引擎。但是,目前我们将接受默认的存储引擎。

现在,我们点击保存来创建表。如果一切顺利,下一个屏幕将确认表已创建;我们现在位于当前数据库的结构页面。

选择键

book表的各种链接中,有些是不活跃的,因为如果其中没有行,则浏览或搜索表是没有意义的。

手动插入数据

既然我们有了一张表,让我们手动在其中插入一些数据。在这样做之前,这本书中有一些有用的关于数据操作的参考资料:

  • 第五章介绍了如何更改数据和结构,包括如何使用Function选择器

  • 第七章解释了如何从现有文件导入数据

  • 第九章解释了如何从其他表复制数据

  • 第十章介绍了关系系统(在我们的情况下,我们将要链接到author表)

现在,点击插入链接,这将带我们进入数据输入(或编辑)面板。该屏幕有空间可以输入两行信息,也就是说,在我们的示例中有两本书。这是因为$cfg['InsertRows']的默认值是2。在屏幕的下部,如果默认的行数不适合我们的需求,可以使用对话框继续插入 2 行。默认情况下,忽略复选框被选中,这意味着第二组输入字段将被忽略。一旦我们在该组的一个字段中输入一些信息并退出该字段,如果浏览器中启用了 JavaScript,则忽略框将自动取消选中。

我们可以为两本书输入以下示例信息:

  • ISBN:1-234567-89-0,标题:一百年的电影(第 1 卷),600 页,作者 ID:1

  • ISBN:1-234567-22-0,标题:未来的纪念品,200 页,作者 ID:2

列的宽度遵循字符列的最大长度。在这个例子中,我们将较低的下拉选择器保持为插入为新行的默认值。然后,我们点击Go来插入数据。在每组代表一行的列后面都有一个Go按钮,屏幕的下部也有一个。所有这些都有相同的效果,即保存输入的数据,但为了方便起见提供了这些按钮。

手动插入数据

如果我们的意图是在这两本书之后输入更多书的数据,我们将在点击Go之前从第二个下拉菜单中选择插入另一行。然后这将插入我们提供的数据并重新加载屏幕以插入更多数据。

CHAR 和 VARCHAR 的数据输入面板调整

默认情况下,phpMyAdmin 为CHARVARCHAR列类型显示单行输入字段。通过将$cfg['CharEditing']设置为'input'来控制。有时,我们可能希望在字段内插入换行符(新行)。这可以通过将$cfg['CharEditing']设置为'textarea'来实现。这是一个全局设置,将适用于此副本的所有用户的所有表的所有列。在此模式下,可以通过Enter键手动插入换行符,或者通过从屏幕上的其他源复制和粘贴文本行来完成。应用此设置将生成不同的插入屏幕,如下所示:

CHAR 和 VARCHAR 的数据输入面板调整

使用此输入模式,每个列的最大长度在视觉上不再适用。它将在插入时由 MySQL 强制执行。

浏览模式

有许多种方式可以进入这种模式。实际上,每次显示查询结果时都会使用这种模式。我们可以通过在导航面板上点击表名,或者在特定表的视图中点击浏览来进入这种模式。

浏览模式

SQL 查询链接

浏览结果中,显示的第一部分是查询本身,以及一些链接。显示的链接可能会根据我们的操作和一些配置参数而有所不同。

SQL 查询链接

以下几点描述了每个链接的功能:

  • 分析复选框在本章的分析查询部分中有详细介绍。

  • 内联链接允许将查询放入文本区域,而无需重新加载页面;然后可以编辑查询并执行新的查询。

  • 如果将$cfg['SQLQuery']['Edit']设置为TRUE,则会显示编辑链接。其目的是打开查询窗口,以便编辑此查询(有关详细信息,请参阅第十一章)。

  • 如果将$cfg['SQLQuery']['Explain']设置为TRUE,则会显示解释 SQL。我们将在第五章中看到此链接可以用于什么。

  • 可以点击创建 PHP 代码链接,将查询重新格式化为 PHP 脚本中预期的语法。然后可以直接复制并粘贴到我们正在工作的 PHP 脚本中需要查询的地方。请注意,点击后,此链接会更改为无 PHP 代码(如下截图所示),这将恢复正常的查询显示。如果将$cfg['SQLQuery']['ShowAsPHP']设置为TRUE,则此链接可用。

SQL 查询链接

  • 刷新用于再次执行相同的查询。结果可能会发生变化,因为 MySQL 服务器是多用户服务器,其他用户或进程可能正在修改相同的表。如果将$cfg['SQLQuery']['Refresh']设置为TRUE,则会显示此链接。

导航栏

导航栏显示在结果的顶部和底部。根据重复标题后字段中输入的值,列标题可以在结果中的某些间隔中重复显示。

导航栏

该栏使我们能够从一页导航到另一页,显示任意数量的行,从结果的某一点开始。通过点击浏览进入浏览模式,生成结果的基础查询包括整个表。但是,情况并非总是如此。

我们目前正在使用包含少量行的表。对于更大的表,我们可能会看到更完整的导航按钮集。为了模拟这种情况,让我们使用显示对话框将默认行数从30更改为1;然后点击显示。我们可以看到导航栏会自适应,如下截图所示:

导航栏

这一次,有标有<<, <, >>>的按钮,用于方便地访问结果的第一页、上一页、下一页和最后一页。这些按钮仅在必要时显示;例如,如果我们已经在第一页上,则不会显示第一页按钮。这些符号以这种方式显示,因为$cfg['NavigationBarIconic']的默认设置为TRUE。在这里的FALSE会产生诸如下一页结束的按钮,而'both'的值会显示> 下一页>> 结束

注意

请注意,$cfg['NavigationBarIconic']指令仅控制这些导航按钮的行为;其他按钮和链接(如编辑)由其他配置指令控制。

还有一个页码下拉菜单,可以直接转到靠近当前页的页面之一。由于可能有数百或数千页,因此该菜单保持较小,并包含常请求的页面:当前页面前后的几页,开头和结尾的几页,以及基于计算间隔的页面编号示例。

按设计,phpMyAdmin 始终尝试提供快速结果,实现此结果的一种方法是在SELECT中添加LIMIT子句。如果原始查询中已经有LIMIT子句,phpMyAdmin 将予以尊重。默认限制是 30 行,设置在$cfg['MaxRows']中。如果服务器上有许多用户,限制返回的行数有助于将服务器负载保持在最低水平。

导航栏上还有一个按钮,但必须通过将$cfg['ShowAll']设置为TRUE来激活。用户很容易会经常使用这个按钮。因此,在 phpMyAdmin 的多用户安装中,建议将按钮保持为其默认值禁用(FALSE)。启用时,导航栏将增加一个显示全部按钮。单击此按钮将检索当前结果集的所有行,这可能会达到 PHP 的执行时间限制或服务器的内存限制;当要求显示数千行时,大多数浏览器也会崩溃。可以安全显示的确切行数无法预测,因为它取决于列中实际存在的数据以及浏览器的功能。

注意

如果在显示 __ 行对话框中输入一个大数字,将会获得相同的结果(并且可能会面临相同的问题)。

查询结果操作

一个名为查询结果操作的部分位于结果下方。它包含打印结果的链接(带有或不带有FULL TEXT列),导出这些结果的链接(参考第六章中的导出部分查询结果部分),或者从此查询创建一个视图的链接(关于这一点在第十七章中有更多信息)。

显示数据为图表

另一个可用的操作是显示图表。为了练习这个,我们将使用一个选择只有两列的不同查询。为此,我们可以使用查询旁边显示的内联链接,并将查询更改为:

SELECT page_count, author_id from book

单击Go会生成一个只有这两列的结果集;接下来我们点击显示图表,会生成以下面板:

显示数据为图表

更多详细信息请参阅wiki.phpmyadmin.net/pma/Charts

排序结果

在 SQL 中,除非我们明确地对数据进行排序,否则我们无法确定数据检索的顺序。检索引擎的一些实现可能以与输入数据顺序相同的顺序显示结果,或者根据主键的顺序显示结果。然而,以明确排序的方式获取我们想要的结果是一种确定的方法。

当浏览结果显示时,可以单击任何列标题以对该列进行排序,即使它不是索引的一部分。让我们点击author_id列标题。

排序结果

我们可以确认排序已经发生,通过观察屏幕顶部的 SQL 查询;它包含一个ORDER BY子句。

现在我们在author_id标题旁边看到一个小三角形指向上方。这意味着当前的排序顺序是“升序”。将鼠标悬停在author_id标题上会使三角形改变方向,以指示如果再次点击标题会发生什么——按author_id值降序排序。

另一种排序的方法是按键排序。排序对话框显示了已经定义的所有键。在这里,我们看到一个名为PRIMARY的键——这是我们在创建时为isbn列检查Primary时给出的主键的名称:

排序结果

这可能是一次对多列进行排序的唯一方法(用于多列索引)。

初始排序顺序在$cfg['Order']中定义,使用ASC表示升序,DESC表示降序,或者SMART;后者是默认排序顺序,这意味着DATE, TIME, DATETIMETIMESTAMP类型的列将按降序排序,而其他列类型将按升序排序。

头词

因为我们可以更改页面上显示的行数,很可能我们看不到所有数据。在这种情况下,看到头词会有所帮助——关于显示数据的第一行和最后一行的指示。这样,您可以点击下一个上一个,而不必滚动到窗口底部。

然而,phpMyAdmin 应该基于哪一列生成头词?一个简单的假设已经被提出:如果您点击列标题表示您打算对该列进行排序,phpMyAdmin 将使用该列的数据作为头词。对于我们当前的book表,我们没有足够的数据来清楚地注意到这种技术的好处。然而,我们仍然可以看到排序后,屏幕顶部现在包含这条消息:

显示行 0 - 1(共 2 行,查询耗时 0.0006 秒)[author_id: 1 - 2]

在这里,方括号中的消息表示author_id编号1在第一行显示,编号2在最后一行显示。

颜色标记行或列

当鼠标在行之间移动(或在列标题之间移动)时,行(或列)的背景颜色可能会改变为$cfg['BrowsePointerColor']中定义的颜色。此参数可以在themes/<themename>/layout.inc.php中找到。要启用此功能,所有主题的浏览指针$cfg['BrowsePointerEnable']必须在config.inc.php中设置为TRUE(默认值)。

当我们在表中有许多列并且必须不断向左和向右滚动以读取数据时,可以有趣地标记一些行。另一个用途是突出一些行的重要性,以进行个人数据比较,或者向他人展示数据时。通过点击行来进行突出显示。再次点击会取消对行的标记。所选颜色由$cfg['BrowseMarkerColor'](参见themes/<themename>/layout.inc.php)定义。此功能必须通过在config.inc.php中将$cfg['BrowseMarkerEnable']设置为TRUE来启用。这将为所有主题设置该功能。我们可以标记多行。标记行还会激活该行的复选框。

颜色标记行或列

通过点击列标题(而不是列名本身)来标记列。

限制每列的长度

在前面的例子中,我们总是看到每列的完整内容,因为每列的字符数都在$cfg['LimitChars']定义的限制内。这是对所有非数字列强制执行的限制。如果这个限制很低(比如10),显示将如下所示:

限制每列的长度

这将帮助我们同时看到更多列(以减少每列的显示量)。

显示选项

为了看到完整的文本,我们现在将使用选项滑块,它会显示一些显示选项。所有这些选项将在涵盖相应概念的章节中进行解释。目前关注我们的选项是部分文本/完整文本对;我们可以选择完整文本来查看所有被截断的文本。即使我们选择不改变$cfg['LimitChars']参数,也会有一个时候要求完整文本会很有用(当我们使用TEXT列类型时——更多内容请参阅第五章)。

查看完整文本的更快方法是点击位于编辑删除图标正上方的大T。再次点击此T会将显示从完整切换到部分。

浏览不同的值

有一种快速的方法可以显示所有不同的值以及每个列值的出现次数。这个功能在表的结构页面上可用。例如,我们想知道我们的书表中有多少不同的作者,以及每个作者写了多少本书。在描述我们想要浏览的列(这里是author_id)的行上,我们打开更多菜单,然后点击浏览不同的值链接。

浏览不同的值

我们有一个有限的测试集,但仍然可以看到结果。

浏览不同的值

性能分析查询

在 MySQL 版本 5.0.37 和 5.1.28 中添加了性能支持。我们之前已经看到性能分析复选框出现在查询结果中。

当选中此框时,phpMyAdmin 将分析每个查询(包括当前查询),并显示有关每个 MySQL 内部操作的执行时间的报告,如下面的屏幕截图所示:

性能分析查询

尽管性能分析系统可以报告有关操作的其他信息(如 CPU 时间,甚至是内部服务器的函数名称),但 phpMyAdmin 目前只显示操作的名称和持续时间。

创建一个额外的表

在我们(简单)的设计中,我们知道我们需要另一个表——author表。author表将包含:

  • 作者识别

  • 全名

  • 电话号码

要创建此表,我们返回到marc_book数据库视图,并请求创建另一个具有如下屏幕截图所示的三列的表:

创建一个额外的表

使用创建第一个表时使用的相同技术,我们输入以下内容:

创建一个额外的表

由于我们只有三列或更少,显示现在处于垂直模式(有关更多详细信息,请参阅第五章中的垂直模式部分)。

列名id,它是我们新表中的主键,与book表中的author_id列相关联。保存表结构后,我们为作者 1 和 2 输入一些数据。为此,请发挥您的想象!

总结

本章解释了如何创建数据库和表,以及如何在表中手动输入数据。它还涵盖了如何通过使用浏览模式来确认数据的存在,其中包括 SQL 查询链接、导航栏、排序选项和行标记。

下一章将解释如何编辑数据行,并涵盖删除行、表和数据库的各个方面。

第五章:改变数据和结构

数据并不是静态的,它经常发生变化。本章重点介绍了编辑和删除数据以及其支持结构——表和数据库。

这一章分为两个主要部分。第一部分涵盖了改变数据的所有方面。首先我们会看到如何编辑数据,即如何进入编辑模式,如何一次编辑多行数据,以及如何从内联编辑中受益。接下来我们会看到如何删除数据行,以及如何删除表和数据库。

第二部分解释了如何修改表的结构。我们将介绍如何向表中添加列;然后我们将探讨各种列类型,如TEXT,BLOB,ENUM,DATEBIT列类型。最后,我们将介绍索引的管理。

改变数据

在本节中,我们将介绍编辑和删除数据的各种方法。

进入编辑模式

当我们浏览表或查看任何单表查询的搜索结果时,小图标和链接会出现在每个表行的左侧或右侧,如下面的截图所示:

进入编辑模式

可以使用铅笔形状的图标(编辑)来编辑行,使用红色图标(删除)来删除行。这些控件的确切形式和位置受以下因素的影响:

$cfg['PropertiesIconic'] = 'both';
$cfg['ModifyDeleteAtLeft'] = true;
$cfg['ModifyDeleteAtRight'] = false;

我们可以决定是在左侧显示它们,右侧显示它们,还是两侧都显示。$cfg['PropertiesIconic']参数可以有TRUE, FALSEboth的值。TRUE只显示图标,FALSE显示编辑,内联编辑,复制删除(或它们的翻译等效),both显示图标和文本,如前面的截图所示。

每一行旁边的小复选框在本章后面的多行编辑删除多行部分中有解释。

点击编辑图标或链接会带来以下面板,它与数据输入面板相似(除了下部分)。

进入编辑模式

在这个面板中,我们可以通过直接输入(或通过常规操作系统机制剪切和粘贴)来更改数据。我们也可以使用重置按钮恢复到原始内容。

默认情况下,下拉菜单设置为保存(以便我们对此行进行更改)和返回到上一页(以便我们可以继续编辑上一页结果页面上的另一行)。如果我们想要在点击Go后留在当前页面以保存然后继续编辑,我们可以选择返回到此页面。如果我们想要在保存当前行后插入另一行,我们只需在保存之前选择插入另一行插入为新行选项(在保存选项下方)在本章后面的复制数据行部分中有解释。

使用 Tab 键移动到下一个字段

喜欢使用键盘的人可以使用Tab键来进入下一个字段。通常情况下,光标从左到右,从上到下移动,所以它会进入Function列中的字段(稍后会详细介绍)。然而,为了方便在 phpMyAdmin 中导航数据,正常的导航顺序已经改变。Tab键首先通过Value列中的每个字段,然后通过Function列中的每个字段。

使用箭头移动

另一种在字段之间移动的方法是使用Ctrl + 箭头键。当屏幕上有许多字段时,这种方法可能比使用Tab键更容易。为了使其工作,$cfg['CtrlArrowsMoving']参数必须设置为true,这是默认值。

注意

在某些情况下,这种技术不能用于在字段之间移动。例如,Google Chrome 浏览器不支持Ctrl + 箭头。另外,在启用了 Spaces 的 Mac OS X 10.5 上,Ctrl + 箭头是在虚拟桌面之间切换的默认快捷键。

处理 NULL 值

如果表的结构允许在列中放置NULL值,那么在Null列中会出现一个小复选框。选择此复选框会在列中放置NULL值。每当在此列的Value中输入数据时,Null复选框会自动清除(这在启用 JavaScript 的浏览器中是可能的)。

在下面的屏幕截图中,我们修改了author表中phone列的结构,以允许NULL值(请参考本章的编辑列属性部分)。这里没有选择Null复选框:

处理 NULL 值

在选择Null框后,相应的数据被清除。

对值应用函数

MySQL 语言提供了一些函数,我们可以在保存之前应用到数据上。如果$cfg['ShowFunctionFields']设置为TRUE,则某些函数将出现在每个列旁边的下拉菜单中。

函数列表在$cfg['Functions']数组中定义。通常,这些数组的默认值位于libraries/config.default.php中。我们可以通过将所需的部分复制到config.inc.php中来更改它们。如果我们这样做,由于这些值可能会因版本而异,我们应该注意将我们的更改与新版本的值合并。某些数据类型的最常用函数首先显示在列表中。一些限制在$cfg['RestrictColumnTypes']$cfg['RestrictFunctions']数组中定义。

如下面的屏幕截图所示,我们可以在保存此行时将UPPER函数应用于title列,将标题转换为大写字符:

对值应用函数

为了节省一些屏幕空间,可以通过将$cfg['ShowFunctionFields']设置为FALSE来禁用此功能。此外,Function列标题是可点击的,因此我们可以即时禁用此功能。

当功能被禁用时,要么通过点击,要么通过配置参数,会出现一个“显示:功能”链接,以便在单击时显示这个“功能”列,如下面的屏幕截图所示:

对值应用函数

Type列标题也可以通过点击或配置$cfg['ShowFieldTypesInDataEditView']来使用类似的功能。

数据行的复制

在数据维护过程中(用于永久复制或测试目的),我们经常需要生成一行的副本。如果在同一表中进行此操作,我们必须遵守唯一键的规则。

这是一个行复制的例子。我们的作者写了关于电影的第 2 卷书。因此,需要稍作更改的列是 ISBN、标题和页数。我们将现有行显示在屏幕上,更改这三列,并选择插入为新行,如下面的屏幕截图所示:

数据行的复制

当我们点击Go时,将创建另一行,带有修改后的信息,原始行保持不变,如下所示:

数据行的复制

存在一个快捷链接来执行相同的操作。在浏览表时,点击特定行的复制会带来该行的编辑面板,并选择插入为新行而不是保存

多行编辑

多行编辑功能使我们能够在要编辑的行上使用复选框,并在With selected菜单中使用Change链接(或铅笔形图标)。Check All / Uncheck All链接也可以用于快速选中或取消选中所有复选框。我们还可以点击行数据的任何位置来激活相应的复选框。要选择一系列复选框,我们可以点击范围的第一个复选框,然后Shift + 点击范围的最后一个复选框。

多行编辑

单击更改后,出现包含所有选定行的编辑面板。在查看、比较和更改这些行的数据时,编辑过程可以继续进行。当我们用复选框标记一些行时,我们还可以对它们执行另外两个操作——删除(参见本章的删除多行部分)和导出(参见第六章))。

编辑下一行

在具有整数列上的主键的表上可以进行顺序编辑。我们的author表符合这些条件。让我们看看当我们开始编辑具有id1的行时会发生什么:

编辑下一行

编辑面板出现,我们可以编辑作者编号1。然而,在下拉菜单中,编辑下一行选项是可用的。如果选择了,下一个作者——第一个主键值大于当前主键值的作者——将可供编辑。

行内编辑

版本 3.4 引入了行内编辑,即在编辑时查看结果集的其他行。如果$cfg['AjaxEnable']设置为true,则可以使用config.inc.php或用户首选项。单击行的行内编辑显示以下对话框:

行内编辑

在编辑需要更改的列之后,我们单击保存。也可以使用隐藏链接中止更改。

删除数据

phpMyAdmin 的界面使我们能够删除以下数据:

  • 单行数据

  • 表的多行

  • 表中的所有行

  • 所有表中的所有行

删除单行

我们可以使用每行旁边的红色删除图标来删除行。如果$cfg['Confirm']的值设置为TRUE,则必须在执行之前确认每个 MySQL DELETE语句。这是默认设置,因为允许仅需一次点击即可删除行可能不明智!

确认的形式因浏览器执行 JavaScript 的能力而异。基于 JavaScript 的确认弹出窗将类似于以下截图:

删除单行

如果我们的浏览器已禁用 JavaScript,则会出现一个不同的面板。

实际的DELETE语句将使用所需的任何信息来确保仅删除预期的行。在我们的情况下,已定义了主键并在WHERE子句中使用了它。如果没有主键,将根据每列的值生成更长的WHERE子句。生成的WHERE子句甚至可能阻止DELETE操作的正确执行,特别是如果存在TEXTBLOB列类型。这是因为用于将查询发送到 Web 服务器的 HTTP 事务可能会受到浏览器或服务器的长度限制。这是另一个为什么强烈建议定义主键的原因。

删除多行

让我们假设我们检查了一页的行,并决定一些行必须被删除。与其逐个使用删除链接或图标删除它们,有时在检查一组行时必须做出删除决定,视图模式下的行旁边有复选框,如下面的截图所示:

删除多行

这些复选框与选择的菜单中的删除图标一起使用。确认屏幕将列出所有即将被删除的行。

删除表中的所有行

要完全删除表中的所有行(保持其结构不变),我们首先通过从导航面板中选择相关数据库来显示数据库结构页面。然后,我们使用与要清空的表位于同一行的清空图标或链接,如下所示:

删除表中的所有行

我们收到了确认TRUNCATE语句的消息(用于快速清空表的 MySQL 语句)。对于我们的练习,我们不会删除这些宝贵的数据!

注意

删除数据,无论是逐行删除还是清空表,都是永久性的操作。除非恢复备份,否则无法恢复。

删除多个表中的所有行

每个表名左侧都有一个复选框。我们可以选择一些表。然后,在选择的操作菜单中,选择清空操作,如下截图所示:

删除多个表中的所有行

当然,这个决定不能轻率地做出!

删除表

删除表会删除数据和表的结构。在数据库视图中,我们可以通过使用该表的红色删除图标来删除特定表。相同的机制也适用于删除多个表(使用下拉菜单和删除操作)。

删除数据库

我们可以通过转到服务器视图中的数据库页面,选择不需要的数据库旁边的复选框,然后点击删除链接来删除整个数据库(包括其所有表):

删除数据库

默认情况下,$cfg['AllowUserDropDatabase']设置为FALSE。因此,该面板不允许非特权用户删除数据库,直到手动将此设置更改为TRUE为止。

为了帮助我们三思而后行,在删除数据库之前会出现一个特殊的消息——您即将销毁一个完整的数据库!

注意

包含所有用户和权限定义的数据库mysql非常重要。因此,即使对于管理员来说,该复选框也被禁用。

更改表结构

在开发应用程序时,由于新的或修改后的需求,关于数据结构的要求经常发生变化。开发人员必须通过审慎的表结构编辑来适应这些变化。本节探讨了更改表结构的主题。具体来说,它展示了如何向现有表中添加列和编辑列的属性。然后,我们基于这些概念引入了更多专业的列类型,并通过 phpMyAdmin 解释了它们的处理。最后,我们将涵盖索引管理的主题。

添加列

假设我们需要一个新列来存储书籍的语言,并且默认情况下,我们保存数据的书籍是用英语写的。我们称该列为language,它将包含由两个字符组成的代码(默认为en)。

book表的视图的结构页面中,我们可以找到添加列对话框。在这里,我们指定要添加多少个新列,以及它们将放在哪里。

表中新列的位置只在开发者的角度上才重要。通常我们会逻辑地分组列,这样我们可以在列的列表中更容易地找到它们。列的确切位置不会影响预期结果(查询的输出),因为无论表结构如何,这些结果都可以进行调整。通常,最重要的列(包括键)位于表的开头。然而,这是个人偏好的问题。

我们想把新列放在表的末尾。因此,我们选中相应的单选按钮,然后点击执行

添加列

其他可能的选择是在表的开头之后(在这种情况下,我们必须从下拉菜单中选择新列应该放在哪个列之后)。

我们看到了输入列属性的熟悉面板。我们填写它。然而,由于这次我们想输入一个默认值,所以我们进行了以下两个操作:

  • 默认下拉菜单从更改为如定义:

  • 输入默认值:en

然后我们点击保存

添加列

垂直模式

前面的面板以垂直模式显示,因为$cfg['DefaultPropDisplay']的默认值为3。这意味着对于三列或更少,将使用垂直模式,对于三列以上,将自动选择水平模式。在这里,我们可以使用我们选择的数字。

如果我们将$cfg['DefaultPropDisplay']设置为'vertical',则添加新列的面板(以及编辑列结构的面板)将始终以垂直顺序呈现。此参数还可以取值'horizontal'以强制水平模式。

编辑列属性

结构页面上,我们可以对表进行进一步更改:

编辑列属性

此面板不允许对列进行所有可能的更改。它特别允许:

  • 使用特定列上的更改链接更改一个列的结构

  • 使用删除操作删除列

  • 向现有Primary键添加列

  • 在列上设置非唯一索引唯一索引

  • 设置FULLTEXT索引(仅当列类型允许时提供)

这些是一些可能在某些情况下有用的快速链接,但它们不能替代完整的索引管理面板。这两者都在本章中有解释。

我们可以使用复选框选择列。然后,使用适当的选择图标,我们可以使用更改编辑列,或者使用删除进行多列删除。全选/取消全选选项允许我们轻松地选中或取消选中所有框。

TEXT 列类型

我们现在将探讨如何使用TEXT列类型和相关配置值来调整最佳的 phpMyAdmin 行为。首先,我们向book表中添加一个名为descriptionTEXT列。

有三个配置指令控制在插入编辑模式下显示的TEXT列类型的文本区域的布局。每列的显示列数和行数由以下定义:

$cfg['TextareaCols'] = 40;
$cfg['TextareaRows'] = 15;

这默认情况下为TEXT列类型提供了工作空间,如下面的屏幕截图所示:

TEXT 列类型

设置只对文本区域施加了视觉限制,如果必要,浏览器会创建垂直滚动条。

注意

尽管MEDIUMTEXT、TEXTLONGTEXT列类型可以容纳超过 32 KiB 的数据,但某些浏览器并不总是能够使用 HTML 提供的文本区域进行编辑。事实上,实验已经说服了 phpMyAdmin 开发团队,如果内容大于 32 KiB,产品将显示警告消息。该消息警告用户内容可能无法编辑。

最后一个配置指令$cfg['LongtextDoubleTextarea']只对LONGTEXT列类型有影响。默认值为TRUE,可以使编辑空间加倍。

BLOB(二进制大对象)列类型

BLOB列类型通常用于保存二进制数据(如图像和声音),尽管 MySQL 文档暗示TEXT列类型也可以用于此目的。MySQL 5.1 手册中说:“在某些情况下,可能希望将媒体文件等二进制数据存储在 BLOB 或 TEXT 列中”。然而,另一句话:“BLOB 列被视为二进制字符串(字节字符串)”,似乎表明二进制数据应该真正存储在BLOB列中。因此,phpMyAdmin 的意图是使用BLOB列类型来保存所有二进制数据。

我们将在第十六章中看到,有特殊机制可进一步处理BLOB列类型,包括能够直接从 phpMyAdmin 中查看一些图像。

首先,我们向book表中添加一个名为cover_photoBLOB列类型。如果现在浏览表,我们可以看到每个BLOB列类型的长度信息[BLOB - 0B]

BLOB(二进制大对象)列类型

这是因为Show BLOB显示选项(还记得选项滑块吗?)默认情况下没有复选标记。因此,它阻止在浏览模式下显示BLOB内容。这种行为是有意的。通常,我们无法对以纯文本表示的二进制数据执行任何操作。

上传二进制内容

如果我们编辑一行,我们会看到Binary do - not edit警告和一个浏览…按钮。这个按钮的确切标题取决于浏览器。尽管不允许编辑,但我们可以轻松地将文本或二进制文件的内容上传到这个blob列中。

让我们使用浏览按钮选择一个图像文件,例如位于客户端工作站上的phpMyAdmin/themes/pmahomme/img目录的测试副本中的logo_left.png文件。现在点击Go

上传二进制内容

我们需要记住一些上传大小的限制。首先,blob列的大小限制为 64 KiB,但在第十六章中,我们将更改此列的类型以容纳更大的图像。因此,phpMyAdmin 通过Max: 64KiB警告提醒我们这一限制。此外,PHP 本身可能存在限制(有关更多详细信息,请参阅第七章)。我们现在已经在特定行中上传了一张图片。

上传二进制内容

我们注意到BLOB - 4.9KiB是一个链接;如果需要,它允许我们下载任何二进制数据到我们的工作站。

如果我们为Show BLOB Contents显示选项打上复选标记,我们现在在BLOB列类型中看到以下内容:

上传二进制内容

注意

要真正在 phpMyAdmin 中查看图像,请参阅第十六章。

$cfg['ProtectBinary']参数控制编辑二进制列(BLOB和任何其他带有binary属性的列)时可以做什么。默认值blob阻止编辑BLOB列,但允许我们编辑 MySQL 标记为binary的其他列。值为all将甚至阻止编辑binary列。值为FALSE将不保护任何内容,因此允许我们编辑所有列。如果我们选择最后一个选项,我们会在此行的编辑面板中看到以下内容:

上传二进制内容

这个BLOB列类型的内容已经转换为十六进制,并且默认选择了UNHEX函数。我们可能不想以十六进制编辑这个图像数据,但这是在屏幕上安全表示二进制数据的最佳方式。这种十六进制表示的原因是,Show binary contents as HEX display选项(在浏览模式下)目前被标记。但我们没有标记这个选项;它被选中是因为$cfg['DisplayBinaryAsHex']指令默认为TRUE

如果我们决定不标记这个选项,我们将看到这个图像的纯二进制数据:

上传二进制内容

这可能不是我们最喜欢的图像编辑器!实际上,即使我们在不触及BLOB列类型的情况下保存这一行,数据也可能会损坏。但是,将$cfg['ProtectBinary']设置为FALSE的可能性是存在的,因为一些用户在他们的BLOB列中放置文本,并且他们需要能够修改这些文本。这就是为什么 phpMyAdmin 可以配置为允许编辑BLOB列。

MySQL 的BLOB数据类型实际上与它们对应的TEXT数据类型类似。但是,我们应该记住BLOB没有字符集,而TEXT列类型有一个影响排序和比较的字符集。

ENUM 和 SET 列类型

ENUMSET列类型都旨在表示可能的值列表。区别在于用户可以从定义的值列表中选择一个值,ENUM,和使用SET可以选择多个值。对于SET,所有多个值都放入一个单元格;但是多个值并不意味着创建多行数据。

我们在book表中添加了一个名为genre的列,并将其定义为ENUM。目前,我们选择在值列表中放入简短的代码,并将其中一个值F作为默认值,如下面的屏幕截图所示:

ENUM and SET column types

在值列表中,我们必须将每个值用单引号括起来,与默认值字段不同。从 3.4.0 版本开始,针对ENUM/SET列的编辑器可用。使用此编辑器,我们无需费心将值用单引号括起来。单击获取更多编辑空间即可启用此编辑器:

ENUM and SET column types

在我们的设计中,这些值代表幻想,儿童小说。但是,目前,我们希望看到界面对简短代码的行为。在插入面板中,我们现在看到一个单选框界面,如下面的屏幕截图所示:

ENUM and SET column types

如果我们决定有更多自描述的值,我们可以回到结构模式,并更改genre列的值定义。我们还必须将默认值更改为可能的值之一,以避免在尝试保存此列结构修改时收到错误消息。

ENUM and SET column types

使用修改后的值列表,插入面板现在如下所示:

ENUM and SET column types

请注意,单选按钮已被下拉列表取代,因为可能的值长度更大。

如果我们想要选择多个可能的值,我们必须将列类型更改为SET。可以使用相同的值列表。但是,使用浏览器的多值选择器(在 Windows 或 Linux 桌面上按住 Ctrl 键单击,在 Mac 上按住 Command 键单击),我们可以选择多个值,如屏幕截图所示:

ENUM and SET column types

注意

在规范化的数据结构中,我们只会在book表中存储genre代码,并依赖另一个表来存储每个代码的描述。在这种情况下,我们将不使用SETENUM

DATE,DATETIME 和 TIMESTAMP 列类型

我们可以使用普通字符列来存储日期或时间信息。但是DATE,DATETIMETIMESTAMP对于此目的更有效。MySQL 检查内容以确保有效的日期和时间信息,并提供特殊函数来处理这些列。

日历弹出

作为额外的好处,phpMyAdmin 提供了一个日历弹出,方便数据输入。

我们将首先在book表中添加一个DATE列类型—date_published—。如果我们进入插入模式,现在应该会看到新列,我们可以在其中输入日期。还有一个日历图标可用。此图标会带来一个弹出窗口,与此DATE列类型同步。如果列中已经有值,则相应地显示弹出窗口。在我们的情况下,列中没有值,因此日历显示当前日期,如下面的屏幕截图所示:

日历弹出

小箭头方便地滚动月份和年份。点击我们想要的日期,将其传输到我们的date_published列。对于DATETIMETIMESTAMP列类型,弹出窗口提供了编辑时间部分的功能。

注意

如果我们输入日期或时间值,如果我们的浏览器启用了 JavaScript,则会进行验证;不正确的值会用红色突出显示。

时间戳选项

从 MySQL 4.1.2 开始,有更多选项可以影响TIMESTAMP列类型。让我们在book表中添加一个名为stampTIMESTAMP类型的列。在默认下拉菜单中,我们可以选择CURRENT_TIMESTAMP;但是对于此练习,我们不会这样做。但是,在属性列中,我们选择on update CURRENT_TIMESTAMP。更多详细信息,请参阅dev.mysql.com/doc/refman/5.5/en/timestamp.html

TIMESTAMP 选项

位列类型

MySQL 5.0.3 引入了真正的位列。它们在数据库中占用的空间与其定义中的位数相同。假设我们对每本书有以下三个信息,并且每个信息只能是真(1)或假(0):

  • 书是精装

  • 书中包含 CD-ROM

  • 书只有电子版可用

我们将使用一个单个BIT列来存储这三个信息。因此,我们在book表中添加一个长度为3(即 3 位)的列:

位列类型

为了构造并随后解释我们存储在此列中的值,我们必须以二进制方式思考,尊重列内每个位的位置。要指示一本书是精装,不包含 CD-ROM,并且仅以电子版形式提供,我们将使用值101

phpMyAdmin 以二进制方式处理BIT列。例如,如果我们编辑一行并将值101设置为some_bits列的值,那么在保存时将发送以下查询:

UPDATE `marc_book`.`book` SET `some_bits` = b '101' 
WHERE `book`.`isbn` = '1-234567-89-0' LIMIT 1;

查询的突出部分显示该列实际上接收到了一个二进制值。在浏览时,精确值(在十进制中为5 ——对于我们的目的来说是一个无意义的值)以其二进制形式101重新显示,这有助于解释每个离散的位值。有关位值表示法的更多详细信息,请参阅dev.mysql.com/doc/refman/5.5/en/bit-type.html

管理索引

正确维护的索引对于数据检索速度至关重要。phpMyAdmin 具有许多索引管理选项,将在本节中介绍。

单列索引

我们已经看到结构面板通过一些链接(如添加主键、添加索引添加唯一索引)提供了快速创建单列索引的方法。在列列表下方,有一个可用于管理索引的界面部分:

单列索引

此部分有链接可编辑或删除每个索引。在这里,部分每个索引只列出一个列,我们可以看到整个列参与索引。这是因为在每个列名后面没有大小信息,与我们下一个示例中将看到的情况相反。

现在我们将在标题上添加一个索引。但是,我们希望限制此索引的长度,以减少磁盘上索引结构使用的空间。在 1 列上创建索引选项是合适的。因此,我们点击Go。在下一个屏幕中,我们指定索引详细信息如下:

单列索引

我们在此面板的选项中填写以下信息:

  • 索引名称:我们发明的描述此索引目的的名称

  • 索引类型:我们可以选择INDEX

  • 列:我们选择用作索引的列,即title

  • 大小:我们输入30而不是 100(列的完整长度),以节省表的物理部分中保存索引数据的空间

保存此面板后,我们可以从以下屏幕截图中确认索引已创建,并且不覆盖title列的整个长度:

单列索引

多列索引和索引编辑

在下一个示例中,我们假设在将来的应用程序中,我们将需要找到特定作者写的特定语言的书。将author_id索引扩展,添加language列到其中是有意义的。

我们点击包含author_id索引的行上的Edit链接(小铅笔图标),这将显示此索引的当前状态。界面上有空间可以向此索引添加另一列。如果需要添加多于一列,我们可以使用Add to index 1 column(s)功能。在选择器中,我们选择language。这次我们不需要输入大小,因为整个列将被用于索引。为了更好的文档记录,我们更改Index name (author_language 为适当的名称,如下图所示:

多列索引和索引编辑

我们保存这个索引修改。在索引列表中,我们可以确认我们的索引修改。

全文索引

这种特殊类型的索引允许进行全文搜索。它仅支持MyISAM表的VARCHARTEXT列类型,但 MySQL 5.6 也应该为InnoDB提供此功能。我们可以在列列表中使用Add FULLTEXT index链接,或者转到索引管理面板,并在下拉菜单中选择FULLTEXT

使用 EXPLAIN 优化索引

在这一部分,我们想要获取有关 MySQL 用于特定查询的索引以及没有定义索引的性能影响的一些信息。

假设我们想使用以下查询:

SELECT *
FROM `book`
WHERE author_id = 2 AND language = 'es'

我们想知道,哪些由id2的作者写的书是用es语言——我们的西班牙语的代码。

要输入此查询,我们可以使用数据库或表菜单中的SQL选项卡,或者 SQL 查询窗口(参见第十一章)。我们在查询框中输入此查询,然后点击Go。目前查询是否找到任何结果并不重要。

注意

您可以通过按照第八章中的解释来获得相同的查询,以便搜索author_id 2和语言es

使用 EXPLAIN 优化索引

我们现在将使用[Explain SQL]链接来获取有关此查询使用了哪个索引(如果有的话)的信息。

使用 EXPLAIN 优化索引

我们可以看到EXPLAIN命令已经传递给 MySQL,告诉我们使用的keyauthor_language。因此,我们知道这个索引将用于这种类型的查询。如果这个索引不存在,结果将会有很大不同。

使用 EXPLAIN 优化索引

这里,key (NULL)type (ALL) 意味着没有使用索引,需要检查所有行以找到所需的数据。根据总行数的不同,这可能会严重影响性能。我们可以通过检查 phpMyAdmin 在每个结果页面上显示的查询时间 (Query took x sec) 来确定确切的影响,并将其与有无索引进行比较。然而,如果我们只有有限的测试数据,与生产中的真实表相比,时间上的差异可能是微不足道的。有关EXPLAIN输出格式的更多详细信息,请参阅dev.mysql.com/doc/refman/5.5/en/explain-output.html

检测索引问题

为了帮助用户维护最佳的索引策略,phpMyAdmin 尝试检测一些常见的索引问题。例如,让我们访问book表并在isbn列上添加一个索引。当我们显示这个表的结构时,我们会得到如下截图所示的警告:

检测索引问题

这里的意图是在考虑整个表时警告我们关于索引结构的低效性。我们不需要在同一列上有两个索引。

总结

本章讨论了数据更改的概念,例如:

  • 编辑数据

  • 包括NULL列和使用Tab

  • 对值应用函数

  • 复制数据行

  • 删除数据、表和数据库

我们还概述了结构更改技术,例如:

  • 如何添加列,包括特殊的列类型,如 TEXT、BLOB、ENUM 和 SET

  • 如何使用日历弹出窗口来处理 DATE、DATETIME 和 TIMESTAMP 列类型

  • 如何将二进制数据上传到 BLOB 列

  • 如何管理索引(多列和全文),并从 MySQL 获取关于特定查询中使用了哪些索引的反馈

在下一章中,我们将学习如何导出表的结构和数据以备份,或者用作连接到另一个应用程序的网关。

第六章:导出结构和数据(备份)

保持良好的备份对于项目至关重要。备份包括最新的备份和在开发和生产阶段进行的中间快照。phpMyAdmin 的导出功能可以生成备份,并且还可以用于将数据发送到其他应用程序。

注意

请注意,phpMyAdmin 的导出功能可以按需生成备份,强烈建议实施自动和脚本化的备份解决方案,定期进行备份。实施这样的解决方案的确切方式取决于服务器的操作系统。

转储,备份和导出

让我们首先澄清一些词汇。在 MySQL 文档中,您会遇到术语dump,在其他应用程序中是备份导出。在 phpMyAdmin 上下文中,所有这些术语都具有相同的含义。

MySQL 包括mysqldump-一个命令行实用程序,可用于生成导出文件。但并非每个主机提供商都提供命令行实用程序所需的 shell 访问权限。此外,从 Web 界面中访问导出功能更加方便。这就是为什么 phpMyAdmin 提供了比 mysqldump 更多导出格式的导出功能。本章将重点介绍 phpMyAdmin 的导出功能。

在开始导出之前,我们必须清楚地了解导出的预期目标。以下问题可能有所帮助:

  • 我们需要完整的数据库还是只需要一些表?

  • 我们只需要结构,只需要数据,还是两者都需要?

  • 将使用哪个实用程序来导入数据?

  • 我们只需要数据的子集吗?

  • 预期导出的大小是多少,我们和服务器之间的链接速度是多少?

导出的范围

当我们从 phpMyAdmin 点击导出链接时,我们可能处于以下视图或上下文之一-数据库视图,视图或服务器视图(稍后在[第十九章]中更多了解此内容))。根据当前上下文,导出的范围将是完整的数据库,单个表,甚至是多个数据库,如服务器视图的情况。我们将首先解释数据库导出和所有相关的导出类型。然后我们将继续表和多数据库导出,强调这些导出模式的区别。

导出数据库

数据库视图中,点击导出链接。自 3.4.0 版本以来,默认的导出面板如下截图所示:

导出数据库

默认情况下,$cfg['Export']['method']设置为'quick'$cfg['Export']['format']设置为'sql'。可用性测试表明,导出的最常见目标是以 SQL 格式生成完整的备份并将其保存在我们的工作站上;只需点击Go即可完成。

$cfg['Export']['method']的其他值是'custom',它将显示详细的导出选项,以及'custom-no-form',它也会显示详细选项,但不会显示选择快速导出的可能性-这是 3.4.0 版本之前的行为。

在自定义模式下,会显示子面板。表,输出格式子面板占据页面顶部。特定格式选项子面板会变化,以显示所选择的导出格式的选项。以下截图显示了 SQL 格式面板:

导出数据库

表子面板

该子面板包含一个表选择器,我们可以从中选择要导出的表。默认情况下,所有表都被选中,我们可以使用全选/取消全选链接来更改我们的选择。

输出子面板

默认行为是通过 HTTP 传输导出文件(选择将输出保存到文件单选按钮)。这会触发浏览器中的保存对话框,最终将文件保存在我们的本地机器上。另一种选择是选择以文本形式查看输出,这可以作为测试过程,前提是导出的数据是合理大小。

文件名模板

建议文件的名称将遵循文件名模板字段。在此模板中,我们可以使用特殊的@SERVER@、@DATABASE@@TABLE@占位符。这些占位符将被当前服务器、数据库或表名(对于单表导出)替换。请注意,在这些单词之前和之后都有一个"at sign"字符。我们还可以使用 PHP strftime函数中的任何特殊字符;这对于根据当前日期或小时生成导出文件非常有用。最后,我们可以放置任何其他字符串(不是strftime特殊字符的一部分),这些字符串将被文字使用。文件扩展名根据导出类型生成。在这种情况下,它将是.sql。以下是模板的一些示例:

  • @DATABASE@将生成marc_book.sql

  • @DATABASE@-%Y%m%d将给出marc_book-20110920.sql

激活将来用于导出选项会将输入的模板设置存储到 cookie 中(用于数据库、表或服务器导出),并在下次使用相同类型的导出时将它们带回来。

默认模板是可配置的,通过以下参数:

$cfg['Export']['file_template_table'] = '@TABLE@';
$cfg['Export']['file_template_database'] = '@DATABASE@';
$cfg['Export']['file_template_server'] = '@SERVER@';

可能的占位符,如@DATABASE@与窗口标题中使用的占位符相同,并在Documentation.html,FAQ 6.27 中描述。

选择字符集

我们可以为导出的文件选择确切的字符集。phpMyAdmin 会验证重新编码的条件是否满足。对于实际的数据重新编码,Web 服务器的 PHP 组件必须支持iconvrecode模块。$cfg['RecodingEngine']参数指定实际的重新编码引擎,选择包括none, auto, iconvrecode。如果设置为auto,phpMyAdmin 将首先尝试iconv模块,然后尝试recode模块。如果设置为none,字符集对话框将不会显示。

汉字支持

如果 phpMyAdmin 检测到使用日语,它会检查 PHP 是否支持mb_convert_encoding()多字节字符串函数。如果支持,导出和导入页面以及查询框上会显示额外的单选按钮,这样我们就可以在EUC-JPSJIS日语编码之间进行选择。

以下是从导出页面中获取的示例:

Kanji support

压缩

为了节省传输时间并获得更小的导出文件,phpMyAdmin 可以压缩为 ZIP、GZIP 或 BZIP2 格式。只有在 PHP 服务器编译时分别使用了--with-zlib(用于 ZIP 和 GZIP)或--with-bz2(用于 BZ2)配置选项,才会提供这些格式。以下参数控制在面板中呈现哪些压缩选项:

$cfg['ZipDump'] = TRUE;
$cfg['GZipDump'] = TRUE;
$cfg['BZipDump'] = TRUE;

安装 phpMyAdmin 的系统管理员可以选择将所有这些参数设置为FALSE,以避免大量用户同时压缩其导出所带来的潜在开销。这种情况通常比所有用户同时传输未压缩文件带来更多的开销。

在较旧的 phpMyAdmin 版本中,压缩文件是在 Web 服务器内存中构建的。由此引起的一些问题包括:

  • 文件生成取决于分配给运行 PHP 脚本的内存限制。

  • 在生成和压缩文件的过程中,没有传输发生。因此,用户倾向于认为操作没有进行,或者发生了崩溃。

  • 大型数据库的压缩是不可能实现的。

$cfg['CompressOnFly']参数(默认设置为TRUE)被添加以生成(对于 GZIP 和 BZIP2 格式)一个包含更多标头的压缩文件。现在,传输几乎立即开始。文件以较小的块发送,因此整个过程消耗的内存要少得多。这样做的缺点是生成的文件稍微更大。

导出格式

我们现在将讨论可以在格式子面板中选择的格式(以及选择后可用的选项)。

注意

即使我们可以导出多种格式,但只有其中一些格式可以使用 phpMyAdmin 导入。

SQL

SQL 格式很有用,因为它创建了标准的 SQL 命令,可以在任何 SQL 服务器上运行。

如果选中显示注释复选框,则导出文件中将包含注释。导出的第一部分包括注释(以--字符开头),详细说明了创建文件的实用程序(和版本),日期和其他环境信息。然后我们看到每个表的CREATEINSERT查询。

phpMyAdmin 在导出文件中生成与 ANSI 兼容的注释。这些注释以--开头。它们有助于在其他 ANSI SQL 兼容系统上重新导入文件。

SQL 选项用于定义导出将包含的确切信息。下面的屏幕截图显示了一般的 SQL 选项:

SQL

一般的 SQL 选项有:

  • 附加自定义头注释:我们可以为此导出添加自己的注释(例如,每月备份),这些注释将显示在导出标头中(在 PHP 版本号之后)。如果注释有多行,我们必须使用特殊字符\n来分隔每一行。

  • 显示外键关系:在第十章中,我们将看到即使是在MyISAM存储引擎下的表,也可以定义关系;此选项将导出这些关系的定义作为注释。这些不能直接导入,但作为可读的表信息仍然很有价值。

  • 显示 MIME 类型:这会添加信息(以 SQL 注释的形式),描述哪些 MIME 类型已与列关联。第十六章进一步解释了这一点。

  • 将导出封装在事务中:从 MySQL 4.0.11 开始,我们可以使用START TRANSACTION语句。这个命令与在开头使用SET AUTOCOMMIT=0和在结尾使用COMMIT结合在一起,要求 MySQL 在一个事务中执行导入(当我们重新导入此文件时),确保所有更改都作为一个整体完成。

  • 禁用外键检查:在导出文件中,我们可以添加DROP TABLE语句。但是,通常如果表在外键约束中被引用,就无法删除该表。此选项通过在导出文件中添加SET FOREIGN_KEY_CHECKS=0来覆盖验证。此覆盖仅在导入的持续时间内有效。

  • 数据库系统或旧的 MySQL 服务器以最大化输出兼容性:这让我们选择要导出的 SQL 的类型。我们必须了解我们打算导入此文件的系统。选择包括MySQL 3.23,MySQL 4.0,ORACLEANSI

我们可能想要导出结构、数据或两者;这是通过转储表选项执行的。选择结构会生成包含CREATE查询的部分,选择数据会生成INSERT查询。

如果我们选择结构,则会出现对象创建选项子面板,如下面的屏幕截图所示:

SQL

结构选项有:

  • 添加 DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT: 在每个CREATE语句之前添加DROP ... IF EXISTS语句,例如DROP TABLE IF EXISTS author``;。这样,我们可以确保导出文件在已经存在相同元素的数据库上执行,更新其结构但销毁先前元素的内容。

  • 添加 CREATE PROCEDURE / FUNCTION / EVENT: 这包括在此数据库中找到的所有存储过程、函数和事件定义,在导出中包含它们。

  • 创建表选项/如果不存在:IF NOT EXISTS修饰符添加到CREATE TABLE语句中,避免在表已经存在时导入时出现错误。

  • 创建表选项/自动增量: 将表中的自动增量信息放入导出中,确保表中插入的行将获得下一个确切的自动增量 ID 值。

  • 用反引号括起表名和字段名: 在 MySQL 世界中,反引号是保护可能包含特殊字符的表和列名的常规方式。在大多数情况下,这是有用的。但是,如果目标服务器(导出文件将被导入的地方)运行不支持反引号的 SQL 引擎,则不建议使用反引号。

以下屏幕截图显示了与数据导出相关的选项:

SQL

数据部分提供的选项包括:

  • INSERT DELAYED 语句:DELAYED修饰符添加到INSERT语句中。这会加速INSERT操作,因为它被排队到服务器,服务器在表不在使用时执行它。这是 MySQL 的非标准扩展,仅适用于MyISAM,MEMORYARCHIVE表。

  • INSERT IGNORE 语句: 通常,在导入时,我们不能为唯一键插入重复的值,因为这会中止插入操作。此选项将IGNORE修饰符添加到INSERTUPDATE语句中,从而跳过生成重复键错误的行。

  • 在转储数据时使用的函数: 选择有INSERT,UPDATEREPLACE。其中最著名的是默认的INSERT—使用INSERT语句导入我们的数据。但是,在导入时,我们可能会遇到这样的情况:表已经存在并包含有价值的数据,我们只想更新当前导出表中的列。UPDATE生成类似下面这行代码的语句,在找到相同的主键或唯一键时更新一行:

UPDATE `author` SET `id` = 1, `name` = 'John Smith', `phone` = '111-1111' WHERE `id` = '1';

第三种可能性,REPLACE,生成诸如REPLACE INTO author VALUES (1, 'John Smith', '111-1111');的语句。这类似于对新行进行插入操作,并根据主键或唯一键更新现有行。

  • 插入数据时使用的语法: 这里有几种选择。在每个语句中包含列名会使生成的文件更大,但在各种 SQL 系统上更具可移植性,并且更易于文档化。使用一个语句插入多行比使用多个INSERT语句更快,但不太方便,因为它使得读取结果文件更加困难。它还会生成一个较小的文件,但是该文件的每一行本身都不可执行,因为每一行都没有INSERT语句。如果无法在一次操作中导入完整的文件,则无法使用文本编辑器拆分文件并逐块导入。

  • 创建查询的最大长度:扩展插入生成的单个INSERT语句可能会变得太大并引起问题。因此,我们为此语句的长度设置了字符数的限制。

  • 以十六进制表示法转储二进制列:此选项使 phpMyAdmin 以0x格式对BLOB列的内容进行编码。这种格式很有用,因为根据将用于处理导出文件的软件(例如文本编辑器或邮件程序),处理包含 8 位数据的文件可能会有问题。但是,使用此选项将产生大小为原始大小两倍的BLOB列类型的导出。

  • 在 UTC 中转储时间戳列:如果导出文件将被导入到位于不同时区的服务器上,则这将很有用。

CSV

这种格式被许多程序理解,您可能会发现它在交换数据时很有用。请注意,这是一种仅包含数据的格式——这里没有 SQL 结构。

CSV

可用的选项有:

  • 用逗号分隔的列:我们在这里放一个逗号,这意味着每个列后面都会放一个逗号。默认值来自$cfg['Export']['csv_separator']

  • 用以下字符包围的列:我们在这里放一个包围字符(双引号),以确保不会将包含终止字符(逗号)的列视为两列。默认值来自$cfg['Export']['csv_enclosed']

  • 用以下字符转义的列:如果导出生成器在列中找到用以下字符包围字符,那么该字符将被放在它之前以保护它。例如,"John \"The Great\"Smith"。默认值来自$cfg['Export']['csv_escaped']

  • 以以下字符结尾的行:这决定了每行的结束字符。我们应该根据将操作结果导出文件的操作系统使用适当的行分隔符。此选项的默认值来自$cfg['Export']['csv_terminated']参数,默认情况下包含'AUTO''AUTO'值会在浏览器的操作系统为 Windows 时产生值\r\n,否则产生值\n。但是,如果导出文件打算用于具有不同操作系统的机器,则这可能不是最佳选择。

  • 用以下字符串替换 NULL:这确定了在导出文件中找到任何NULL值的列中占据位置的字符串。

  • 删除列中的回车/换行字符:由于列可能包含回车或换行字符,这将确定是否应从导出的数据中删除这些字符。

  • 将列名放在第一行:这会获取有关每列含义的一些信息。一些程序将使用此信息来命名列。在这个练习中,我们选择了这个选项。

最后,我们选择author表。

点击Go会生成一个包含以下行的文件:

"id","name","phone"
"1","John Smith","+01 445 789-1234"
"2","Maria Sunshine","+01 455 444-5683"

Microsoft Excel 的 CSV

这种导出模式生成了一个专门为 Microsoft Excel 格式化的 CSV 文件(使用分号而不是逗号)。我们可以选择确切的 Microsoft Excel 版本,如下面的屏幕截图所示:

Microsoft Excel 的 CSV

PDF

通过导出为 PDF,可以创建表的 PDF 报告。此功能始终会生成一个文件。自 phpMyAdmin 3.4.7 以来,我们还可以一次性导出完整数据库或多个表。我们可以为此报告添加标题,并且它也会自动分页。在这种导出格式中,book表中的非文本(BLOB)数据将被丢弃。

在这里,我们在author表上进行测试,要求使用"The authors"作为标题。PDF 很有趣,因为它固有的矢量性质——结果可以被放大。让我们来看一下从 Adobe Reader 中看到的生成的报告:

PDF

Microsoft Word 2000

这种导出格式直接生成一个适用于所有理解 Word 2000 格式的软件的.doc文件。我们发现与 Microsoft Excel 导出中类似的选项,还有一些其他选项。我们可以独立导出表的结构数据

Microsoft Word 2000

请注意,对于这种格式和 Excel 格式,我们可以选择多个表进行一次导出。但是,如果其中一个表具有非文本数据,将会出现不愉快的结果。以下是author表格的结果:

Microsoft Word 2000

LaTeX

LaTeX是一种排版语言。phpMyAdmin 可以生成一个代表表的结构和/或数据的.tex文件,以横向表格的形式呈现。

注意

请注意,这个文件不能直接查看,必须进一步处理或转换为预期的最终媒体。

可用的选项有:

选项 描述
包括表标题 在表格输出中显示标题
结构数据 请求结构、数据或两者的熟悉选择
表标题 要放在第一页上的标题
表标题(继续) 要放在每一页上的标题
显示外键关系、注释、MIME 类型 我们希望作为输出的其他结构信息。如果 phpMyAdmin 配置存储已经就位,这些选择是可用的

XML

这种格式在数据交换中非常流行。我们可以选择要导出的数据定义元素(如函数、过程、表、触发器或视图)。接下来是author表格的输出。

<?xml version="1.0" encoding="utf-8"?>
<!--
- phpMyAdmin XML Dump
- version 3.4.5
- http://www.phpmyadmin.net
-
- Host: localhost
- Generation Time: Sep 16, 2011 at 03:18 PM
- Server version: 5.5.13
- PHP Version: 5.3.8
-->
<pma_xml_export version="1.0" >
<!--
- Structure schemas
-->
<pma:structure_schemas>
<pma:database name="marc_book" collation="latin1_swedish_ci" charset="latin1">
<pma:table name="author">
CREATE TABLE `author` (
`id` int(11) NOT NULL,
`name` varchar(30) NOT NULL,
`phone` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
</pma:table>
</pma:database>
</pma:structure_schemas>
<!--
- Database: 'marc_book'
-->
<database name="marc_book">
<!-- Table author -->
<table name="author">
<column name="id">1</column>
<column name="name">John Smith</column>
<column name="phone">+01 445 789-1234</column>
</table>
<table name="author">
<column name="id">2</column>
<column name="name">Maria Sunshine</column>
<column name="phone">333-3333</column>
</table>
</database>
</pma_xml_export>

打开文档电子表格

这种电子表格格式是开放文档(en.wikipedia.org/wiki/OpenDocument)的一个子集,它在OpenOffice.org办公套件中非常流行。我们需要选择一个要导出的表,以便有一个连贯的电子表格。以下截图显示了我们的author表格,导出为名为author.ods的文件,并随后在 OpenOffice 中查看:

打开文档电子表格

打开文档文本

这是开放文档标准的另一个子集,这次是面向文本处理的。我们的author表格现在已经从 OpenOffice 中导出并查看。

打开文档文本

YAML

YAML代表YAML 不是标记语言。YAML 是一种人类可读的数据序列化格式;它的官方网站是www.yaml.org。这种格式在 phpMyAdmin 中没有我们可以选择的选项。以下是author表格的 YAML 导出:

1:
id: 1
name: John Smith
phone: +01 445-789-1234
2:
id: 2
name: Maria Sunshine
phone: 333-3333

CodeGen

这个选择可能有一天会支持与代码开发相关的许多格式。目前,它可以导出 NHibernate 对象关系映射(ORM)格式。更多详情,请参阅en.wikipedia.org/wiki/Nhibernate

Texy!文本

Texy!是一个带有自己简化语法的格式化工具(texy.info/en/)。以下是以这种格式导出的示例代码:

===Database marc_book
== Table structure for table author
|------
|Field|Type|Null|Default
|------
|//**id**//|int(11)|Yes|NULL
|name|varchar(30)|Yes|NULL
|phone|varchar(30)|Yes|NULL
== Dumping data for table author
|1|John Smith|+01 445 789-1234
|2|Maria Sunshine|333-3333

PHP 数组

在 PHP 中,关联数组可以保存文本数据;因此,可以使用 PHP 数组导出格式。以下是author表格的 PHP 数组导出:

<?php
// marc_book.author
$author = array(
array('id'=>1,'name'=>'John Smith','phone'=>'+1 445 789-1234'),
array('id'=>2,'name'=>'Maria Sunshine','phone'=>'333-3333')
);

MediaWiki 表格

MediaWiki(www.mediawiki.org/wiki/MediaWiki)是一个流行的维基包,支持广泛使用的维基百科。这个维基软件实现了一种格式化语言,可以用表格格式描述数据。在 phpMyAdmin 中选择这种导出格式会产生一个文件,可以粘贴到我们正在编辑的维基页面上。

JSON

JavaScript 对象表示法(json.org)是一种在网络世界中流行的数据交换格式。以这种格式导出author表格的代码如下所示:

/**
Export to JSON plugin for PHPMyAdmin
@version 0.1
*/
/* Database 'marc_book' */
/* marc_book.author */
[{"id": 1,"name": "John Smith","phone": "+01 445 789-1234"}, {"id": 2,"name": "Maria Sunshine","phone": "333-3333"}]

导出表格

视图中的导出链接会显示特定表的导出子面板。它类似于数据库导出面板,但没有表选择器。然而,在输出子面板之前,还有一个用于分割导出(行)的额外部分,如下所示:

导出表格

分割文件导出

对话框中包含的行数开始行部分使我们能够将表分成多个部分。根据确切的行大小,我们可以尝试各种值来找到要查找的行数以及在 Web 服务器中达到内存或执行时间限制之前可以放入单个导出文件中的行数。然后,我们可以为我们的导出文件使用名称,例如book00.sqlbook01.sql。如果我们决定导出所有行,我们只需选择转储所有行单选按钮。

有选择地导出

在 phpMyAdmin 界面的各个位置,我们可以导出我们看到的结果,或者选择要导出的行。我们将研究导出表的选定部分的各种方法。

导出部分查询结果

当从 phpMyAdmin 显示结果(这里是查询要求显示作者 ID 为 2的书籍结果)时,页面底部会出现一个导出链接。

导出部分查询结果

单击此链接会弹出一个特殊的导出面板,其中包含顶部的查询以及其他表导出选项。通过此面板生成的导出将仅包含此结果集中的数据。

注意

单表查询的结果可以以所有可用格式导出,而多表查询的结果可以以除 SQL 之外的所有格式导出。

导出和复选框

每当我们看到结果(例如浏览或搜索时),我们可以勾选我们想要的行旁边的复选框,然后使用选择的内容:导出图标或链接生成一个仅包含这些行的部分导出文件。

导出和复选框

导出多个数据库

任何用户都可以在一次操作中导出他/她有权限访问的数据库。

在主页上,导出链接将我们带到下面截图所示的屏幕。除了数据库列表之外,它的结构与其他导出页面相同。

导出多个数据库

注意

导出大型数据库可能有效,也可能无效。这取决于它们的大小,所选择的选项,以及 Web 服务器的 PHP 组件设置(特别是内存大小和最大执行时间)。

在服务器上保存导出文件

与通过 HTTP 传输导出文件不同,可以直接将其保存在 Web 服务器的文件系统上。这可能会更快,而且不太受执行时间限制的影响,因为从服务器到客户端浏览器的整个传输被绕过了。最终,可以使用文件传输协议(如 FTP 或 SFTP)来检索文件,因为将其留在同一台机器上不会提供良好的备份保护。

在保存导出文件之前,必须在 Web 服务器上创建一个特殊目录。通常,这是主phpMyAdmin目录的子目录。我们将使用save_dir作为示例。此目录必须具有正确的权限。首先,Web 服务器必须对此目录具有写权限。此外,如果 Web 服务器的 PHP 组件正在安全模式下运行,则 phpMyAdmin 脚本的所有者必须与save_dir的所有者相同。

在 Linux 系统上,假设 Web 服务器以group apache运行,以下命令可以解决问题:

# mkdir save_dir
# chgrp apache save_dir
# chmod g=rwx save_dir 

注意

适当的所有权和权限高度取决于所选择的 Web 服务器和SAPI(服务器应用程序编程接口)(参见en.wikipedia.org/wiki/Server_Application_Programming_Interface)),它影响目录和文件的创建和访问方式。PHP 可能使用脚本所有者作为访问用户,也可能使用 Web 服务器的用户/组本身。

我们还必须在$cfg['SaveDir']中定义'./save_dir'目录名称。我们在这里使用相对于phpMyAdmin目录的路径,但绝对路径同样有效。

输出部分将出现一个新的在服务器上保存..部分。

在服务器上保存导出文件

点击Go后,我们将收到确认消息或错误消息(如果 Web 服务器没有所需的权限来保存文件)。

注意

要再次使用相同的文件名保存文件,请勾选覆盖现有文件框。

用户特定的保存目录

我们可以在$cfg['SaveDir']参数中使用特殊字符串%u。这个字符串将被登录的用户名替换。例如,如下行代码所示:

$cfg['SaveDir'] = './save_dir/%u';

这将给我们一个屏幕选择,在目录./save_dir/marc/中保存在服务器上。这些目录(每个潜在用户一个)必须存在,并且必须具有适当的权限,如前一节所示。

内存限制

生成导出文件会使用一定量的内存,取决于表的大小和选择的选项。$cfg['MemoryLimit']参数可以包含 PHP 脚本在 phpMyAdmin 中使用的内存量的限制(以字节为单位)-导出/导入脚本和其他脚本。默认情况下,该参数设置为0,表示没有限制。我们可以通过使用20M的值来设置 20 MiB 的限制(这里的M后缀非常重要,以避免设置 20 字节的限制!)。

注意

请注意,如果 PHP 启用了安全模式,更改$cfg['MemoryLimit']将不起作用。相反,强制限制来自php.ini中的memory_limit指令。

除了内存限制,执行时间限制对导出有影响,并且可以通过$cfg['ExecTimeLimit']参数进行控制。

摘要

在本章中,我们研究了触发导出的各种方式-从数据库视图,视图或结果页面。我们还列出了各种可用的导出格式,它们的选项,压缩导出文件的可能性以及可能发送的各种地方。

在下一章中,我们将有机会导入我们的结构和数据,前提是所选的格式得到 phpMyAdmin 支持。

第七章:导入结构和数据

在本章中,我们将学习如何导入我们可能为备份或传输目的而导出的数据。导出的数据也可能来自其他应用程序的作者,并且可能包含这些应用程序的整个基础结构以及一些示例数据。

当前的 phpMyAdmin 版本(3.4)可以导入以下内容:

  • 包含 MySQL 语句的文件(通常具有.sql后缀,但不一定如此)

  • CSV 文件(逗号分隔值,尽管分隔符不一定是逗号);这些文件可以由 phpMyAdmin 本身导入,也可以通过 MySQL 的LOAD DATA INFILE语句导入,该语句使 MySQL 服务器能够直接处理数据,而不是首先由 phpMyAdmin 解析数据

  • 打开文档电子表格文件

  • XML 文件(由 phpMyAdmin 生成)

在第五章中涵盖的二进制列上传可以说属于导入系列。

注意

在这种情况下,导入和上传是同义词。

一般来说,导出文件可以导入到它来自的同一数据库或任何其他数据库;XML 格式是一个例外,本章后面的 XML 部分中给出了一个解决方法。此外,从旧的 phpMyAdmin 版本生成的文件应该没有问题被当前版本导入,但是导出时的 MySQL 版本与导入时的版本之间的差异可能在兼容性方面起到更大的作用。很难评估未来 MySQL 版本将如何改变语言的语法,带来导入挑战。

可以从几个面板访问导入功能:

  • 导入菜单可从主页、Database视图或Table视图中访问

  • 导入文件菜单在查询窗口内提供(如第十一章中所述)

Import界面的默认值在$cfg['Import']中定义。

在检查实际导入对话框之前,让我们讨论一些限制问题。

传输限制

当我们导入时,源文件通常位于我们的客户端机器上,因此必须通过 HTTP 传输到服务器。这种传输需要时间并使用资源,这些资源可能在 Web 服务器的 PHP 配置中受到限制。

我们可以使用 FTP 等协议将文件上传到服务器,而不是使用 HTTP,如“从 Web 服务器上传目录读取文件”部分所述。这种方法绕过了 Web 服务器的 PHP 上传限制。

时间限制

首先,让我们考虑时间限制。在config.inc.php中,$cfg['ExecTimeLimit']配置指令默认分配了任何 phpMyAdmin 脚本的最大执行时间为 300 秒(五分钟),包括文件上传后处理数据的脚本。值为0会移除限制,并在理论上给我们无限的时间来完成导入操作。如果 PHP 服务器运行在安全模式下,修改$cfg['ExecTimeLimit']将不会生效。这是因为在php.ini或用户相关的 Web 服务器配置文件(如.htaccess或虚拟主机配置文件)中设置的限制优先于此参数。

当然,实际花费的时间取决于两个关键因素:

  • Web 服务器负载

  • MySQL 服务器负载

注意

文件在客户端和服务器之间传输所花费的时间不计为执行时间,因为 PHP 脚本只有在服务器接收到文件后才开始执行。因此,$cfg['ExecTimeLimit']参数只对处理数据的时间(如解压缩或将数据发送到 MySQL 服务器)产生影响。

其他限制

系统管理员可以使用php.ini文件或 Web 服务器的虚拟主机配置文件来控制服务器上的上传。

upload_max_filesize参数指定了可以通过 HTTP 上传的文件的上限或最大文件大小。这个很明显,但另一个不太明显的参数是post_max_size。由于 HTTP 上传是通过 POST 方法完成的,这个参数可能会限制我们的传输。有关 POST 方法的更多详细信息,请参考en.wikipedia.org/wiki/Http#Request_methods

memory_limit参数用于防止 Web 服务器子进程占用过多服务器内存——phpMyAdmin 在子进程中运行。因此,给这个参数一个较小的值可能会影响正常文件上传的处理,特别是压缩的转储文件。在这里,无法推荐任何首选值;这个值取决于我们想要处理的上传数据的大小和物理内存的大小。内存限制也可以通过config.inc.php中的$cfg['MemoryLimit']参数进行调整,如第六章所示。

最后,通过将file_uploads设置为On来允许文件上传;否则,phpMyAdmin 甚至不会显示选择文件的对话框。显示这个对话框是没有意义的,因为后来 Web 服务器的 PHP 组件会拒绝连接。

处理大型导出文件

如果文件太大,我们可以通过多种方式解决这个问题。如果原始数据仍然可以通过 phpMyAdmin 访问,我们可以使用 phpMyAdmin 生成较小的导出文件,选择Dump some row(s)对话框。如果这不可能,我们可以使用电子表格程序或文本编辑器将文件分割成较小的部分。另一种可能性是使用上传目录机制,它访问$cfg['UploadDir']中定义的目录。这个功能在本章的后面会有详细解释。

在最近的 phpMyAdmin 版本中,部分导入功能也可以解决这个文件大小的问题。通过选择允许中断...复选框,如果检测到接近时间限制,导入过程将自行中断。我们还可以指定要从头部跳过的查询数量,以防我们成功导入一些行并希望从那个点继续。

上传到临时目录

在服务器上,一个名为open_basedir的 PHP 安全功能(将 PHP 可以打开的文件限制为指定的目录树)可能会阻碍上传机制。在这种情况下,或者出于其他任何原因,当上传出现问题时,可以使用$cfg['TempDir']参数设置临时目录的值。这可能是 phpMyAdmin 主目录的子目录,Web 服务器允许将上传文件放入其中。

导入 SQL 文件

任何包含 MySQL 语句的文件都可以通过这种机制导入。这种格式更常用于备份/恢复目的。对话框可在服务器视图、数据库视图或视图中,通过导入页面或查询窗口中使用。

导入 SQL 文件

注意

当前选择的表(这里是author)与将要导入的 SQL 文件的实际内容之间没有关系。SQL 文件的所有内容都将被导入,决定受影响的表或数据库的是这些内容。但是,如果导入的文件不包含任何选择数据库的 SQL 语句,那么导入文件中的所有语句都将在当前选择的数据库上执行。

让我们尝试一个导入练习。首先,确保我们有一个book表的当前 SQL 导出文件(如第六章中所述)。这个导出文件必须包含结构和数据。然后我们删除book表——是的,真的!我们也可以简单地重命名它。(有关该过程,请参阅第九章。)

现在是时候将文件导入到当前数据库中了(文件可以在不同的数据库中进行测试导入,甚至可以在另一个 MySQL 服务器上进行)。我们应该在导入页面上,可以看到要导入的文件对话框。我们只需要点击浏览按钮并选择我们的文件。

phpMyAdmin 能够检测文件应用了哪种压缩方法(如果有的话)。根据 phpMyAdmin 版本和 Web 服务器的 PHP 组件中可用的扩展,程序可以解压缩的格式有所不同。

然而,要成功导入,phpMyAdmin 必须知道要导入的文件的字符集。默认值是utf-8。但是,如果我们知道导入文件是用另一种字符集创建的,我们应该在这里指定它。

在导入时,可以选择SQL 兼容模式选择器。这种模式应该根据之前导出数据的服务器类型来调整,以匹配我们即将导入的实际数据。

另一个选项不要对零值使用 AUTO_INCREMENT默认标记。如果我们在主键中有一个零值,并且希望它保持为零而不是自动递增,我们应该使用这个选项。

要开始导入,我们点击Go。导入过程继续,我们收到一条消息:导入已成功完成,执行了 2 个查询。我们可以浏览我们新创建的表来确认导入操作的成功。

导入文件可能包含DELIMITER关键字。这使得 phpMyAdmin 能够模仿mysql命令行解释器。DELIMITER分隔符用于界定包含存储过程的文件部分,因为这些过程本身可能包含分号。

导入 CSV 文件

在本节中,我们将研究如何导入 CSV 文件。有两种可能的方法——CSV使用 LOAD DATA 的 CSV。第一种方法是由 phpMyAdmin 内部实现的,因为它的简单性而被推荐。使用第二种方法,phpMyAdmin 接收要加载的文件,并将其传递给 MySQL。理论上,这种方法应该更快。然而,由于 MySQL 本身的要求更多(请参阅CSV 使用 LOAD DATA部分的要求子部分)。

SQL 和 CSV 格式之间的区别

通常,SQL 格式包含结构和数据。CSV 文件格式只包含数据,因此如果我们在视图中导入,我们必须已经有一个现有的表。这个表不需要与原始表(数据来自哪里)具有相同的结构;列名对话框使我们能够选择目标表中受影响的列。

自 3.4 版本以来,我们还可以在数据库视图中导入 CSV 文件。在这种情况下,phpMyAdmin 会检查 CSV 数据并生成一个表结构来保存这些数据(具有通用列名,如COL 1,COL 2和一个表名,如TABLE 24)。

导出测试文件

在尝试导入之前,让我们从author表中生成一个author.csv导出文件。我们使用CSV 导出选项中的默认值。然后我们可以使用Empty选项来清空author表——我们应该避免删除这个表,因为我们仍然需要表结构。清空表的过程在第五章中有介绍,在删除表中的所有行部分。

CSV

author表菜单中,我们选择导入,然后选择CSV

CSV

我们可以通过多种方式影响导入的行为。默认情况下,导入不会修改现有数据(基于主键或唯一键)。然而,“用文件替换表数据”选项指示 phpMyAdmin 使用 REPLACE 语句而不是 INSERT 语句,以便用导入的数据替换现有行。

使用“在 INSERT 错误时不中止”,将生成 INSERT IGNORE 语句。这会导致 MySQL 在插入时忽略任何重复键的问题。导入文件中的重复键不会替换现有数据,程序会继续下一行 CSV 数据。

然后我们可以指定终止每一列的字符,包围数据的字符,以及转义包围字符的字符。通常是“\”。

对于“行终止符”选项,应首先尝试“auto”选项,因为它会自动检测行尾字符。我们还可以手动指定终止行的字符。通常 UNIX 系统选择“\n”,DOS 或 Windows 系统选择“\r\n”,Mac 系统选择“\r”(Mac OS 9 及以下)。如果不确定,我们可以在客户端计算机上使用十六进制文件编辑器(不是 phpMyAdmin 的一部分)来检查确切的代码。

默认情况下,phpMyAdmin 期望 CSV 文件与目标表具有相同数量的列和相同的列顺序。这可以通过在“列名”中输入一个逗号分隔的列名列表来改变,以符合源文件格式。例如,假设我们的源文件只包含作者 ID 和作者姓名信息:

"1","John Smith"
"2","Maria Sunshine"

我们必须在“列名”中放入“id,name”以匹配源文件。

当我们点击“Go”时,导入将被执行,并且我们会收到确认。如果文件的总大小不太大,我们还可能看到生成的 INSERT 查询。

Import has been successfully finished, 2 queries executed.
INSERT INTO `author` VALUES ('1', 'John Smith', '+01 445 789-1234'
)# 1 row(s) affected.
INSERT INTO `author` VALUES ('2', 'Maria Sunshine', '333-3333'
)# 1 row(s) affected.

使用 LOAD DATA 的 CSV

使用这种方法(仅在“表”视图中可用),phpMyAdmin 依赖服务器的 LOAD DATA INFILE 或 LOAD DATA LOCAL INFILE 机制来执行实际的导入,而不是在内部处理数据。这些语句是在 MySQL 中导入文本的最快方式。它们会导致 MySQL 开始从 MySQL 服务器上的文件(LOAD DATA INFILE)或其他地方(LOAD DATA LOCAL INFILE)进行读取操作,而在这种情况下,通常是 Web 服务器的文件系统。如果 MySQL 服务器位于与 Web 服务器不同的计算机上,我们将无法使用 LOAD DATA INFILE 机制。

要求

依赖 MySQL 服务器会产生一些后果。使用 LOAD DATA INFILE 要求登录用户拥有全局的 FILE 权限。此外,文件本身必须可被 MySQL 服务器的进程读取。

注意

第十九章解释了 phpMyAdmin 的界面,系统管理员可以使用该界面来管理权限。

在 PHP 中使用 LOAD DATA LOCAL INFILE 时,必须允许 MySQL 服务器和 MySQL 的客户端库中的 LOCAL 修饰符。

phpMyAdmin 的 LOAD 界面提供了两种 LOAD 方法,试图选择最佳的默认选项。

使用 LOAD DATA 界面

我们从author表菜单中选择导入。选择 CSV using LOAD DATA 选项会弹出以下对话框:

使用 LOAD DATA 界面

注意

可用的选项已经在 CSV 部分中介绍过了。

在“要导入的文件”部分,我们选择我们的 author.csv 文件。

最后,我们可以选择 LOAD 方法,如前面讨论的,通过选择“使用 LOCAL 关键字”选项。然后点击“Go”。

如果一切顺利,我们可以看到确认屏幕,如下截图所示:

使用 LOAD DATA 界面

这个屏幕显示了使用的 LOAD DATA LOCAL INFILE 语句。以下是发生的事情:

  1. 我们选择了 author.csv。

  2. 这个文件的内容通过 HTTP 传输并被 Web 服务器接收。

  3. Web 服务器内的 PHP 组件将此文件保存在工作目录(此处为/opt/php-upload-tmp/)并赋予临时名称。

  4. phpMyAdmin 知道这个工作文件的位置后,构建了一个LOAD DATA LOCAL INFILE命令,并将其发送到 MySQL。请注意,只执行了一个查询,加载了许多行。

  5. MySQL 服务器读取并加载了文件的内容到我们的目标表中。然后返回受影响的行数(2),phpMyAdmin 在结果页面上显示了这个数字。

导入其他格式

除了 SQL 和 CSV 格式,phpMyAdmin 还可以导入 Open Document Spreadsheet 和 XML 文件。但是,这些文件需要由 phpMyAdmin 自己导出,或者紧密遵循 phpMyAdmin 导出时的操作。

Open Document Spreadsheet

默认情况下,当我们以这种格式通过 phpMyAdmin 导出时,将列名放在第一行选项未被标记。这意味着导出的文件只包含数据。在导入时,相应的选项文件的第一行包含表列名被提供,并且如果文件的第一行不包含列名,则不应该被标记。

但是,如果导出的文件包含列名,我们可以检查这个选项。因此,当从数据库视图导入时,phpMyAdmin 将执行以下操作:

  1. 使用文件名(author.ods)作为表名(author)创建表。

  2. 使用第一行的列名作为此表的列名。

  3. 根据数据本身确定每个列的类型和适当的大小。

  4. 将数据插入表中。

如果我们处于视图中,只有数据将被导入。

还有其他导入选项,用于指示应该如何处理空行以及包含百分比或货币值的数据。

XML

通过导入 XML 文件创建的结构信息的数量取决于导出时选择的选项。实际上,如果选择了对象创建选项对话框的选项,那么精确的CREATE TABLE语句将被放置在导出文件中。因此,恢复表中将有相同的表结构。

同样,如果标记了导出内容选项,则整个数据都在 XML 文件中准备好导入。在导入时没有可用选项,因为 XML 是一种自描述格式;因此,phpMyAdmin 可以正确解释文件中的内容并做出适当的反应。

由于原始数据库名称是 XML 导出的一部分,当前的 phpMyAdmin 版本只支持将 XML 文件导入到导出源数据库中。要导入到不同的数据库,我们需要首先使用文本编辑器并更改以下行中的数据库名称:

<pma:database name="marc_book" collation="latin1_swedish_ci" charset="latin1">

从 Web 服务器上传目录读取文件

为了解决 Web 服务器的 PHP 配置完全禁用上传的情况,或者上传限制太小的情况,phpMyAdmin 可以从 Web 服务器文件系统上的特殊目录中读取上传文件。

首先,在$cfg['UploadDir']参数中指定我们选择的目录名称,例如,'./upload'。我们还可以使用%u字符串,如第六章中所述,来表示用户的名称。

现在,让我们回到导入页面。我们收到一个错误消息:

您设置的上传工作目录无法访问

这个错误消息是预期的,因为该目录不存在。它应该已经在当前的phpMyAdmin安装目录内创建。该消息也可能表明该目录存在,但无法被 Web 服务器读取。

注意

在 PHP 安全模式下,目录的所有者和 phpMyAdmin 安装脚本的所有者必须相同。

使用 SFTP 或 FTP 客户端,我们创建必要的目录,现在可以在那里上传文件(例如book.sql),绕过任何 PHP 超时或上传最大限制。

提示

请注意,文件本身必须具有允许 Web 服务器读取的权限。

在大多数情况下,最简单的方法是允许每个人都可以读取文件。

刷新导入页面会出现以下截图:

从 Web 服务器上传目录读取文件的操作如下图所示:

点击Go应该执行文件中的语句。

上传目录中的文件也可以自动解压缩。文件名应该具有.bz2, .gz, .sql.bz2.sql.gz等扩展名。

提示

使用双扩展名(.sql.bz2)是指示.sql文件已经生成并压缩的更好方式,因为我们看到了生成此文件所使用的所有步骤。

显示上传进度条

特别是在导入大文件时,有一个视觉反馈对上传进度的进行是很有趣的。请注意,我们在这里讨论的进度条只通知我们有关上传部分的进度,这是整个导入操作的一个子集。

拥有启用 JavaScript 的浏览器是此功能的要求。此外,Web 服务器的 PHP 组件必须具有 JSON 扩展和以下扩展中的至少一个:

phpMyAdmin 使用 AJAX 技术获取进度信息,然后将其显示为要导入的文件对话框的一部分。上传的字节数、总字节数和上传百分比显示在条形图下方。

配置 APC

一些php.ini指令对上传进度起着重要作用。首先,apc.rfc1867指令必须设置为Ontrue,否则该扩展将不会向调用脚本报告上传进度。当设置为On时,该扩展会使用上传状态信息更新 APC 用户缓存条目。

此外,更新的频率可以通过apc.rfc1867_freq指令进行设置,可以采用总文件大小的百分比形式(例如,apc.rfc1867_freq = "10%"),或以字节为单位的大小(接受后缀k表示千字节,m表示兆字节,g表示千兆字节)。这里的值为0表示尽可能频繁地更新,看起来很有趣,但实际上可能会减慢上传速度。

更新频率的概念解释了为什么在使用这种机制时,进度条以块状而不是连续地进行。

总结

本章涵盖了:

  • phpMyAdmin 中允许我们导入数据的各种选项

  • 导入文件涉及的不同机制

  • 尝试传输时可能遇到的限制,以及绕过这些限制的方法

下一章将解释如何进行单表搜索(涵盖搜索条件规范)以及如何在整个数据库中进行搜索。

第八章:搜索数据

在本章中,我们介绍了可用于查找我们正在寻找的数据的机制,而不仅仅是浏览表格页面并对其进行排序。在搜索模式下,应用程序开发人员可以以界面不期望的方式查找数据,调整并有时修复数据。本章涵盖了单表搜索和整个数据库搜索。第十二章是本章的补充,并提供了涉及同时多个表的搜索示例。

单表搜索

本节描述了搜索页面,其中提供了单表搜索。仅在单个表中搜索仅在单个表中聚合了我们想要搜索的所有数据的情况下才有效。如果数据分散在许多表中,则应该启动数据库搜索,这将在本章后面进行介绍。

输入搜索页面

可以通过在Table视图中点击搜索链接来访问搜索页面。这在这里已经为book表完成了:

输入搜索页面

搜索界面最常用的部分(示例查询)会立即显示,而其他对话框则隐藏在可以通过选项链接激活的滑块中(本章后面将更多介绍这些对话框)。

按列搜索条件-示例查询

搜索面板的主要用途是输入某些列的条件,以便只检索我们感兴趣的数据。这被称为示例查询,因为我们给出了我们要查找的内容的示例。我们的第一个检索将涉及查找具有 ISBN 1-234567-89-0的书。我们只需在isbn框中输入这个值,并将运算符字段设置为=

按列搜索条件-示例查询

点击Go会给出以下结果(在下面的截图中部分显示):

按列搜索条件-示例查询

这是一个标准的结果页面。如果结果分页显示,我们可以浏览它们,并在过程中编辑和删除所选择的子集的数据。phpMyAdmin 的另一个特性是,用作条件的列通过更改边框颜色来突出显示,以更好地反映它们在结果页面上的重要性。

并不需要指定isbn列被显示,即使这是我们搜索的列。我们可以仅选择title列进行显示(参考选择要显示的列部分),并选择isbn列作为条件。

搜索空/非空值

当列具有字符类型(如CHAR,VARCHARTEXT)时,操作符列表中会出现两个方便的操作符:

  • = ''

  • != ''

当您想要搜索某列中的空值(= '')或非空值(!= '')时,可以使用这些。通常,在列的字段中不输入任何内容意味着该列不参与搜索过程。但是,使用这些运算符之一,该列将包括在生成的搜索查询中。

注意

请不要将此方法与搜索NULL值混淆,这是完全不同的。实际上,NULL值(参考en.wikipedia.org/wiki/Null_(SQL)以获取更完整的解释)是一种特殊值,表示该列中缺少一些信息。

使用打印视图生成报告

我们在结果页面上看到了打印视图打印视图(带有完整文本)链接。这些链接会直接将结果(不包括导航界面)更正式地生成报告并直接发送到打印机。在我们的情况下,使用打印视图会产生以下结果:

使用打印视图生成报告

这份报告包含有关服务器、数据库、生成时间、phpMyAdmin 版本、MySQL 版本和生成的 SQL 查询的信息。另一个链接打印视图(带有完整文本)将打印TEXT列的全部内容。

使用通配符字符进行搜索

让我们假设我们正在寻找一些不太精确的东西——所有标题中带有“电影”一词的书籍。首先,我们回到搜索页面。对于这种类型的搜索,我们将使用 SQL 的LIKE运算符。该运算符接受通配符字符——百分号(%)字符(匹配任意数量的字符)和下划线(_)字符(匹配单个字符)。因此,我们可以使用%cinema%让 phpMyAdmin 找到任何与单词“cinema”匹配的子字符串。如果我们省略了通配符字符,我们将只得到包含该单词的精确匹配。

这种子字符串匹配更容易访问,因为它是运算符下拉列表的一部分。我们只需输入单词cinema并使用运算符LIKE %...%进行匹配。我们应该避免在大表上使用这种形式的LIKE运算符(包含数千行),因为 MySQL 在这种情况下不会使用索引进行数据检索,导致等待时间取决于服务器硬件及其当前负载。这就是为什么这个运算符不是下拉列表中的默认选项,即使这种搜索方法在较小的表上通常被使用。

以下屏幕截图显示了我们如何使用LIKE %...%运算符要求搜索cinema

使用通配符字符进行搜索

注意

LIKE运算符可以用于其他类型的通配符搜索,例如History%,这将在标题开头搜索这个词。由于表达式不以通配符字符开头,MySQL 将尝试使用索引来加快数据检索。有关 MySQL 索引的更多详细信息,请参阅dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html

使用这两种查询方法之一会产生以下结果:

使用通配符字符进行搜索

在搜索表达式中可以重复使用%_通配符字符;例如,histo__(两个下划线)将匹配history,而histo%将匹配historyhistorian。MySQL 手册在dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html中给出了更多示例。

大小写敏感和搜索

在前面的例子中,我们可以用“CINEMA”替换“cinema”并获得类似的结果。原因是title列的排序规则是latin1_swedish_ci。这种排序规则来自于在数据库创建时默认设置的排序规则集,除非服务器的默认排序规则已更改(参见dev.mysql.com/doc/refman/5.1/en/charset-mysql.html))。这里,ci表示比较是以不区分大小写的方式进行的。有关更多详细信息,请参阅dev.mysql.com/doc/refman/5.1/en/case-sensitivity.html

组合条件

我们可以为同一查询使用多个条件(例如,查找所有超过 300 页的英文书籍)。在运算符中有更多比较选择,因为page_count列是数字型的,如下面的屏幕截图所示:

组合条件

搜索选项

选项滑块显示了额外的面板,以进一步细化搜索过程。

选择要显示的列

在“选项”滑块中,“选择列”面板方便地选择要在结果中显示的列。默认情况下会选择所有列,但我们可以使用“Ctrl”+单击其他列来进行必要的选择。Mac 用户将使用“Command”+单击来选择/取消选择列。

以下是此示例中感兴趣的列:

选择要显示的列

我们还可以在列选择旁边的文本框中指定每页的行数。稍后将在“应用 WHERE 子句”部分中解释“添加搜索条件”框。

排序结果

“显示顺序”对话框允许指定结果的初始排序顺序。在此对话框中,下拉菜单包含所有表的列;我们可以选择要排序的列。默认情况下,排序将按升序进行,但也可以选择降序。

值得注意的是,在结果页面上,我们可以使用第四章中解释的技术来更改排序顺序。

应用 WHERE 子句

有时,我们可能希望输入一个在“示例查询”部分的“函数”列表中没有提供的搜索条件。该列表无法包含语言中的每种可能的变化。假设我们想要使用IN子句找到所有英语或法语的书。为此,我们可以使用“添加搜索条件”部分。

应用 WHERE 子句

注意

通过将搜索条件和其他条件(在“示例查询”行中输入)与逻辑AND运算符组合生成完整的搜索表达式。

我们可以有一个更复杂的搜索条件列表,可以在同一个文本框中输入,可能包括括号和ANDOR等运算符。

“文档”链接指向 MySQL 手册,我们可以在那里看到大量可用函数的选择。(每个函数适用于特定的列类型。)

避免重复结果

SELECT语句的正常行为是获取与条件相对应的所有条目,即使有些条目重复。有时,我们可能希望避免多次获取相同的结果。例如,如果我们想知道我们在哪些城市有客户,只显示每个城市的名称一次就足够了。在这里,我们想知道我们的书是用哪种语言写的。在“选择列”对话框中,我们只选择“语言”列,并勾选“DISTINCT”,如下面的屏幕截图所示:

避免重复结果

单击“Go”会生成一个结果页面,在那里我们只看到“en”一次;如果没有“DISTINCT”选项,包含“en”的行将出现三次。

如果我们选择了多个列(例如author_idlanguage)并标记了DISTINCT选项,那么现在我们将在结果中看到两行,因为有两本书是用英语写的(但来自不同的作者)。结果仍然不重复。

执行完整的数据库搜索

在前面的示例中,搜索被限制在一个表中。这假设我们知道可能存储所需信息的确切表(和列)。

当数据隐藏在数据库中的某个地方,或者当相同的数据可以以各种列的形式呈现(例如,“标题”列或“描述”列),使用数据库搜索方法会更容易。

我们在marc_book数据库的“数据库”视图中进入“搜索”页面:

执行完整的数据库搜索

在“单词或值”部分,我们输入想要查找的内容。在这里,“%”通配符字符可能会很有用,但请记住本章前面提到的通配符字符的性能建议。我们输入“纪念品”。

Find部分,我们指定如何处理输入的值。我们可能需要找到至少一个输入的单词所有单词(无特定顺序),或确切的短语(单词按相同顺序出现在某个列中)。另一个选择是使用作为正则表达式,这是一种更复杂的模式匹配方式。更多细节可在dev.mysql.com/doc/refman/5.1/en/regexp.htmlwww.regular-expressions.info/找到。我们将保持默认值——至少一个输入的单词

我们可以选择要限制搜索的表,或选择所有表。由于我们只有两个(小)表,我们选择了两个。

注意

由于搜索将在所选表的每一行上进行,如果行数或表的数量太大,我们可能会遇到一些时间限制。因此,可以通过将$cfg['UseDbSearch']设置为FALSE来停用此功能(默认设置为TRUE)。

点击Go为我们找到以下结果:

执行完整的数据库搜索

这是匹配数量和相关表的概述。我们可能会在我们不感兴趣的表中找到一些匹配。但是,对于看起来有希望的匹配,我们可以点击browse来浏览结果页面,或者我们可以选择delete来删除不需要的行。show search criteria链接将带回我们的条件面板。

限制搜索到一列

有时,特定的列名是一个(或多个)表的一部分,我们只想在这个列中进行搜索。例如,假设我们正在寻找"marc";但这个名字也可能是书名的一部分。因此,我们只想在所有选择的表的"name"列中限制搜索。这可以通过在inside column选项中输入"name"来实现。

停止错误的查询

假设我们启动了一个复杂的搜索,并注意到浏览器正在等待结果。这可能发生在数据库搜索中,也可能发生在单表搜索中。我们可以指示浏览器停止,但这只会告诉 Web 服务器停止处理我们的请求。然而,此时 MySQL 服务器进程正在忙碌,可能正在进行复杂的连接或完整的表扫描。以下是停止这个错误查询的方法:

  1. 我们打开一个不同的浏览器(例如,错误的查询是通过 Firefox 启动的,我们打开 Internet Explorer)。

  2. 我们使用相同的帐户通过 phpMyAdmin 登录到 MySQL。

  3. 在主页上,我们点击Processes

  4. 此时,我们应该在Command列下看到一个由Query标识的进程,并包含错误的查询(而不是SHOW PROCESSLIST,这不是要终止的进程)。

  5. 我们点击Kill来终止这个进程。

  6. 为了验证,我们可以立即再次点击Processes,选择的进程现在应该被标识为Killed而不是Query

摘要

在本章中,我们概述了带有“按示例查询”的单表搜索以及附加条件规范的概述——选择显示的值和排序结果。我们还研究了通配符搜索和完整的数据库搜索。

下一章将解释如何对表执行操作,例如更改表的属性,比如存储引擎。本章还涵盖了修复和优化表的主题。

第九章:执行表和数据库操作

在前几章中,我们主要处理了表列。在本章中,我们将学习如何执行一些影响整个表或数据库的操作。我们将涵盖表属性以及如何修改它们,并讨论多表操作。

视图的操作页面上汇集了各种启用表操作的链接。以下是此页面的概述:

执行表和数据库操作

维护表

在其生命周期中,表会反复修改,因此不断增长和缩小。服务器可能会出现中断,导致一些表处于损坏状态。

使用操作页面,我们可以执行各种操作,下面列出了这些操作。但是,并非每种存储引擎都支持每种操作。

  • 检查表:扫描所有行以验证删除的链接是否正确。还会计算校验和以验证键的完整性。如果一切正常,我们将获得一个显示OK表已经是最新的的消息;如果出现其他消息,现在是修复此表的时候了(参考修复表项目)。

  • 分析表:分析并存储键分布;这将在后续的JOIN操作中用于确定应该连接表的顺序。应定期执行此操作(如果表中的数据已更改)以提高JOIN效率。

  • 修复表:修复MyISAMARCHIVE引擎中表的任何损坏数据。请注意,表可能会损坏到我们甚至无法进入视图!在这种情况下,请参考多表操作部分以修复它的程序。

  • 碎片整理表:InnoDB表中进行随机插入或删除会使其索引碎片化。应定期对表进行碎片整理以加快数据检索。此操作会导致 MySQL 重建表,并且仅适用于InnoDB

  • 优化表:当表包含开销时,这是有用的。在大量删除行或VARCHAR列长度更改后,表中会保留丢失的字节。如果 phpMyAdmin 在各个地方(例如在结构视图中)感觉表应该被优化,它会警告我们。此操作将回收表中未使用的空间。在 MySQL 5.x 的情况下,可以优化的相关表使用MyISAM,InnoDBARCHIVE引擎。

  • 刷新表:当出现许多连接错误并且 MySQL 服务器阻止进一步连接时,必须执行此操作。刷新将清除一些内部缓存,并允许正常操作恢复。

注意

操作是基于可用的底层 MySQL 查询进行的 - phpMyAdmin 只调用这些查询。更多详细信息请参阅dev.mysql.com/doc/refman/5.5/en/table-maintenance-sql.html

更改表属性

表属性是表的各种属性。本节讨论了其中一些设置的设置。

表存储引擎

我们可以更改的第一个属性称为存储引擎

表存储引擎

这控制了表的整体行为 - 其位置(在磁盘上或内存中)、索引结构以及是否支持事务和外键。下拉列表取决于我们的 MySQL 服务器支持的存储引擎。

注意

如果行数较多,更改表的存储引擎可能是一个长时间的操作。

表注释

表注释选项允许我们为表输入注释。

表注释

这些注释将显示在适当的位置,例如在导航面板中,在Table视图中的表名称旁边,以及在导出文件中。以下屏幕截图显示了当$cfg['ShowTooltip']参数设置为其默认值TRUE时导航面板的外观:

表注释

$cfg['ShowTooltipAliasDB']$cfg['ShowTooltipAliasTB']的默认值为(FALSE),会产生我们之前看到的行为—导航面板和Structure页面中显示真实的数据库和表名。当光标悬停在数据库或表名上时,注释会显示为工具提示。如果其中一个参数设置为TRUE,则行为将反转—默认显示注释,并将真实名称显示为工具提示。当真实表名不具有意义时,这是方便的。

还有另一种可能性是$cfg['ShowTooltipAliasTB']的值为'nested'。如果使用此功能会发生什么:

  • 导航面板中显示真实表名

  • 表注释(例如,project__)被解释为项目名称,并按原样显示(参见第三章中的数据库中表的嵌套显示部分)

表顺序

当我们浏览表,或执行诸如SELECT * from book之类的语句而没有指定排序顺序时,MySQL 使用行物理存储的顺序。可以使用Alter table order by对话框更改表顺序。我们可以选择任何列,表将在此列上重新排序一次。在示例中,我们选择author_id,然后单击Go,表将按此列排序。

如果我们知道大部分时间将按此顺序检索行,则重新排序是方便的。此外,如果以后使用ORDER BY子句,并且表已经在此列上物理排序,可能会获得更好的性能。

默认排序将持续到表中没有更改(没有插入、删除或更新)为止。这就是为什么 phpMyAdmin 显示(单独)警告。

表顺序

在对author_id进行排序后,作者1的书将首先显示,然后是作者2的书,依此类推(我们谈论的是默认浏览表而没有明确排序)。我们还可以指定排序顺序为升序降序

如果我们插入另一行,描述来自作者1的新书,然后单击浏览,由于排序是在插入之前完成的,该书将不会与此作者的其他书一起显示。

表排序规则

基于字符的列具有描述用于解释内容的字符集以及排序规则的排序属性。name列当前具有latin1_swedish_ci排序规则,可以通过Structure页面看到。在Operations页面上,如果我们将表author的排序规则从latin1_swedish_ci更改为utf8_general_ci,则会生成以下语句:

ALTER TABLE `author` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

因此,我们只更改了将来将添加到此表中的列的默认排序规则;对于现有列,未更改排序规则。

表选项

可以使用表选项对话框指定影响表行为的其他属性:

表选项

选项包括:

  • PACK_KEYS:设置此属性会导致较小的索引。这样可以更快地读取,但更新需要更多时间。适用于MyISAM存储引擎。

  • CHECKSUM:这使得 MySQL 为每一行计算一个校验和。这会导致更新速度变慢,但查找损坏的表变得更容易。仅适用于MyISAM

  • DELAY_KEY_WRITE:这指示 MySQL 不立即写入索引更新,而是将它们排队以便稍后写入。这可以提高性能,但存在负面折衷——在服务器故障的情况下可能需要重建索引(参见dev.mysql.com/doc/refman/5.1/en/miscellaneous-optimization-tips.html))。仅适用于MyISAM

  • TRANSACTIONAL、PAGE_CHECKSUM:适用于Aria存储引擎,以前称为MariaTRANSACTIONAL选项将此表标记为事务性表;然而,此选项的确切含义会随着此存储引擎的未来版本获得更多的事务性功能而变化。PAGE_CHECKSUM计算所有索引页的校验和。目前在kb.askmonty.org/en/aria-storage-engine中有文档记录。

  • ROW_FORMAT:对支持此功能的存储引擎(MyISAM、InnoDB、PBXTAria)提供了一种行格式的选择。默认值是该表行格式的当前状态。

  • AUTO_INCREMENT:这会更改自动递增值。仅当表的主键具有自动递增属性时才显示。

清空或删除表

清空表(删除其数据)和删除表(删除其数据和表的结构)可以通过清空表(TRUNCATE)删除表(DROP)链接来完成,这些链接位于删除数据或表部分。

重命名、移动和复制表

重命名操作是最容易理解的——表只是更改其名称并保持在同一数据库中。

移动操作(如下截图所示)以两种方式操作表——更改其名称以及存储它的数据库。

重命名、移动和复制表

MySQL 不直接支持移动表。因此,phpMyAdmin 必须在目标数据库中创建表,复制数据,然后最终删除源表。这可能需要很长时间,具体取决于表的大小。

复制操作会保留原始表并将其结构或数据(或两者)复制到另一个表中,可能是另一个数据库中。在这里,book-copy表将是book源表的精确副本。复制后,我们仍然保持在book表的Table视图中,除非我们选择了切换到复制表选项,此时我们将移动到新创建表的Table视图中。

重命名、移动和复制表

仅结构复制用于创建具有相同结构但没有数据的测试表。

向表追加数据

复制对话框也可以用于将数据从一个表追加(添加)到另一个表中。两个表必须具有相同的结构。通过输入我们想要复制数据的表并选择仅数据来实现此操作。

例如,图书数据来自各种来源(各种出版商)以每个出版商一个表的形式,并且我们希望将所有数据汇总到一个地方。对于MyISAM,可以通过使用Merge存储引擎(这是一组相同的MyISAM表)来获得类似的结果。但是,如果表是InnoDB,我们需要依赖 phpMyAdmin 的复制功能。

执行其他表操作

操作界面上,可能会出现其他对话框。引用完整性验证对话框将在第十章中介绍。分区维护将在第十七章中进行检查。

多表操作

数据库视图中,每个表名旁边都有一个复选框,并且在表列表下方有一个下拉菜单。这使我们能够快速选择一些表并一次对所有这些表执行操作。在这里,我们选择book-copybook表,并选择所选表的检查表操作,如下截图所示:

多表操作

我们还可以使用全选/取消全选选项快速选择或取消选择所有复选框。

修复“正在使用”的表

多表模式是修复损坏表的唯一方法(除非我们知道要输入的确切 SQL 查询)。此类表可能在数据库列表中显示为正在使用标志。在 phpMyAdmin 的支持论坛中寻求帮助的用户经常会从经验丰富的 phpMyAdmin 用户那里得到这个提示。

数据库操作

数据库视图中的操作选项卡提供了访问面板的权限,使我们能够对整个数据库执行操作,如下截图所示:

数据库操作

重命名数据库

重命名数据库为对话框可用。虽然 MySQL 不直接支持此操作,但 phpMyAdmin 通过创建新数据库,重命名每个表(从而将其发送到新数据库)并删除原始数据库来间接执行此操作。

复制数据库

即使 MySQL 本身不原生支持此操作,也可以对数据库进行完整复制。选项与已经解释的表复制类似。

复制数据库

摘要

本章介绍了我们可以对整个表或数据库执行的操作。还介绍了表维护操作,包括表修复和优化,更改各种表属性,表移动(包括重命名和移动到另一个数据库)和多表操作。

在下一章中,我们将开始研究依赖于 phpMyAdmin 配置存储的高级功能,例如关系系统。

第十章:从关系系统中受益

关系系统允许用户更密切地与 phpMyAdmin 合作,我们将在接下来的章节中看到。本章将解释如何定义表格之间的关系。

关系型 MySQL

当应用程序开发人员使用 PHP 和 MySQL 构建 Web 界面或其他数据操作应用程序时,他们通常使用底层 SQL 查询来建立表格之间的关系。例如,"获取发票及其所有项目"和"获取作者的所有书籍"等查询。

在早期版本的 phpMyAdmin 中,关系数据结构(表格之间的关系)并未存储在 MySQL 中。表格是通过应用程序进行程序化连接以生成有意义的结果的。

这被 phpMyAdmin 开发人员和用户认为是 MySQL 的一个缺点。因此,团队开始构建基础设施,以支持MyISAM表的关系,现在称为 phpMyAdmin 配置存储。这个基础设施发展到支持越来越多的特殊功能,如查询书签和基于 MIME 的转换。

现在,表格之间的关系通常是使用InnoDBPBXT存储引擎的FOREIGN KEY功能本地定义的。phpMyAdmin 支持这种类型的关系以及为MyISAM定义的关系。

InnoDB 和 PBXT

InnoDBwww.innodb.com)是由 Innobase Oy,Oracle 的子公司开发的 MySQL 存储引擎。在 MySQL 5.5 之前,这个存储引擎可能不可用,因为它必须由系统管理员激活;然而,在 5.5 版本中,它是默认的存储引擎。

PrimeBase XT存储引擎或 PBXT(www.primebase.org)是由 PrimeBase Technologies 开发的。最低要求的 MySQL 版本是 5.1,因为这个版本支持可插拔存储引擎 API,这个 API 被PBXT和其他第三方用来提供替代存储引擎。这个事务性存储引擎比InnoDB更新。通常在从他们的网站下载后进行编译步骤后安装。对于一些操作系统,也有预编译的二进制文件可用-请访问上述网站获取下载和安装说明。

在考虑关系方面,对于表格使用InnoDBPBXT存储引擎的好处有:

它们支持基于外键的引用完整性,这些外键是外部(或引用)表中的键。相比之下,仅使用 phpMyAdmin 的内部关系(稍后讨论)不会带来自动的引用完整性验证。

InnoDBPBXT表的导出结构包含了定义的关系。因此,它们可以轻松地被重新导入,以实现更好的跨服务器互操作性。

这些存储引擎的外键功能可以有效地替代 phpMyAdmin 配置存储中处理关系的部分。我们将看到 phpMyAdmin 如何与InnoDBPBXT外键系统进行交互。

注意

phpMyAdmin 的其他部分配置存储(例如书签)在InnoDB、PBXT或 MySQL 中没有等价物。因此,仍然需要它们来访问完整的 phpMyAdmin 功能集。然而,在 MySQL 5.x 中,支持视图,并且与 phpMyAdmin 的书签有相似之处。

使用关系视图定义关系

安装 phpMyAdmin 配置存储后,在Database视图和Table视图中有更多选项可用。我们现在将在Table视图的Structure页面中检查Relation view链接。

使用关系视图定义关系

这个视图用于:

  • 定义当前表格与其他表格的关系

  • 选择显示列

我们的目标是在book表(包含作者 ID)和author表(通过 ID 描述每个作者)之间创建关系。我们从book表的“表”视图开始,转到“结构”,然后点击“关系视图”链接。

定义内部关系

如果book表是以MyISAM格式,我们会看到以下屏幕(否则,显示会不同,如后面的“定义外键关系”部分所解释的):

定义内部关系

这个屏幕允许我们创建“内部关系”(存储在pma_relation表中),因为 MySQL 本身对MyISAM表没有任何关系概念。每一列旁边的空下拉列表表示没有与任何外键表的关系(链接)。

定义关系

我们可以将book表的每一列与另一张表的列(或同一张表,因为自引用关系有时是必要的)相关联。界面会在同一数据库的所有表中找到唯一和非唯一键,并以下拉列表的形式呈现这些键。(目前不支持从界面创建到其他数据库的内部关系。)对于“author_id”列的适当选择是从author表中选择相应的“id”列。

定义关系

然后点击“保存”,定义将保存在 phpMyAdmin 的配置存储中。要删除关系,只需返回到屏幕,选择空选项,然后点击“保存”。

定义显示列

我们的author表的主键是id,这是我们为主键目的而创造的唯一编号。作者的名字是自然指代作者的方式。在浏览book表时看到作者的名字会很有趣。这就是显示列的目的。我们通常应该为每个参与关系的表定义一个显示列,作为外键表。

我们将在“从定义的关系中受益”部分看到这些信息是如何显示的。现在我们转到author表的“关系视图”(在这种情况下是外键表),并指定显示列。我们选择“name”作为显示列,然后点击“保存”,如下面的截图所示:

定义显示列

注意

phpMyAdmin 只提供为一张表定义一个显示列的选项,并且这一列在使用该表作为外键表的所有关系中都会使用。

现在这个关系的定义已经完成。虽然我们没有将author表的任何列与另一张表相关联,但可以这样做。例如,我们可以在这个表中有一个国家代码,并且可以创建到国家表的国家代码的关系。

现在,我们将看到如果我们的表受到InnoDBPBXT存储引擎的控制会发生什么。

外键关系

InnoDBPBXT存储引擎为我们提供了本地外键系统。

注意

在本节中,可以选择使用InnoDBPBXT存储引擎来完成练习。InnoDB已经在文本中选择。

在这个练习中,我们的bookauthor表必须使用InnoDB存储引擎。我们可以在“表”视图的“操作”页面中进行此操作。

在练习中,为了看到缺少索引的后果,需要采取另一步。我们回到book表的“结构”,移除我们在“author_id”和“language”列上创建的组合索引。

InnoDB中的外键系统维护相关表之间的完整性。因此,我们无法向book表中添加不存在的作者 ID。此外,在对主表执行DELETEUPDATE操作时,可以编程执行操作(在我们的情况下是book)。

打开book表的结构页面并进入关系视图,现在显示了一个不同的页面:

外键关系

此页面为我们提供以下信息:

  • author_idauthor表有一个内部关系定义。

  • 尚未定义任何InnoDB关系。

  • 当在InnoDB中定义了相同的关系时,我们将能够删除内部关系。实际上,悬停在内部关系旁边的问号上会显示以下消息:当存在相应的 FOREIGN KEY 关系时,内部关系是不必要的。因此,最好将其删除。

在相关键的可能选择中,我们可以看到同一数据库中所有InnoDB表中定义的键。 (当前不支持在 phpMyAdmin 中创建跨数据库关系。)当前表中定义的键也会显示,因为自引用关系是可能的。让我们删除author_id列的内部关系并单击保存。我们的目标是为author_id列添加一个InnoDB 类型的关系,但是由于此行上出现了未定义索引!消息,这是不可能的。这是因为只有在两个列都有索引的情况下,才能在InnoDBPBXT中定义外键。

注意

有关约束的其他条件在 MySQL 手册中有解释。请参考dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

因此,我们回到book表的结构页面,并为author_id列添加一个普通(非唯一)索引,产生以下屏幕:

外键关系

关系视图中,我们可以再次尝试添加我们想要的关系;这次成功了!

外键关系

我们还可以使用ON DELETEON UPDATE选项设置一些操作。例如,ON DELETE CASCADE会使 MySQL 在从父表中删除相应行时自动删除相关(外键)表中的所有行。例如,当父表是invoices,而外键表是invoice‑items时,这将非常有用。这些选项是 MySQL 本身支持的,因此在 phpMyAdmin 之外进行删除会导致级联删除。

注意

如果我们尚未这样做,应该按照“定义显示列”部分的说明为author表定义显示列。

没有 phpMyAdmin 配置存储的外键

即使未安装配置存储,我们在InnoDBPBXT表的结构页面上也可以看到关系视图链接。这会带我们到一个屏幕,我们可以在这里定义外键,例如book表。

请注意,如果选择此选项,无法定义所链接表(在本例中为author)的显示列,因为它属于 phpMyAdmin 的配置存储。因此,我们将失去查看外键相关描述的好处。

使用设计师定义关系

基于 Ajax 的设计师提供了一种以视觉方式管理关系(内部和基于外键的),并为每个表定义显示列的方法。它还可以充当:

  • 访问现有表结构和访问表创建页面的菜单

  • 如果我们想要一个包含所有表的 PDF 模式管理器

设计师工作区,我们可以在同一面板上处理所有表的关系。另一方面,关系视图只显示单个表的关系。

我们可以通过单击设计师菜单选项从数据库视图访问此功能。

注意

如果此菜单选项未出现,则是因为我们尚未按照第一章中描述的方式安装 phpMyAdmin 配置存储。

查看界面

设计师页面包含主工作区,可以在其中看到表。该工作区将根据我们的表的位置动态增长和缩小。以下截图展示了包含我们的三个表及其之间关系的设计师界面:

查看界面

顶部菜单包含图标,将鼠标悬停在上面可以显示其描述。以下表格总结了顶部菜单图标的目标:

图标 描述
显示/隐藏左侧菜单 显示或隐藏左侧菜单。
保存位置 保存工作区的当前状态。
创建表 退出设计师并进入对话框以创建表;在单击此按钮之前,我们应该注意保存表的位置。
创建关系 设计师置于创建关系的模式中。
选择要显示的列 指定哪一列代表一个表。
重新加载 设计师之外表的结构发生变化时,刷新表的信息。
帮助 显示有关选择关系的解释。
Angular 链接/直接链接 指定关系链接的形状。
吸附到网格 影响相对于想象网格的表移动行为。
小/大全部 隐藏或显示每个表的列列表。
切换小/大 反转每个表的列显示模式,因为可以使用其角标图标V>为每个表选择此模式。
导入/导出 显示一个对话框,以从现有的 PDF 模式定义中导入或导出。
移动菜单 顶部菜单可以向右移动,然后再次返回。

单击显示/隐藏左侧菜单图标时,会出现一个侧边菜单。其目的是呈现完整的表列表,以便您可以决定哪个表出现在工作区,并启用访问特定表的结构页面。在这个例子中,我们选择从工作区中移除book-copy表,如下截图所示:

查看界面

如果我们想永久删除它,我们点击保存位置顶部图标。该图标还会保存我们的表在工作区上的当前位置。

表可以通过拖动它们的标题栏在工作区上移动,并且可以通过每个表的左上角图标来显示/隐藏表的列列表。在这个列列表中,小图标显示数据类型(数字、文本和日期),并告诉我们这一列是否是主键。

定义关系

由于我们已经使用关系视图定义了一个关系,我们首先看看如何删除它。设计师不允许更改关系。但是,设计师允许删除和定义关系。

问号图标显示一个面板,解释了在哪里点击,以便选择要删除的关系。

定义关系

单击关系线以选择它。我们会得到一个确认面板,在上面单击删除

定义关系

然后我们可以继续重新创建它。要做到这一点,我们首先点击创建关系图标:

定义关系

然后,光标变成一个短消息,上面写着选择引用键。在我们的情况下,引用键是author表的id列;所以我们把光标放在这个列上并点击它。进行验证,确保我们选择了一个主键或唯一键。

接下来,将光标更改为选择外键,将其移动到book表的author_id列上,然后再次点击。这确认了关系的创建。目前,界面不允许创建复合键(具有多个列)。

定义外键关系

删除或定义InnoDBPBXT表之间的关系的过程与内部关系相同。唯一的例外是,在创建时,会出现一个不同的确认面板,使我们能够指定on deleteon update操作。

定义外键关系

定义显示列

在工作空间中,author表中的name列具有特殊的背景颜色。这表示该列作为显示列。我们只需点击选择要显示的列图标,然后将短消息选择要显示的列拖到另一列上,例如phone列。这将更改显示列为该列。如果我们将消息拖到现有的显示列上,我们将删除该列作为表的显示列的定义。

导出 PDF 模式

在第十五章中,我们将看到如何为数据库的子集生成 PDF 模式。我们可以将这样一个模式的表坐标导入到设计师的工作空间中,反之亦然,将它们导出到 PDF 模式。导入/导出坐标图标可用于此目的。

受益于定义的关系

在本节中,我们将看到我们目前可以测试的定义关系的好处。其他好处将在第十二章和第十五章中描述。phpMyAdmin 配置存储的其他好处将在第十四章、第十六章和第十八章中出现。

这些好处适用于内部和外键关系。

外键信息

让我们浏览book表。我们看到相关键(author_id)的值现在是链接。将光标移动到任何author_id值上会显示作者的名字(由author表的显示列定义)。

外键信息

点击author_id会带我们到相关的—author—表,针对特定的作者:

外键信息

我们可能更喜欢看到所有行的显示列而不是查看键。返回到book表,我们可以选择关系显示列显示选项并点击Go。这会产生一个类似以下截图的屏幕:

外键信息

现在我们通过选择关系键并点击Go来切换回查看键。

外键的下拉列表

插入模式(或编辑模式)下显示book表,现在每个具有定义关系的列都有可能键的下拉列表。列表包含键和描述(显示列)的两种顺序——键到显示列以及显示列到键。这使我们可以使用键盘输入键或显示列的第一个字母。

外键的下拉列表

注意

只有键(在这种情况下为1)将存储在book表中。显示列仅用于辅助我们。

默认情况下,如果外部表中最多有 100 行,则会出现此下拉列表。这由以下参数控制:

$cfg['ForeignKeyMaxLimit'] = 100;

对于比这更大的外部表,会出现一个不同的窗口——外部表窗口(参见下一节),可以进行浏览。

我们可能希望以不同的方式查看下拉列表中的信息。这里,John Smith是内容,1是 ID。默认显示由以下代码控制:

$cfg['ForeignKeyDropdownOrder'] = array( 'content-id', 'id-content');

我们可以在定义数组中使用—content-idid-content—中的一个或两个字符串,并按照我们喜欢的顺序。因此,将$cfg['ForeignKeyDropdownOrder']定义为array('id-content')将产生一个只有这些选择的列表:

1 John Smith
2 Maria Sunshine
3 André Smith

可浏览的外键表窗口

我们当前的author表中只有很少的条目。因此,为了说明这个机制,我们将把$cfg['ForeignKeyMaxLimit']设置为一个人为的低数,1。现在在book表的插入模式中,我们看到一个小表形状的图标和浏览外键值链接,用于author_id列。这个图标打开另一个窗口,其中会显示author表的值和一个搜索输入框。左边的值按键值排序(这里是id列),右边的值按描述排序。

可浏览的外键表窗口

选择一个值(通过点击键值或描述)会关闭这个窗口,并将值带回author_id列。

引用完整性检查

我们在第九章中讨论了操作页面及其表维护部分。在这个练习中,我们假设bookauthor表都不受InnoDBPBXT存储引擎的控制。如果我们为author表定义了内部关系,那么book表会出现一个新的选项——检查引用完整性

引用完整性检查

每个定义的关系都会出现一个链接(author_id -> author.id),点击它会开始验证。对于每一行,会验证外键表中相应键的存在性,并报告任何错误。如果结果页面报告零行,那就是好消息!

这个操作存在是因为对于不支持外键的存储引擎下的表,无论是 MySQL 还是 phpMyAdmin 都不会强制执行引用完整性。例如,可以在book表中插入无效的author_id列的数据。

元数据的自动更新

phpMyAdmin 通过在每次通过 phpMyAdmin 对表进行更改时,保持内部关系的元数据同步。例如,重命名作为关系一部分的列会使 phpMyAdmin 在关系的元数据中重命名此列。这保证了内部关系在列名更改后仍然能够正常工作。当删除列或表时也会发生同样的情况。

注意

如果从 phpMyAdmin 外部对结构进行更改,元数据应该手动维护。

列评论

在 MySQL 4.1 之前,MySQL 结构本身不支持对列添加注释。然而,由于 phpMyAdmin 的元数据,我们可以对列进行注释。然而,自 MySQL 4.1 以来,原生列注释得到了支持。好消息是,对于任何 MySQL 版本,phpMyAdmin 中的列注释始终通过结构页面访问,通过编辑每个列的结构。在下面的例子中,我们需要对book表的三列进行注释。因此,我们选择它们,然后点击With selected旁边的铅笔图标。

列评论

要获得下一个面板,如图所示,我们正在垂直模式下工作。这种模式在第五章中有介绍。我们按照下面的截图输入注释,然后点击保存

列评论

这些注释会出现在各个地方,例如导出文件(参见第六章),PDF 关系模式(参见第十五章),以及浏览模式,如下面的截图所示:

列评论

如果我们不希望注释出现在浏览模式中,我们可以将$cfg['ShowBrowseComments']设置为FALSE。(默认为TRUE。)

列注释也会出现在结构页面的工具提示中,列名下划线为虚线。要停用此行为,我们可以将$cfg['ShowPropertyComments']设置为FALSE。(这个也是默认为TRUE。)

自动迁移列注释

每当 phpMyAdmin 检测到列注释存储在其元数据中时,它会自动将这些列注释迁移到本机 MySQL 列注释中。

总结

本章介绍了如何定义InnoDB和非 InnoDB 表之间的关系。它还检查了 phpMyAdmin 的修改行为(当存在关系时)和外键。最后,它涵盖了设计者功能,列注释以及如何从表中获取信息。

下一章将介绍输入 SQL 命令的方法,当 phpMyAdmin 的界面不足以完成我们需要的操作时,这些命令非常有用。

第十一章:输入 SQL 语句

本章解释了我们如何在 phpMyAdmin 中输入自己的 SQL 语句(查询),以及如何保留这些查询的历史记录。传统上,人们会通过“mysql”命令行客户端与 MySQL 服务器交互,输入 SQL 语句并观察服务器的响应。官方的 MySQL 培训仍然涉及直接向这样的客户端输入语句。

SQL 查询框

phpMyAdmin 允许我们通过其图形界面执行许多数据库操作。然而,有时我们必须依靠 SQL 查询输入来实现界面不直接支持的操作。以下是两个这样的查询示例:

SELECT department, AVG(salary) FROM employees GROUP BY department HAVING years_experience > 10;
SELECT FROM_DAYS(TO_DAYS(CURDATE()) +30);

要输入这样的查询,可以从 phpMyAdmin 中的多个位置使用 SQL 查询框。

数据库视图

当进入“数据库”视图中的“SQL”菜单时,我们会遇到第一个 SQL 查询框。

数据库视图

这个框很简单——我们输入一些有效(希望如此)的 MySQL 语句,然后点击Go。在查询文本区域下方,有与书签相关的选择(稍后在第十四章中解释)。通常,我们不必更改标准的 SQL 分隔符,即分号。但是,如果需要,有一个分隔符对话框(参见第十七章)。

要在此框中显示默认查询,我们可以使用$cfg['DefaultQueryDatabase']配置指令进行设置,默认情况下为空。我们可以在这个指令中放置一个查询,比如SHOW TABLES FROM @DATABASE@。这个查询中的@DATABASE@占位符将被当前数据库名替换,结果就是在查询框中显示SHOW TABLES FROM marc_book``。

表视图

在“表”视图的book表中,“SQL”菜单中有一个略有不同的框。

表视图

该框已经有一个默认查询,如前一个截图所示。这个默认查询是从$cfg['DefaultQueryTable']配置指令生成的,其中包含SELECT * FROM @TABLE@ WHERE 1。这里,@TABLE@会被当前表名替换。$cfg['DefaultQueryTable']中的另一个占位符是@FIELDS@。这个占位符将被该表的完整列列表替换,从而生成以下查询:

SELECT `isbn`, `title`, `page_count`, `author_id`, `language`, `description`, `cover_photo`, `genre`, `date_published`, `stamp`, `some_bits` FROM `book` WHERE 1.

WHERE 1是一个始终为真的条件。因此,查询可以按原样执行。我们可以用我们想要的条件替换1,或者我们可以输入一个完全不同的查询。

由于这个 SQL 框出现在“表”视图中,表名是已知的;因此,phpMyAdmin 在查询框下方显示按钮,允许快速创建包含该表名的常见 SQL 查询。这些按钮生成的大多数查询包含完整的列列表。

列选择器

“列”选择器是加快查询生成的一种方式。通过选择一个列并点击箭头<<,这个列名就会被复制到查询框中当前的光标位置。在这里,我们选择author_id列,删除数字1,然后点击<<。然后我们添加条件= 2,如下截图所示:

列选择器

“再次显示此查询”选项(默认选中)确保查询在执行后仍然保留在框中,如果我们仍然在同一页上。这对于像UPDATEDELETE这样影响表但不产生单独结果页面的查询更容易看到。

点击查询框

我们可能想要通过$cfg['TextareaAutoSelect']配置指令来改变在查询框内点击的行为。它的默认值是FALSE,这意味着点击时不会自动选择内容。如果将这个指令更改为TRUE,那么第一次点击这个框将选择它的所有内容。(这是一种快速将内容复制到其他地方或从框中删除的方法。)下一次点击将把光标放在点击位置。

查询窗口

在第三章中,我们讨论了这个窗口的目的,以及更改一些参数(如尺寸)的过程。这个窗口可以很容易地从导航面板中使用SQL图标或查询窗口链接打开,如下面的屏幕截图所示,非常方便用于输入查询和测试:

查询窗口

以下屏幕截图显示了出现在主面板上的查询窗口:

查询窗口

屏幕截图中的窗口包含与视图上下文中使用的相同的选择器和<<按钮。这个独特的查询窗口只支持启用了 JavaScript 的浏览器。

查询窗口选项

SQL选项卡是这个窗口中默认的活动选项卡。这来自于配置指令$cfg['QueryWindowDefTab'],默认包含sql

如果我们想要另一个选项卡成为默认活动选项卡,我们可以用fileshistory替换sql。另一个值full一次显示所有三个选项卡的内容。

在查询窗口中,我们可以看到一个不要从窗口外部覆盖此查询选择的复选框。通常情况下,这个复选框是选中的。如果我们取消选中它,那么我们在生成查询时所做的更改将反映在查询窗口中。这被称为同步。例如,从导航或主面板中选择不同的数据库或表会相应地更新查询窗口。然而,如果我们直接在这个窗口中开始输入查询,复选框将被选中以保护其内容并取消同步。这样,这里组成的查询将被锁定和保护。

基于会话的 SQL 历史记录

这个功能将我们作为 PHP 会话数据执行的所有成功的 SQL 查询收集起来,并修改查询窗口以使它们可用。这种默认类型的历史记录是临时的,因为$cfg['QueryHistoryDB']默认设置为FALSE

基于数据库的 SQL 历史记录(永久)

当我们安装了 phpMyAdmin 配置存储(参见第一章)时,就可以使用更强大的历史记录机制。我们现在应该通过将$cfg['QueryHistoryDB']设置为TRUE来启用这个机制。

在我们从查询框中尝试一些查询之后,一个历史记录就会建立起来,只有从查询窗口中才能看到,如下面的屏幕截图所示:

基于数据库的 SQL 历史记录(永久)

我们可以看到(按相反顺序)最后成功的查询和它们所在的数据库。只有从查询框中输入的查询以及 phpMyAdmin 生成的查询(例如通过点击浏览生成的查询)才会保存在这个历史记录中。

它们可以立即执行,更改图标可用于将记录的查询插入查询框进行编辑。

将保留的查询数量由$cfg['QueryHistoryMax']控制,默认设置为25。这个限制不是出于性能原因,而是为了实现一个视觉上不受限制的视图而设置的实际限制。额外的查询在登录时被消除,这个过程传统上被称为垃圾收集。查询被存储在$cfg['Servers'][$i]['history']中配置的表中。

编辑查询

在成功查询的结果页面上,会显示包含执行查询的标题,如下截图所示:

编辑查询

单击编辑会打开查询窗口的SQL选项卡,并准备修改此查询。这是因为该参数的默认设置如下:

$cfg['EditInWindow'] = TRUE;

当它设置为FALSE时,单击编辑将不会打开查询窗口;相反,查询将出现在SQL页面的查询框内。

单击内联会将显示的查询替换为文本区域,在这里可以编辑和提交此查询,而不离开当前结果页面。

多语句查询

在 PHP 和 MySQL 编程中,我们可以使用mysql_query()函数调用一次只发送一个查询。phpMyAdmin 允许我们使用分号作为分隔符,在一次传输中发送多个查询。假设我们在查询框中输入以下查询:

INSERT INTO author VALUES (100,'Paul Smith','111-2222');
INSERT INTO author VALUES (101,'Melanie Smith','222-3333');
UPDATE author SET phone='444-5555' WHERE name LIKE '%Smith%';

我们将收到以下结果屏幕:

多语句查询

我们通过注释看到受影响的行数,因为$cfg['VerboseMultiSubmit']设置为TRUE

让我们再次发送相同的查询列表并观看结果:

多语句查询

收到“重复条目”错误消息是正常的,该消息表示值100已经存在。我们看到第一个INSERT语句的结果;但是下一个会发生什么?由于$cfg['IgnoreMultiSubmitErrors']设置为FALSE,告诉 phpMyAdmin 不要忽略多个语句中的错误,因此执行在第一个错误处停止。如果设置为TRUE,程序将依次尝试所有语句,我们会看到两个重复条目错误。

如果我们尝试多个SELECT语句,此功能将无法按预期工作。我们将只看到最后一个SELECT语句的结果。

漂亮打印(语法高亮)

默认情况下,phpMyAdmin 解析和突出显示其处理的任何 MySQL 语句的各个元素。这由$cfg['SQP']['fmtType']控制,默认设置为'html'。此模式对每个不同的元素(保留字、变量、注释等)使用特定颜色,如$cfg['SQP']['fmtColor']数组中所描述的那样,该数组位于特定主题的layout.inc.php文件中。

fmtType设置为'text'将删除所有颜色格式,将换行符插入到 MySQL 语句中的逻辑点。最后,将fmtType设置为'none'将删除所有格式,保留我们的语法不变。

SQL 验证器

每次 phpMyAdmin 传输查询时,MySQL 服务器会解释它并提供反馈。查询的语法必须遵循 MySQL 规则,这与 SQL 标准不同。但是,遵循 SQL 标准可以确保我们的查询在其他 SQL 实现上可用。

一个免费的外部服务,Mimer SQL 验证器,由 Mimer Information Technology AB 提供。它根据 Core SQL-99 规则验证我们的查询并生成报告。验证器可以直接从 phpMyAdmin 使用,并且其主页位于developer.mimer.com/validator/index.htm

注意

出于统计目的,此服务会匿名存储接收到的查询。在存储查询时,它会用通用名称替换数据库、表和列名称。查询中的字符串和数字将被替换为通用值,以保护原始信息。

系统要求

此验证器作为 SOAP 服务提供。我们的 PHP 服务器必须具有 XML、PCRE 和 SOAP 支持。SOAP 支持由 PHP 扩展或 PEAR 模块提供。如果选择 PEAR 方式,系统管理员在服务器上执行以下命令安装我们需要的模块:

pear install Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP 

如果由于某些模块处于测试阶段而导致该命令出现问题,我们可以执行以下命令,安装 SOAP 和其他依赖模块:

pear -d preferred_state=beta install -a SOAP 

使验证器可用

必须在config.inc.php中配置一些参数。将$cfg['SQLQuery']['Validate']设置为TRUE可以启用验证 SQL链接。

我们还应该启用验证器本身(因为将来的 phpMyAdmin 版本可能会提供其他验证器)。这可以通过将$cfg['SQLValidator']['use']设置为TRUE来完成。

验证器默认使用匿名验证器帐户访问,配置如下命令:

$cfg['SQLValidator']['username'] = '';
$cfg['SQLValidator']['password'] = '';

相反,如果 Mimer Information Technology 已经为我们提供了一个帐户,我们可以在这里使用该帐户信息。

验证器结果

验证器返回两种报告之一,一种是查询符合标准的,另一种是不符合标准的。

符合标准的查询

我们将尝试一个简单的查询:SELECT COUNT(*) FROM book。像往常一样,我们在查询框中输入此查询并发送。在结果页面上,我们现在看到了一个额外的链接——验证 SQL,如下截图所示:

符合标准的查询

点击验证 SQL会生成如下截图所示的报告:

符合标准的查询

我们可以选择点击跳过验证 SQL来查看我们的原始查询。

不符合标准的查询

让我们尝试另一个在 MySQL 中正确工作的查询:SELECT * FROM book WHERE language = 'en'。将其发送到验证器会生成如下截图所示的报告:

不符合标准的查询

每当验证器发现问题时,它会在错误点添加诸如{error: 1}的消息,并在报告中添加脚注。在此查询中,language列名是非标准的。因此,验证器告诉我们在此处期望标识符。关于使用LIMIT子句的非标准错误也被报告,这是 phpMyAdmin 添加到查询中的。

另一个情况是反引号。如果我们只是点击浏览book表,phpMyAdmin 会生成SELECT * FROM book``,用反引号括起表名。这是 MySQL 保护标识符的方式,标识符可能包含特殊字符,如空格、国际字符或保留字。然而,将此查询发送给验证器会显示反引号不符合标准 SQL。我们甚至可能会得到两个错误,每个反引号一个。

摘要

本章帮助我们理解了查询框的目的,并告诉我们在哪里找到它们。它还概述了如何使用列选择器、查询窗口选项、如何获取输入命令的历史记录、多语句查询,最后,如何使用 SQL 验证器。

下一章将展示如何通过 phpMyAdmin 的查询生成器生成多表查询而无需输入太多内容。

第十二章:生成多表查询

“数据库”或“表”视图中的搜索页面适用于单表查找。本章介绍了“数据库”视图中可用的多表查询示例(QBE)功能。

许多 phpMyAdmin 用户在“表”视图中逐个表地工作,因此往往忽视了多表查询生成器,这是一个用于微调查询的精彩功能。查询生成器不仅在多表情况下有用,也在单表情况下有用。它使我们能够为列指定多个条件,这是“表”视图中的搜索页面所不具备的功能。

注意

本章的示例假定已经进行了 phpMyAdmin 配置存储的多用户安装(参见第一章),并且在第九章的练习中创建的book-copy表仍然存在于marc_book数据库中。

要打开此功能的页面,我们转到特定数据库的“数据库”视图(查询生成器一次只支持对一个数据库的操作),然后点击查询

以下屏幕截图显示了初始的 QBE 页面。它包含以下元素:

  • 可视化构建器链接(本章末尾介绍)

  • 条件列

  • 添加条件行的界面

  • 添加条件列的界面

  • 表选择器

  • 查询区域

  • 更新或执行查询的按钮

生成多表查询

选择表

初始选择包括所有表。因此,选择器包含大量列。对于我们的示例,我们将仅使用authorbook表。因此,我们只从使用表选择器中选择这两个。

然后我们点击更新查询按钮。这将刷新屏幕并减少选择器中可用的列数。我们可以随时使用浏览器的多选机制(通常是控制点击)后来更改所选的表。

探索列条件

默认情况下提供了三个条件列。本节讨论了我们编辑它们的条件的选项。这些选项包括选择列、对单个列进行排序、输入单个列的条件等。

列选择器:单列或所有列

选择器包含所选表的所有单独列,以及以星号(*)结尾的特殊选择,表示选择了所有列。

列选择器:单列或所有列

要显示author表中的所有列,我们会选择author并勾选显示复选框,而不在排序条件框中输入任何内容。在我们的情况下,我们选择author.name,因为我们想为作者的姓名输入一些条件。

排序列

对于每个选定的单独列,我们可以指定排序(升序降序),或让该行保持不变(无排序,这是默认行为)。如果我们选择了多个排序列,排序将从左到右进行。

注意

当我们要求对列进行排序时,通常会勾选显示复选框。但这并非必需,因为我们可能只想进行排序操作而不显示该列。

显示列

我们勾选Show复选框,以便在结果中看到该列。有时,我们可能只想在列上应用一个条件,而不包括它在结果页面中。在这里,我们添加了phone列,要求对其进行排序,并选择同时显示姓名和电话号码。我们还要求按照姓名的升序进行排序。如果姓名相同,则首先按姓名排序,然后按电话号码排序。这是因为姓名在左侧的列条件中,因此具有更高的优先级。

显示列

更新查询

在任何时候,我们都可以点击Update Query按钮来查看我们生成的查询的进展。在执行查询之前,我们必须至少点击一次。现在,让我们点击它,看看在查询区域生成的查询。在接下来的示例中,我们将在每次修改后点击Update Query按钮。

更新查询

我们已经选择了两个表,但尚未从book表中选择任何列。因此,生成的查询中没有提到这个表。

向条件框添加条件

Criteria框中,我们可以为每个相应的列输入一个条件(遵守 SQL WHERE子句的语法)。默认情况下,我们有两行条件。为了找到所有名字中带有Smith的作者,我们使用LIKE条件(LIKE '%SMITH%')并点击Update Query

向条件框添加条件

我们还有另一行可用于输入额外的条件。假设我们想要找到作者Maria Sunshine。这次,我们使用=条件。两个条件行将由默认从界面左侧选择的Or运算符连接。

向条件框添加条件

为了更好地展示Or运算符如何连接两个条件行,让我们现在在电话号码上添加一个条件LIKE '%8%',如下截图所示:

向条件框添加条件

通过检查ANDOR运算符的定位,我们可以看到条件的第一行是由AND(因为在name列下选择了AND)运算符连接的,而条件的第二行是由OR运算符连接的。我们刚刚添加的条件'(LIKE %8%)并不是为了找到任何人,因为我们已经将所有名为“Smith”的作者的电话号码更改为“444-5555”(在第十一章中)。

如果我们想在同一列上添加另一个条件,我们只需添加一个条件行。

调整条件行的数量

条件行的数量可以通过两种方式进行更改。首先,我们可以在Criteria下选择Ins复选框来添加一个条件行(在点击Update Query后)。由于此复选框一次只能添加一行条件,因此我们将取消选中它,然后使用Add/Delete criteria rows对话框。在此对话框中,我们选择添加两行。

再次点击Update Query按钮会产生以下屏幕:

调整条件行的数量

现在,您可以看到有两行额外的条件(目前为空)。我们也可以删除条件行。这可以通过在我们要删除的行旁边勾选Del复选框来完成。让我们删除刚刚添加的两行,因为我们现在不需要它们。Update Query按钮将根据指定的调整刷新页面。

调整条件列的数量

使用类似的机制,我们可以通过在修改对话框中的每列下方的插入删除复选框,或者添加/删除列对话框来添加或删除列。我们已经有一个未使用的列(在前面的图像中未显示)。在这里,我们使用了位于未使用列下方的插入复选框添加了一列(这次我们将需要它):

调整条件列的数量

生成自动连接(内部关系)

phpMyAdmin 可以生成查询中表之间的连接,前提是已经定义了内部关系。现在让我们用我们book表的titlegenre列填充我们的两个未使用的列,看看当我们更新查询时会发生什么。

生成自动连接(内部关系)

现在有两个与book.titlebook.genre列相关的额外条件列。phpMyAdmin 利用其对表之间定义的关系的知识生成了一个LEFT JOIN子句(在上面的屏幕截图中突出显示),该子句在author_id关键列上。当前版本的一个缺点是只检查了内部关系,而没有检查InnoDB关系。

注意

可能涉及到多于两个表的连接。

执行查询

单击提交查询按钮发送查询以执行。在下面的屏幕截图中,您可以看到上部的完整生成的查询,以及下部的结果数据行:

执行查询

在我们提交查询后,除了使用浏览器的返回按钮之外,没有简单的方法返回到查询生成页面。第十四章讨论了如何保存生成的查询以供以后执行。

可视化生成器

从 3.4 版本开始,提供了另一种查询构建方法。它利用了Designer界面,可能更熟悉于用户,将查询生成与其结合起来。我们可以通过单击切换到可视化生成器链接来打开此界面,这将产生一个初始屏幕,如下面的屏幕截图所示:

可视化生成器

我们现在应该通过单击全部展开/收起图标来打开所有表的列列表。

可视化生成器

每列都有一个左侧复选框和一个右侧选项图标。复选框用于指示我们希望成为结果的哪一列;而选项图标允许打开一个面板,在面板中我们将指定要应用于此列的条件。例如,如果我们想选择超过 200 页的书,我们将单击page_count列旁边的选项图标,并填写条件对话框,如下面的屏幕截图所示:

可视化生成器

单击确定保存此查询选项;现在它可以在右侧的活动选项对话框下找到,如果需要查看或删除选项。

为了构建查询,我们使用构建查询图标,生成一个如下屏幕截图所示的屏幕:

可视化生成器

此时,我们要么使用附加选项来完善查询,要么单击提交查询以获取结果。

摘要

本章涵盖了包括打开查询生成器、选择表、输入列条件、排序和显示列、修改条件行或列的数量等各种方面。我们还学习了如何使用ANDOR运算符来定义行和列之间的关系,以及如何在表之间使用自动连接。Designer集成的可视化查询生成器也被介绍了。

下一章将向您展示如何在服务器之间同步数据以及如何管理复制。

第十三章:同步数据和支持复制

在本章中,我们将介绍 phpMyAdmin 3.3.0 版本中发布的两个功能。第一个功能是同步数据库的能力,这是开发人员要求的,他们在多个服务器上工作。第二个功能允许管理 MySQL 复制,在性能和数据安全性重要的环境中使用。这些功能有些相关,因为在设置复制过程时,通常需要将数据库同步到从服务器。

同步数据和结构

在较早的 phpMyAdmin 版本中,可以在同一服务器或不同服务器上的两个数据库之间实现一些结构和数据的同步,但这需要手动操作。可以从一个数据库导出结构和/或数据,然后导入到另一个数据库。我们甚至可以直观地比较两个表的结构,并根据需要进行调整。然而,必须由开发人员自己用眼睛比较两个数据库以确定需要导入的内容。此外,数据库之间的结构差异没有被考虑在内,可能导致目标表中缺少列时出现错误。

phpMyAdmin 的同步功能非常灵活,通过处理初始比较过程,当然也通过执行同步本身。我们将首先讨论同步的原因,然后检查并实验涉及的所有步骤。

同步的目标

尽管想要同步两个数据库的原因可能很多,但我们可以将它们分为以下几类。

在开发和生产服务器之间移动

一个良好的数据库开发策略包括在与生产服务器不同的服务器上进行开发和测试。如果没有单独的开发服务器,至少鼓励使用单独的开发数据库。随着时间的推移,测试和生产环境之间的结构差异会积累,这是正常的。例如,测试版本可能会添加一个列,或者字符列可能会被扩大。同步功能允许我们首先查看差异,然后根据需要将其应用到生产环境。

有时需要以相反的方式移动数据,例如,为了衡量性能而将真实生产数据填充到测试数据库中。

数据库设计师之间的协作

由于 MySQL 测试服务器可以轻松设置,可能会出现这样的情况,即开发团队的每个成员都有自己的服务器(或自己的数据库副本),在其中开发项目的某个方面。当需要协调每个人对同一表的更改时,同步功能是非常宝贵的。

为复制做准备

MySQL 支持主服务器和一个或多个从服务器之间的异步复制。这种数据复制被称为“异步”,因为主服务器和从服务器之间的连接不需要是永久的。然而,要启动复制过程(假设主服务器已经包含一些数据),就需要将所有数据复制到从服务器上。MySQL 手册中提供了一个完成此复制的建议,可以在dev.mysql.com/doc/refman/5.1/en/replication-howto.html找到,如下所述:

“如果您的主服务器已经有数据,并且您想使用它来同步您的从服务器,您需要创建一个数据快照。您可以使用mysqldump来创建一个快照(...)”

然而,这需要使用一个命令行工具,这取决于托管选项并不总是可能的。此外,数据库的某些部分可能已经存在于从属数据库;因此,同步功能非常方便,因为它集成到了 phpMyAdmin 中,并且它负责比较阶段。

查看同步过程

重要的原则是同步是从源数据库到目标数据库完成的。在此操作期间,源数据库保持不变。我们需要正确识别哪个数据库是源数据库,哪个是目标数据库(可能会被修改)。

整个过程被细分为可以在任何阶段停止的步骤:

  • 服务器和数据库选择

  • 比较

  • 完整或选择性同步

我们可以选择出于以下原因之一停止该过程:

  • 我们没有连接到其中一个服务器所需的凭据

  • 我们发现两个数据库之间存在差异,并且还没有准备好进行同步,因为需要进一步研究

  • 我们在比较阶段之后注意到目标数据库已经充分同步

在执行同步之前,我们将准备好必要的元素。

为同步练习做准备

由于我们只会操作authorbook表,因此本练习将假定marc_book数据库中没有其他表。我们首先将marc_book数据库复制到marc_book_dev(有关如何执行此操作的确切方法,请参阅第九章)。然后我们打开marc_book_dev数据库并执行以下操作:

  • 删除book

  • author表中删除一行

  • name列的类型从VARCHAR(30)更改为VARCHAR(29)

  • author表中删除phone

第五章介绍了如何执行前面的操作。

选择源和目标服务器和数据库

通过“服务器”视图中的同步菜单选项显示初始同步页面。请注意,这是唯一可以使用该菜单的地方。

第一个面板允许我们连接到服务器(如果需要)并选择正确的数据库。如果$cfg['AllowArbitraryServer']参数设置为其默认值false,则会出现以下面板:

选择源和目标服务器和数据库

这意味着我们只能使用在config.inc.php中已定义的服务器。如果允许任意服务器,则会看到一个不同的面板,如下面的截图所示:

选择源和目标服务器和数据库

对于源数据库和目标数据库,我们可以选择服务器位置。默认情况下,选择器放置在手动输入上,我们可以输入其主机名、端口、套接字名称、用户名、密码和数据库名称。在大多数情况下,端口应该保持默认的 3306,套接字名称应该保持为空。请注意,我们当前连接到一个 MySQL 服务器(通过正常的登录面板),这个面板可以让我们连接到另外两个服务器。

服务器位置的另一个选择是当前连接。这指的是我们连接的用于正常 phpMyAdmin 操作的服务器;其名称显示在主面板顶部。如果我们选择这个选项,启用 JavaScript 的浏览器会隐藏除了数据库名称之外的所有选项(在这种情况下,连接凭据是不必要的),并且会出现一个选择器,显示我们可以访问的所有数据库。

在源和目标两侧选择相同的服务器是完全可能的;然而,在这种情况下,我们至少会选择一个不同于目标的源数据库。另一个常见情况是选择当前服务器和某个数据库作为源,以及具有相同数据库的远程服务器作为目标,假设远程服务器是生产服务器,并且两个服务器都拥有同名的数据库。

在这个练习中,让我们为源和目标服务器都选择当前连接;然后我们可以选择marc_book作为源数据库,marc_book_dev作为目标数据库,如下面的截图所示:

选择源和目标服务器和数据库

点击Go后,phpMyAdmin 尝试连接服务器(如果需要)。此时可能会显示连接错误消息。但是,连接应该会成功,程序将开始比较两个数据库,然后显示结果。

分析比较结果

比较结果面板包含三个部分。第一部分显示了结构和数据的差异,并包含将用于启动选择性同步的图标:

分析比较结果

如上部所示,红色的S图标触发结构同步,而绿色的D图标用于数据同步。然后,对于每个表,我们得到差异的摘要。在相应表的结构和数据相同的情况下,中央的差异列将为空。在这里,我们看到两个表的红色S和绿色D,但原因并不相同。

中部显示了作为同步过程一部分的计划操作(目前没有,如下面的截图所示):

分析比较结果

下部包含一个复选框(您是否要删除目标表中的所有先前行?)和两个操作按钮。我们将在以下部分看到它们的用途:

分析比较结果

请注意,书表在一侧有一个加号(+),表示该表在源数据库中但不在目标数据库中。我们甚至在目标一侧看到了对该表的不存在注释。如果一个表在目标数据库中但不在源数据库中,它将在目标一侧标有减号(-)。

此时,我们可以决定我们对比较结果感到满意,不想继续进行;在这种情况下,我们只需在 phpMyAdmin 中选择一个数据库并恢复我们的工作。我们还有机会以一次性的方式同步数据库(完整同步),或者以更细粒度的方式进行更改(选择性同步)。让我们检查这两种方法。

执行完整同步

如果我们不想问自己太多问题,只需要完全同步,我们点击同步数据库。请注意,在这种情况下,我们不必使用任何红色的S或绿色的D图标。

注意

如果目标表中有一些行不在相应的源表中,这些行将保留在目标表中,除非我们勾选是否要删除..复选框。这是一个安全网,以避免意外数据丢失。但是,如果我们需要精确同步,我们应该选择此选项。

点击后,我们得到以下消息:目标数据库已与源数据库同步。在屏幕的下部,我们看到必须执行的查询以实现此操作。我们还得到了数据库现在已同步的视觉确认:

执行完整同步

执行选择性同步

如果我们更喜欢更谨慎,并且想要对即将执行的操作进行初步反馈,我们可以同步选择的表。本节假设数据库的状态与为同步练习做准备部分结束时的状态相同,该部分在本章的前面部分已经涵盖。

如果我们点击描述author表的行上的红色S图标,这个S图标会变成灰色,屏幕中部会更新显示要执行的操作,如下面的截图所示:

执行选择性同步

实际上还没有对数据进行任何操作!我们仍然可以通过点击相同的图标来改变主意,这会使图中部分所示的建议更改消失,图标也会变回红色。

现在我们点击绿色的D图标,看到另一行建议的更改出现,如下面的截图所示:

执行选择性同步

author表中需要插入一行,因为目标数据库中少了一个作者。总共需要更新四行,因为我们在同一张表中删除了phone列。

现在我们可以点击应用所选更改按钮。您想删除..复选框不适用于此操作。

现在我们看到屏幕上部提出了更少的更改:

执行选择性同步

我们可以继续选择结构或数据更改,然后按照我们认为合适的顺序应用它们。

这结束了描述同步功能的部分。我们将继续介绍复制支持。

支持 MySQL 复制

为复制做准备部分,我们看到了 MySQL 复制的概述。在本节中,我们将涵盖以下主题:

  • 我们如何使用 phpMyAdmin 来配置复制

  • 如何准备一个包含一个主服务器和两个从服务器的测试环境

  • 如何发送命令来控制服务器

  • 如何获取有关服务器、数据库和表的复制信息

phpMyAdmin 的界面提供了一个复制页面;然而,其他页面包含有关复制的信息或控制复制操作的链接。在涉及相关主题时,我们将指出每个适当的位置。

如何使用这一部分取决于我们手头有多少服务器。如果我们至少有两台服务器,并且想通过 phpMyAdmin 在主/从关系中配置它们,我们可以按照配置复制部分的步骤。如果我们只有一台服务器可以使用,那么我们应该从设置测试环境部分中获取建议,在同一台机器上安装多个 MySQL 服务器实例。

复制菜单

服务器视图中,复制菜单只显示给特权用户,如 MySQL 根用户。当服务器已经配置为主服务器或从服务器(或两者兼有)时,复制页面用于显示状态信息并提供发送命令的链接。

配置复制

对于这个练习,我们假设服务器目前不占据主服务器或从服务器的角色。phpMyAdmin 不能直接配置 MySQL 复制的所有方面。原因是,与通过向 MySQL 服务器发送查询来操作数据库结构和数据不同,复制配置包括(部分)存储在 MySQL 配置文件中的命令行,通常命名为my.cnf。作为一个 Web 应用程序,phpMyAdmin 无法访问这个文件。这是 MySQL 服务器开发人员打算的配置方式——在配置文件级别上。

在这种情况下,phpMyAdmin 能做的最好的就是通过根据我们的偏好生成(在屏幕上)正确的命令行来指导我们,然后由我们将这些行复制到它们需要去的地方并重新启动服务器。phpMyAdmin 甚至不能读取当前的复制配置行;它只能通过一些SHOW命令推断服务器状态。

让我们进入“复制”菜单,看看会发生什么:

配置复制

主服务器配置

现在我们选择通过点击适当的“配置”链接将服务器配置为主服务器。出现的面板给了我们详细的建议:

主服务器配置

第一段确认了这个服务器目前没有配置为复制过程中的主服务器。我们想要实现这个配置,但首先我们需要考虑我们想要的复制类型。所有数据库都应该被复制,除了其中一些吗?还是我们想要相反的?一个方便的下拉列表为我们提供了这些选择:

  • 复制所有数据库;忽略:

  • 忽略所有数据库;复制:

第一个选择(默认)意味着一般情况下所有数据库都被复制;我们甚至不需要在配置文件中列举它们。在这种情况下,数据库选择器用于指定我们想要从复制过程中排除的数据库。让我们选择“mysql”数据库,看看在我们启用 JavaScript 的浏览器中会发生什么:

主服务器配置

我们注意到出现了一行,说明binlog_ignore_db=mysql。这是一个 MySQL 服务器指令(而不是 SQL 语句),告诉服务器忽略将关于这个数据库的事务发送到二进制日志。让我们来解释其他行的含义。server-id是由 phpMyAdmin 生成的唯一 ID;参与复制的每个服务器都必须有一个唯一的服务器 ID。因此,我们要么手动跟踪服务器 ID,确保它们的唯一性,要么简单地使用 phpMyAdmin 随机生成的数字。我们还看到了log-binlog-error指令;实际上,为了进行任何复制,二进制日志记录是强制性的。

我们可以通过使用Ctrl + 点击或Command + 点击在列表中添加其他数据库名称,具体取决于我们工作站的操作系统。然而,phpMyAdmin 所做的只是生成正确的行;要使它们生效,我们仍然需要遵循给定的建议,并将这些行粘贴到我们的 MySQL 配置文件的[mysqld]部分的末尾。然后我们应该重新启动 MySQL 服务器进程——如何做这取决于我们的环境。

在我们的服务器重新启动后,我们回到“复制”菜单;此时,我们会看到关于主服务器的不同面板:

主服务器配置

我们可以使用“显示主服务器状态”链接来获取有关主服务器的一些信息,包括当前的二进制日志名称和位置,以及先前指定的要复制或忽略的数据库的信息。

“显示已连接的从服务器”链接目前不会报告任何内容,因为还没有从服务器连接到这个主服务器。

现在是使用“添加从服务器复制用户”链接的时候了,因为这个主服务器需要有一个专门用于复制的单独账户。从服务器将使用在主服务器上创建的这个账户来连接到它。点击这个链接会显示以下面板,其中正在创建一个名为“replic”的用户账户,密码由我们选择:

主服务器配置

点击“Go”后,phpMyAdmin 会负责创建这个用户并设置正确的权限。

从服务器配置

现在,在将作为复制过程中从服务器的机器上,我们启动 phpMyAdmin。在“复制”菜单中,我们点击以下对话框中的“配置”:

从服务器配置

从服务器配置面板显示如下截图所示:

从服务器配置

与主配置一样,我们在从服务器的配置文件中得到了关于在配置文件中具有唯一服务器 ID 的建议,我们应该遵循这个建议。

在此面板中,我们输入在主服务器上创建的专用复制帐户的用户名和密码。我们还必须指示与主服务器对应的主机名和端口号。在填写此面板并单击“Go”后,phpMyAdmin 将向从服务器发送适当的CHANGE MASTER命令,将此服务器置于从服务器模式。

设置测试环境

复制过程发生在至少两个 MySQL 服务器实例之间。在生产中,这通常意味着至少需要两台物理服务器来获得这些好处:

  • 更好的性能

  • 增加冗余

但是,由于 MySQL 的可配置端口号(默认为 3306)、数据目录和套接字,可能在同一台服务器上有多个 MySQL 实例。此设置可以手动配置,也可以通过安装系统(如 MySQL Sandbox)进行配置。这是一个位于mysqlsandbox.net的开源项目。使用这个工具,我们可以非常快速地设置一个或多个 MySQL 服务器。通过使用强大的make_replication_sandbox Linux shell 命令,我们可以安装一个包含一个主服务器和两个从服务器的环境。每个服务器可以单独启动或停止。

以下练习假定 MySQL Sandbox 已安装在您的服务器上,并且 phpMyAdmin 的config.inc.php包含对这些 Sandbox 服务器的引用,如下面的代码块所示(请根据自己的环境调整套接字名称):

$i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['socket'] = '/tmp/mysql_sandbox25562.sock';
$cfg['Servers'][$i]['verbose'] = 'master';
$i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['socket'] = '/tmp/mysql_sandbox25563.sock';
$cfg['Servers'][$i]['verbose'] = 'slave1';
$i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['socket'] = '/tmp/mysql_sandbox25564.sock';
$cfg['Servers'][$i]['verbose'] = 'slave2';

在这里,我们使用$cfg['Servers'][$i]['verbose']指令为每个实例提供一个唯一的名称,因为所有这些实例的真实服务器名称都是localhost。每个 Sandbox 服务器最初包含两个数据库:mysqltest

控制从服务器

在这里,我们假设 Sandbox 测试环境已经设置。但是,这些解释对于所有具有从服务器的情况都是有用的。连接到从服务器并再次打开“复制”菜单后,我们看到:

控制从服务器

有以下选项可用:

  • “查看从服务器状态表”链接允许我们接收有关此从服务器复制相关的所有系统变量的信息。

  • “控制从服务器:”链接显示更多选项;其中一些可以在停止和启动条件之间切换。

  • “全面停止”选项用于停止 IO 线程(负责从主服务器接收更新并将其写入从服务器的中继日志的 MySQL 服务器的一部分)和 SQL 线程(从中继日志读取更新并执行它们)

  • “重置从服务器”选项停止从服务器,发送RESET SLAVE命令导致其忘记在主服务器的二进制日志中的复制位置,然后重新启动从服务器

  • “仅停止 SQL 线程”选项和“仅停止 IO 线程”选项用于仅停止各自的线程

  • 错误管理:链接允许告诉从服务器跳过主服务器发送的一些事件(更新)。有关更多详细信息,请参阅dev.mysql.com/doc/refman/5.1/en/set-global-sql-slave-skip-counter.html

  • 更改或重新配置主服务器:链接可用于指定此从服务器现在应该接收来自不同主服务器的更新。

获取复制信息

除了复制菜单之外,phpMyAdmin 的其他屏幕也会向我们提供有关复制的信息。这些屏幕在其他复制对话框中找不到;相反,它们分散在各个页面上,在相应页面的上下文中显示复制信息。

收集复制状态

通过进入服务器视图中的状态面板,我们首先会得到一个简短的消息,例如:

“这个 MySQL 服务器在复制过程中作为主服务器工作。有关服务器复制状态的更多信息,请访问复制部分。”

在这个页面上有一些复制链接,它们向我们展示了主服务器或从服务器的状态变量,以及一些关于连接的从服务器主机数量和复制状态的信息。

已复制的数据库

在主服务器上,查看服务器视图中的数据库菜单会显示一些数据库可能会被复制,主复制列中会有一个绿色的勾号:

已复制的数据库

这是因为这台服务器配置了二进制日志,而这些数据库没有被排除在复制之外。

由于我们在主服务器的配置文件的[mysqld]部分中有以下代码行,我们可以排除影响mysql数据库的所有事务不记录到二进制日志中:

binlog_ignore_db=mysql

因此,数据库页面的输出显示了mysql数据库旁边的红色图标。

如果这是一个从服务器,将显示一个服务器复制列。

提示

请注意,从服务器本身可以有一个二进制日志;因此,在这种情况下,主复制从复制列都会显示出来。这意味着这个从服务器可以成为另一个从服务器的主服务器。

已复制的表

假设在主服务器上,我们在test数据库中创建了一个名为employee的表。此时,复制会发挥其魔力,我们可以在从服务器上查看test数据库:

已复制的表

在这里,复制列显示为提醒。我们不应该直接在从服务器上修改这个表,因为它的存在只是为了复制目的。如果我们决定直接修改它,我们的更改只会在这个表中进行,导致主服务器和从服务器之间的不一致,这不是一个好主意。

总结

在本章中,我们学习了如何将一个数据库的结构和数据同步到另一个数据库,无论是在同一台服务器上还是在不同的服务器上。我们涵盖了同步的目标以及如何执行完整或选择性的同步。然后我们研究了如何使用 phpMyAdmin 来引导我们进行复制设置,包括主服务器和从服务器;如何使用 MySQL Sandbox 准备测试环境,以及如何控制从服务器。

下一章将向您展示如何保留您的查询的永久书签。

第十四章:使用查询书签

本章介绍了查询书签——phpMyAdmin 配置存储的一个功能。能够为查询添加标签,并通过标签进行检索,可以节省真正的时间。书签是具有以下属性的查询:

  • 永久存储

  • 可查看

  • 可擦除

  • 与一个数据库相关

  • 仅作为用户操作的结果记录

  • 已标记

  • 默认情况下是私有的(仅对创建它们的用户可用),但可能是公共的

如本章后面的向书签传递参数部分所述,书签也可以具有可变部分。

没有用于管理书签的书签页面。相反,书签的各种操作可在特定页面上进行,例如结果页面或查询框页面。

比较书签和查询历史功能

在第十一章中,我们了解了 SQL 历史功能,它会自动存储查询(临时或永久)。存储在历史中的查询和书签之间存在相似之处。毕竟,这两个功能都旨在存储查询以供以后执行。然而,关于查询的存储方式和触发查询记录的操作,存在重要的区别。

查询历史的存储是自动的;而查询被保存为书签是通过用户的显式请求。此外,存储在永久历史中的查询数量有可配置的限制(参见第十一章);然而,书签的数量没有限制。最后,历史功能按照查询发送的时间的倒序呈现查询。然而,书签是按标签显示的(不直接显示查询文本)。

总之,当我们既不打算回忆查询,也不希望记住我们输入的查询时,自动查询历史是有用的。这与书签功能形成对比,我们故意要求系统记住一个查询,甚至给它一个名称(标签)。因此,我们可以通过书签做更多事情,而不仅仅是查询历史,但是这两个功能都有其重要性。

创建书签

有两种情况下可以创建书签——在执行查询后(在这种情况下,我们不需要提前计划其创建),以及在将查询发送到 MySQL 服务器执行之前。这两个选项在以下部分中进行了探讨。

在成功查询后创建书签

初始书签创建是通过收藏此 SQL 查询按钮实现的。此按钮仅在执行生成结果的查询后出现(至少找到一行时);因此,此方法仅存储SELECT语句。例如,由多表查询生成器生成的复杂查询(如第十二章中所示)可以以这种方式存储为书签,前提是它找到了一些结果。

让我们看一个例子。在book表的搜索页面上,我们选择要在结果中显示的列,并输入如下截图所示的搜索值:

成功查询后创建书签

点击Go后,我们看到结果页面显示了一个书签对话框。我们仅为此书签输入一个标签作者 1 的书籍,然后点击收藏此 SQL 查询以将此查询保存为书签。书签保存在由$cfg['Servers'][$i]['bookmarktable']定义的表中。

成功查询后创建书签

这个书签对话框可以在包含结果的任何页面上看到。作为测试,我们可以只需点击一个表的浏览以获取结果,然后将此查询存储为书签。然而,将一个可以轻松点击完成的查询存储为书签并没有太多意义。

在发送查询之前存储书签

我们已经看到,在生成结果的SELECT语句执行后很容易创建一个书签。有时,即使查询没有找到任何结果,我们也可能希望存储一个书签。如果查询所指的数据尚未存在,或者查询是除SELECT之外的语句,就可能出现这种情况。为了实现这一点,我们在Database视图、Table视图和查询窗口的SQL选项卡中提供了将此 SQL 查询设为书签对话框。

现在我们转到book表的SQL页面,输入一个检索法语书籍的查询,并直接将法语书籍书签标签放入将此 SQL 查询设为书签对话框中。如果此书签标签以前已被使用,除非我们选中替换同名现有书签复选框,否则将创建一个同名的新书签。书签带有内部识别号,以及用户选择的标签。

在发送查询之前存储书签

单击Go后,查询将被执行并存储为书签。即使查询没有找到任何内容也没关系。这就是我们可以为非SELECT查询生成书签的方法,例如UPDATE, DELETE, CREATE TABLE等。

注意

这种技术也可以用于SELECT语句,无论是返回结果还是不返回结果。

将书签设为公开

我们创建的所有书签默认都是私有的。创建书签时,我们登录的用户名将与书签一起存储。假设我们勾选了如下屏幕截图中显示的让每个用户访问此书签复选框:

将书签设为公开

这将产生以下效果:

  • 所有访问同一数据库(当前数据库)的用户都将可以访问该书签。

  • 用户能够从书签中看到有意义的结果,这取决于他们在书签中引用的表上的权限。

  • 任何用户都可以删除该书签。

  • 用户将被允许通过在发送查询之前存储此书签并使用替换同名现有书签选项来更改书签的查询。

公共书签在调用时会显示(共享)后缀。

表的默认初始查询

在先前的示例中,我们根据自己的喜好选择了书签标签。但是,按照惯例,如果私有书签与表同名,当单击此表的浏览时,它将被执行。因此,我们将看到书签的结果,而不是此表的正常浏览结果。

假设我们有兴趣查看(默认情况下,以浏览模式)所有页数少于 300 页的书。我们首先生成适当的查询,可以从搜索页面轻松完成,然后在结果页面上使用book作为书签标签。

表的默认初始查询

在此操作之后,每当创建此书签的用户浏览book表时,他将看到以下屏幕截图:

表的默认初始查询

多查询书签

单个书签还可以存储多个查询(用分号分隔)。这对于非SELECT查询非常有用。例如,假设我们需要定期清理有关作者的数据,以删除电话号码中的无效区号。此操作总是会跟随author表的显示。

为了实现这一目标,我们存储了一个包含这些查询的书签(在发送执行之前):

update author set phone = replace(phone,'(123)', '(456)');
select * from author;

在书签中,我们可以放置许多数据修改语句,例如INSERT, UPDATEDELETE,然后可以选择性地跟随一个SELECT语句。堆叠大量SELECT语句不会产生预期的结果,因为我们只会看到最后一个SELECT语句获取的数据。

从书签列表中调用书签

创建的任何书签都可以在以下页面找到:

  • 视图:marc_book的任何表的SQL页面

  • 查询窗口:SQL 历史选项卡

  • 数据库视图:marc_book数据库的SQL页面

从书签列表中调用书签

在调用书签时有三个选择——提交、仅查看删除(提交是默认选项)。

执行书签

选择一个书签并点击Go执行存储的查询并显示其结果。书签执行后的页面没有另一个对话框来创建书签,因为这将是多余的。

注意

我们得到的结果不一定与创建书签时相同。它们反映了数据库的当前内容。只有查询被存储为书签。

操作书签

有时,我们可能只想确定书签的内容。这可以通过选择书签并选择仅查看来完成。然后查询将被显示,我们有机会重新编辑其内容。这样做,我们将编辑原始书签查询的副本。为了保留这个新的编辑查询,我们可以将其保存为书签。同样,即使我们选择相同的书签标签,这将创建另一个书签,除非我们明确要求替换原始书签。

可以使用删除选项来删除书签。没有确认对话框来确认删除书签。我们现在应该继续删除我们的book书签。

操作书签

向书签传递参数

如果我们再次查看我们创建的第一个书签(查找作者 1的所有书),我们会意识到,虽然它很有用,但只能找到一个作者,总是相同的那个。

特殊的查询语法使得可以向书签传递参数。这种语法利用了 SQL 注释/**/在 MySQL 中被忽略的特性。如果查询中存在/*[VARIABLE]*/结构,它将在执行时用提供的值进行扩展。

创建一个带参数的书签

假设我们想要找到给定作者的所有书,但不知道作者的id。我们首先输入以下查询:

SELECT author.name, author.id, book.title
FROM book, author
WHERE book.author_id = author.id
/* AND author.name LIKE '%[VARIABLE]%' */

注释字符(/* */)之间的部分将在以后扩展,并且标签将被移除。我们将这个查询标记为一个名为按姓名查找作者的书签(在执行之前),然后点击Go。查询的第一次执行只是存储了书签,同时检索了所有作者的所有书,因为这次我们没有向查询传递参数。

在这个例子中,我们在WHERE子句中有两个条件,其中一个包含特殊语法。如果我们在WHERE子句中的唯一条件需要一个参数,我们可以使用诸如/* WHERE author_id = [VARIABLE] */的语法。

传递参数值

为了测试书签,我们像往常一样调用它,并在变量对话框中输入一个值。

传递参数值

当我们点击Go时,我们看到了扩展的查询和作者 Smith 的书。

传递参数值

总结

在本章中,我们看到了如何记录书签(在发送查询之前或之后),如何操作它们,以及如何使一些书签公开。本章还向我们介绍了浏览模式的默认初始查询。它还涵盖了向书签传递参数。

下一章将解释如何通过 phpMyAdmin 提供的工具生成解释数据库结构的文档。

第十五章:系统文档

生成并维护有关数据结构的良好文档对于项目的成功至关重要,特别是在团队项目中。事实上,能够向其他团队成员展示当前数据字典和建议的列更改是一种有价值的沟通手段。此外,表间关系的图形显示可以快速展示数据库的内部工作原理。幸运的是,phpMyAdmin 具有处理这些事情的文档功能。

生成结构报告

数据库视图的结构页面,打印视图链接可用于生成有关数据库结构的报告。此外,数据库视图中的数据字典链接会生成不同的报告。这些将在以下部分详细介绍。

创建可打印的报告

当 phpMyAdmin 生成结果时,总是有一个打印视图链接,可用于生成数据的可打印报告。打印视图功能也可用于生成基本的结构文档。这是通过两个步骤完成的。首次单击打印视图会在屏幕上显示报告,并在页面末尾有一个打印按钮。稍后,此打印按钮会生成格式化为打印机的报告。

数据库打印视图

单击数据库的结构页面上的打印视图会生成一个表格列表。此列表包含每个表的行数、存储引擎、大小、注释和创建日期,如下面的屏幕截图所示:

数据库打印视图

选择性数据库打印视图

有时,我们更喜欢为表的子集获取报告。这可以通过从数据库的结构页面选择我们想要的表,然后从下拉菜单中选择打印视图来完成,如下面的屏幕截图所示:

选择性数据库打印视图

表打印视图

对于每个表,结构页面上也有一个打印视图链接。单击此链接会生成有关表的列和索引的信息,如下面的示例所示:

表打印视图

使用数据字典准备完整报告

数据库视图的结构页面可以获取有关数据库中表和列的更完整的报告。我们只需单击数据字典链接即可获取此报告,部分内容如下屏幕截图所示:

使用数据字典准备完整报告

MIME列在我们向某些列添加 MIME 相关信息之前为空(如第十六章中所述)。

生成关系模式

在第十章中,我们定义了bookauthor表之间的关系。这些关系用于各种外键功能(例如,在插入模式中获取可能值的列表)。现在,我们将研究一项功能,它使我们能够为我们的表生成定制的关系模式,以流行的 PDF 格式和其他格式。此功能要求正确安装和配置 phpMyAdmin 配置存储。

向我们的模型添加第三个表

为了获得更完整的模式,我们现在将向我们的数据库添加另一个表country。以下代码块显示了其导出文件的内容:

CREATE TABLE IF NOT EXISTS `country` (
`code` char(2) NOT NULL,
`description` varchar(50) NOT NULL,
PRIMARY KEY (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `country` (`code`, `description`) VALUES
('ca', 'Canada'),
('uk', 'United Kingdom');

现在,我们将此表链接到author表。首先,在country表的关系视图中,我们指定要显示的列,然后单击保存

向我们的模型添加第三个表

然后,我们向author表添加一个country_code列(与country表中的code列相同类型和大小),并在关系视图中将其链接到新创建的country表。

注意

我们必须记得点击“保存”以记录关系。

对于这个例子,不需要为作者输入任何国家数据,因为我们只对关系模式感兴趣。

向我们的模型添加第三个表

生成模式页面

每个关系模式称为“页面”。我们可以通过在“数据库”视图的“操作”页面上点击“编辑或导出关系模式”来创建或编辑页面。

页面规划

关系模式不能跨越多个数据库。但即使只使用一个数据库,表的数量可能很大。以清晰的方式表示各种表之间的关系可能是一个挑战。这就是为什么我们可能会使用许多页面,每个页面显示一些表及其关系。

我们还必须考虑最终输出的尺寸。在信纸大小的纸张上打印给我们更少的空间来显示所有的表,并且仍然有一个可读的模式。

创建一个新页面

由于没有现有页面,我们需要创建一个。由于我们最重要的表是“书籍”,我们还将把这个页面命名为“书籍”。

我们将选择希望在关系模式中看到的表。我们可以逐个选择每个表。但是,为了一个良好的开始,建议勾选适当的“自动布局”复选框。这样做会将数据库中所有相关的表放入要包括在模式中的表列表中。然后生成适当的坐标,使表格将以螺旋布局的方式出现在模式中,从模式的中心开始。这些坐标以毫米表示,其中(0, 0)位于左上角。然后点击“开始”:

创建一个新页面

编辑页面

现在我们得到了一个有三个不同部分的页面。第一个是页面菜单,我们可以从下拉菜单中选择要操作的页面。我们也可以删除所选的页面。我们最终也可以创建第二个模式(页面)。

编辑页面

接下来的部分是表的放置部分。我们现在可以看到“自动布局”功能的好处——我们已经选择了我们的三个表,并填写了“X”和“Y”坐标列。我们可以添加一个表(在最后一行),删除一个表(使用复选框),并更改坐标(表示模式上每个表的左上角位置):

编辑页面

为了帮助设置精确的坐标,JavaScript 启用的浏览器可以使用可视化编辑器。当单击“切换草稿板”按钮一次时,编辑器将出现。当再次单击此按钮时,它将消失。我们可以在草稿板上拖放表格,坐标将相应更改。草稿板上表格的外观提供了最终 PDF 输出的粗略指南。有些人更喜欢在草稿板上只看到表格名称(而不是每个列名称)。这可以通过取消选择“列名称”复选框然后点击“保存”来完成。以下图片显示了这个草稿板的例子:

编辑页面

注意

当我们对布局感到满意时,必须点击“保存”。

为了显示导出页面

屏幕的最后部分是报告生成对话框。现在我们已经创建了一个页面,“显示关系模式”显示一个对话框,如下面的屏幕截图所示:

导出用于显示的页面

可用的选项有:

选项 描述
选择导出关系类型允许选择要导出的文件格式(PDF、SVG、DIA、Visio 或 EPS)。
显示网格 模式将具有显示坐标的网格层。在设计和测试模式时很有用。
显示颜色 链接、表名和特殊列(主键和显示列)将以颜色显示。
显示表的尺寸 在表标题中显示每个表的视觉尺寸(例如,32x30)。这在设计和测试模式时很有用。
显示所有具有相同宽度的表 所有表将使用相同的宽度显示。(通常,宽度会根据表和列名的长度自动调整。)
数据字典 数据字典,本章前面介绍过的,将包含在报告的开头。
仅显示键 不显示未定义索引的列。
方向 在这里,我们选择报告的打印方向。
纸张尺寸 更改此选项将影响模式和草稿板的尺寸。

config.inc.php中,以下参数定义了可用的纸张尺寸和默认选择:

$cfg['PDFPageSizes'] = array('A3', 'A4', 'A5', 'letter', 'legal');
$cfg['PDFDefaultPageSize'] = 'A4';

以下屏幕截图显示了生成报告的最后一页(模式页面)的 PDF 格式。前四页包含数据字典以及其他功能。

箭头指向相应外部表的方向。如果显示颜色复选框已被选中,则主键显示为红色,显示列显示为蓝色,如下面的屏幕截图所示:

导出页面以供显示

以下屏幕截图提供了从相同的book表的 PDF 页面定义生成的另一个示例。这次显示了网格,但没有颜色:

导出页面以供显示

更改 PDF 模式中的字体

我们在 PDF 模式中看到的所有文本都是使用特定字体绘制的。phpMyAdmin 使用DejaVuSans字体(dejavu.sourceforge.net),该字体涵盖了广泛的字符。

对于实际的 PDF 生成,phpMyAdmin 依赖于tcpdf库(tcpdf.sourceforge.net)。该库有两种使用字体的方式——嵌入和非嵌入。嵌入字体会产生更大的 PDF 文件,因为整个字体都包含在 PDF 文件中。这是 phpMyAdmin 选择的默认选项,因为该库不依赖于客户操作系统中特定的TrueType字体的存在。

字体位于phpMyAdmin主目录下的libraries/tcpdf/fonts中。

要使用不同的字体文件,我们必须首先将其添加到库中(工具在原始tcpdf工具包中,www.fpdf.org网站上有教程),然后修改 phpMyAdmin 的libraries/schema/ Pdf_Relation_Schema.class.php源代码。

使用设计者功能布置模式

设计者功能(在数据库视图中可用)提供了一种更精细的在屏幕上移动表的方式,因为列链接会跟随表的移动。因此,设计者保存的表的坐标和模式的坐标之间存在接口。让我们进入设计者,并点击小的 PDF 标志。

这将带我们到一个面板,在这里我们可以选择(现有的)模式名称和我们想要执行的操作——在我们的情况下,将设计者坐标导出到模式定义中。我们还可以使用新页面名称对话框,输入页面名称,然后点击Go创建一个空白页面。从这里,我们随后可以导出从设计者工作区保存的坐标:

使用设计者功能布置模式

设计者编辑或导出关系模式功能管理的表的跨度存在差异。设计者默认情况下操作数据库的每个表,而编辑或导出关系模式面板为我们提供了表的选择,使我们能够表示关系的子集,如果有很多表的话。

总结

本章介绍了 phpMyAdmin 提供的文档功能,包括数据库或表的打印视图以及完整列列表的数据字典。本章还涵盖了关系模式。特别是,它着重介绍了如何创建、修改和导出模式页面,以及如何使用可视化编辑器(scratchboard)。

下一章将解释如何对数据应用转换,以便在查看时自定义数据格式。

第十六章:使用 MIME 转换数据

在本章中,我们将介绍 phpMyAdmin 的一个强大功能——它能够根据称为转换的特定规则,在表浏览期间转换列的内容。通常,浏览表只显示其中存储的原始数据。然而,基于 MIME 的转换允许改变显示格式。

请注意,这种转换并不像通过UPDATE语句进行的永久数据更改那样产生相同的效果。转换后的数据不会被写回到 MySQL 服务器;它只是被发送到浏览器以供显示目的。

浏览数据而不进行转换

通常,每行的确切内容都会被显示,只是:

  • TEXTCHARACTER列可能会根据$cfg['LimitChars']而被截断,取决于我们是否选择查看完整文本

  • BLOB和与几何相关的列可能会被替换为诸如[BLOB - 1.5 KB]的消息

我们将使用术语单元格来指示特定行的特定列。当前显示的包含“未来纪念品”书籍封面照片的单元格(一个BLOB列)目前显示为像‰PNG\r\n\Z\n\0\0\0\rIHDR\0这样的加密数据,或者显示BLOB列的大小的消息。在 phpMyAdmin 中直接看到图片的缩略图(如下面的截图中所示)以及可能的全尺寸图片本身将是很有趣的。通过适当的转换,这将成为可能。

浏览数据而不进行转换

切换显示选项

浏览模式下,选项链接会显示一个滑块,其中包括一个隐藏浏览器转换复选框。我们可以在想要在查看单元格的真实数据和转换后的版本之间切换时使用它。

启用转换

我们将转换定义为一种机制,通过该机制,与某一列相关的所有单元格在浏览时都会进行转换,使用为该列定义的元数据。只有当前结果页面上可见的单元格会被转换。

这个功能的使用受config.inc.php中的$cfg['BrowseMIME']指令的控制。该指令的默认值为TRUE,表示启用了转换。然而,phpMyAdmin 配置存储必须就位(参见第一章),因为转换所需的元数据在官方 MySQL 表结构中是不可用的。这是专门为 phpMyAdmin 添加的附加功能。

注意

转换逻辑本身是通过 PHP 脚本编码的,存储在libraries/transformations中,并使用插件架构进行调用。在 phpMyAdmin 官方网站的文档部分(当前位于www.phpmyadmin.net/home_page/docs.php))中,有一个指向额外信息的链接,供希望了解插件内部结构以编写自己的转换的开发人员参考。

配置 MIME 列的设置

如果我们转到book表的结构页面的视图,并点击cover_photo列的更改链接,我们会看到三个额外的属性(假设启用了转换功能):

  • MIME 类型

  • 浏览器转换

  • 转换选项

如下截图所示:

配置 MIME 列的设置

对于特定列,可能只能指定一种类型的转换。在这里,该列是一个BLOB。因此,它可以容纳任何类型的数据。为了使 phpMyAdmin 能够正确解释和处理数据,必须通知转换系统数据格式和预期结果。因此,我们必须确保上传的数据始终遵循相同的文件格式。

我们将首先了解这些属性的目的,然后在本章后面的转换示例部分尝试一些可能性。

选择 MIME 类型

MIME 规范(en.wikipedia.org/wiki/MIME)已被选择为元数据属性,用于对列持有的数据类型进行分类。多用途互联网邮件扩展(MIME),最初设计用于扩展邮件,现在也用于描述其他协议的内容类型。在 phpMyAdmin 的上下文中,当前可能的值是:

  • image/jpeg

  • image/png

  • text/plain

  • application/octetstream

text/plain类型可用于包含任何类型文本(例如 XHTML 或 XML 文本)的列。在转换示例部分,您将看到需要选择哪种 MIME 类型以实现特定效果。

浏览器转换

这是我们设置要执行的确切转换的地方。每种 MIME 类型可能支持多个转换。例如,对于image/jpeg MIME 类型,我们有两种可用的转换:image/jpeg: inline用于图像的可点击缩略图,以及image/jpeg: link用于仅显示链接。

以下屏幕截图显示了可用转换的列表:

浏览器转换

单击转换选项旁边的问号图标,然后单击出现的转换描述链接,可以获得更完整的转换说明和可能的选项列表。

将值分配给转换选项

转换示例部分,我们将看到一些转换接受选项。例如,我们可以指定生成图像的转换的像素宽度和高度。逗号用于在选项列表中分隔值,并且某些选项可能需要用引号括起来。

一些选项具有默认值,我们必须小心遵守选项的文档顺序。例如,如果有两个选项,我们只想为第二个选项指定一个值,我们可以使用空引号作为第一个选项的占位符,让系统使用其默认值。

图像生成的要求

普通缩略图生成需要 Web 服务器上存在一些组件,并且config.inc.php中的参数正确配置。

配置 GD2 库可用性验证

phpMyAdmin 使用一些内部函数来创建缩略图。这些函数需要 PHP 服务器上存在 GD2 库。

phpMyAdmin 可以检测到正确的 GD2 库的存在,但这种检测需要一些时间。它不是每个会话一次,而是几乎每次在 phpMyAdmin 中执行操作时都会进行。

config.inc.php中将$cfg['GD2Available']参数设置为其默认值'auto'表示需要检测库的存在和版本。

如果我们知道 GD2 库可用,将$cfg['GD2Available']设置为yes将使执行更快。如果 GD2 库不可用,建议将此参数设置为no

要找出服务器上有哪个 GD2 库,我们可以转到 phpMyAdmin 的主页,然后单击显示 PHP 信息。如果没有此链接,则需要将$cfg['ShowPhpInfo']参数设置为true。然后查找一个名为gd的部分,并验证识别的版本。在下面的屏幕截图中,一切都很好,因为我们可以看到 GD 版本是 2.X,并且支持 JPEG 和 PNG:

配置 GD2 库可用性验证

确认支持 JPEG 和 PNG 库

如果我们想为这些类型的图像生成缩略图,我们的 Web 服务器中的 PHP 组件需要支持 JPEG 和 PNG 图像。有关更多详细信息,请参阅php.net/manual/en/ref.image.php

评估内存限制的影响

在一些服务器上,php.inimemory_limit的默认值为8M,表示 8 MiB。这对于正确的图像处理来说太低了,因为用于生成最终图像的 GD 函数需要工作内存。例如,在一个测试中,需要将memory_limit的值设置为11M才能从一个 300 KiB 的 JPEG 图像生成缩略图。此外,如果同时查看多行,将需要更多的工作内存。

转换示例

我们现在将讨论一些转换示例。显示了典型的选项值,并建议调整它们,直到达到期望的结果。根据 phpMyAdmin 的版本,可能会提供更多的转换。

可点击的缩略图(JPEG 或 PNG)

我们将首先将cover_photo列的类型从BLOB更改为LONGBLOB,以确保我们可以上传大小超过 65 KiB 的照片。然后,我们输入以下截图中显示的属性:

可点击的缩略图(JPEG 或 PNG)

这里,选项以宽度和高度的形式呈现。如果我们省略选项,那么默认值为 100 和 100。缩略图生成代码保留图像的原始宽高比。因此,输入的值是生成图像的最大宽度和高度。然后,我们在一个单元格中上传一个.jpeg文件(使用第五章的说明)。结果,我们在该表的浏览模式下得到以下屏幕:

可点击的缩略图(JPEG 或 PNG)

这个缩略图可以点击以显示全尺寸的照片。

注意

缩略图不会存储在任何地方,而是每次我们进入这组行的浏览模式时生成。在一个双 Xeon 3.2 GHz 服务器上,我们通常每秒可以生成六张 JPEG 图像。phpMyAdmin 不提供这些缩略图的缓存。

对于.png文件,我们必须在MIME 类型对话框中使用image/png,并在浏览转换对话框中使用image/png: inline

向图像添加链接

为了提供没有缩略图的链接,我们使用image/jpeg: link转换。没有转换选项。这个链接可以用来查看照片(通过左键单击链接),然后可能下载它(通过右键单击照片本身)。

向图像添加链接

日期格式化

在我们的book表中有一个名为date_published的列;让我们将其类型更改为DATETIME。然后,我们将其 MIME 类型设置为text/plain,并将浏览器转换设置为text/plain: dateformat。下一步是编辑“未来纪念品”书籍的行,并在date_published列中输入2003-01-01 14:56:00。当我们浏览表时,我们现在看到该列已被格式化。将鼠标悬停在上面会显示未格式化的原始内容,如下截图所示:

日期格式化

这个转换接受两个选项。第一个是要添加到原始值的小时数(默认为零)。如果我们存储基于协调世界时(UTC)的所有时间值,但想要为特定时区(例如 UTC+5)显示它们,添加小时数可能会很有用。第二个选项是我们想要使用的时间格式,使用任何 PHP strftime参数指定(更多细节请参阅php.net/strftime)。因此,如果我们在转换选项中放入'0','Year: %Y',我们将得到以下输出:

日期格式化

文本链接

假设我们在book表的description列中放入了一个完整的 URL — http://domain.com/abc.pdf。在浏览表时,链接的文本将被显示,但我们无法点击它。现在我们将看到在这种情况下使用text/plain MIME 类型的用法。

如果我们在刚才提到的场景中使用text/plain MIME 类型和text/plain: link浏览器转换,我们仍然会看到链接的文本,并且可以点击。

text/plain: link

如果我们要指向的所有文档都位于一个共同的 URL 前缀下,我们可以将这个前缀(例如,domain.com/)放在第一个转换选项中,用引号括起来。然后,我们只需要在每个单元格中放入 URL 的最后部分(abc.pdf)。

第二个转换选项用于设置标题。这将在浏览模式中显示,而不是 URL 内容,但点击后仍会带我们到预期的 URL。

如果我们只使用第二个转换选项,我们必须将第一个选项的值设为引号。可以这样做:'','this is the title'

text/plain: imagelink转换与前一个类似,只是在单元格中放置一个指向图像的 URL。该图像将被获取并与链接文本一起显示在单元格中。图像可以位于网络上的任何地方,包括我们的本地服务器。

在这里,我们有以下三个选项可用:

  • 常见的 URL 前缀(比如text/plain: link的前缀)

  • 图像的宽度(默认值:100 像素)

  • 高度(默认值:50)

对于我们的测试 URL,您应该输入以下选项:

'','100','123'

如果链接的文本太长,转换就不会发生。默认情况下选择部分文本显示选项。

text/plain: imagelink

在这种情况下,我们可以切换到完整文本以显示完整的链接。然后我们可以看到完整的图片。

text/plain: imagelink

其他转换,如image/jpeg: inlineimage/png: inline,指定了图像的确切 MIME 类型。在这些情况下,phpMyAdmin 使用 GD2 库函数进行缩略图生成。然而,在text/plain: imagelink转换中包含的链接可能指向任何浏览器支持的图像类型。因此,phpMyAdmin 只显示一个调整大小的图像,带有 HTML 的img标签,并根据转换中定义的大小选项设置widthheight属性。要查看原始图像,我们可以点击链接或缩略图。

保留原始格式

通常,当显示文本时,phpMyAdmin 会转义特殊字符。例如,如果我们在一个书籍的description列中输入This book is good,在浏览表时通常会看到This book is good。但是,如果我们对该列使用text/plain: formatted转换,那么在浏览时会得到以下输出:

保留原始格式

在这个例子中,结果是正确的。但是,列中输入的其他 HTML 标记可能会产生意想不到的结果(包括无效的 HTML 页面)。例如,由于 phpMyAdmin 使用 HTML 表呈现结果,列中的未转义的</table>标记会破坏输出。

显示文本的部分

text/plain: substr转换用于仅显示文本的一部分。以下是选项:

  • 文本的起始位置(默认值:0)

  • 有多少个字符(默认值:剩余文本的所有字符)

  • 显示截断发生时的后缀;默认情况下显示省略号(...)

请记住,$cfg['LimitChars']对于每个非数字列都会进行字符截断。因此,text/plain: substr是一种逐列微调的机制。

显示下载链接

假设我们想在 MySQL 中为每本书存储一个小的音频评论。我们向book表中添加一个新列,名为audio_contents,类型为MEDIUMBLOB。我们将其MIME 类型设置为application/octetstream,并选择application/octetstream: download 转换。在转换选项中,我们插入'comment.wav'

这个 MIME 类型和扩展名将告知我们的浏览器有关传入数据,并且浏览器应该打开适当的播放器。要插入评论,我们首先以.wav格式记录它,然后将文件内容上传到其中一个书籍的audio_contents列中。在浏览我们的表时,我们可以看到一个名为comment.wav的音频评论链接:

显示下载链接

十六进制表示

字符以数字数据的形式存储在 MySQL(以及计算机一般),并转换为屏幕或打印机上的有意义的内容。用户有时会从另一个应用程序剪切和粘贴数据到 phpMyAdmin,如果字符不直接受 MySQL 支持,可能会导致意外结果。phpMyAdmin 的帮助论坛中报告了一个案例,涉及在 Microsoft Word 文档中输入特殊引号并粘贴到 phpMyAdmin 中。通过使用application/octetstream: hex转换,可以看到确切的十六进制代码。

在以下示例中,此转换将应用于我们book表的title列。当浏览包含Future souvenirs标题的行时,我们可以看到以下屏幕:

十六进制表示

由于我们知道这一列使用的字符集,我们可以将其内容与描述每个字符的图表进行比较。例如,en.wikipedia.org/wiki/Latin1描述了 Latin1 字符集。

SQL 漂亮打印

术语漂亮打印en.wikipedia.org/wiki/Pretty_printing)指的是一种“美化”源代码的方式(在我们的情况下是 SQL 语句)。在 phpMyAdmin 配置存储中,pma_bookmark.querypma_history.sqlquery 列包含 SQL 语句。通过为这些列定义text/plain: sql 转换,当浏览表时,这些 SQL 语句将以带有语法高亮的颜色显示。

IP 地址

IP(v4)地址可以编码为长整型(例如,通过 PHP 的iptolong()函数),并存储到 MySQL 的UNSIGNED INT列中。要将其转换回熟悉的点分字符串(例如,127.0.0.1),可以使用text/plain: longToIpv4转换。

通过外部应用程序转换数据

先前描述的转换是直接从 phpMyAdmin 中实现的。然而,一些转换最好通过现有的外部应用程序执行。

text/plain: external 转换使我们能够将单元格的数据发送到另一个应用程序,该应用程序将在 Web 服务器上启动,捕获此应用程序的输出,并在单元格位置显示此输出。

注意

此功能仅在 Linux 或 UNIX 服务器上受支持(在 Microsoft Windows 下,输出和错误重定向不能轻松地被 PHP 进程捕获)。此外,PHP 不应该运行在安全模式下。因此,该功能可能在托管服务器上不可用。

出于安全原因,无法从 phpMyAdmin 内部设置应用程序的确切路径和名称作为转换选项。应用程序名称直接设置在 phpMyAdmin 脚本中的一个。

首先,在 phpMyAdmin 安装目录中,我们编辑libraries/transformations/中的text_plain__external.inc.php文件,并找到以下部分:

$allowed_programs = array();
//$allowed_programs[0] = '/usr/local/bin/tidy';
//$allowed_programs[1] = '/usr/local/bin/validate';

默认情况下,没有配置外部应用程序,我们必须明确添加我们自己的应用程序。

注意

转换脚本的名称采用以下格式构建——MIME 类型,双下划线,然后是指示应进行哪种转换的部分。

每个允许的程序,以及其完整路径,都必须在此处用从 0 开始的索引号描述。然后我们保存对此脚本的修改,如果需要的话将其放回服务器。其余的设置是从面板完成的,我们在那里选择其他浏览器转换的选项。

当然,我们现在在转换菜单中选择text/plain: external

作为第一个选项,我们放置应用程序编号(例如,0 表示整理应用程序)。第二个选项包含我们需要传递给此应用程序的参数。如果我们希望 phpMyAdmin 对结果应用htmlspecialchars()函数,我们将1作为第三个参数——这是默认值。我们可以将0放在那里,以避免用htmlspecialchars()保护输出。

如果我们想避免重新格式化单元格的行,我们将1作为第四个参数。这将使用NOWRAP修饰符,默认情况下会这样做。

外部应用示例:单元格排序

这个例子展示了如何对单个单元格的文本内容进行排序。我们首先修改text_plain__external.inc.php脚本,如前一节所述,添加sort程序:

$allowed_programs[0] = '/bin/sort';

请注意,我们的新程序带有索引号0

然后,我们向我们的book表添加一个名为keywordsTEXT列。最后,我们填写与 MIME 相关的信息,输入'0','-r'作为转换选项,如下截图所示:

外部应用示例:单元格排序

这里的'0'是指sort的索引号,'-r'sort的参数,使程序以相反的顺序排序。

接下来,我们编辑书籍“A hundred years of cinema (volume 1)”的行,以任意顺序输入一些关键词(如下截图所示),然后点击Go以保存更改:

外部应用示例:单元格排序

为了测试外部程序的效果,我们浏览表格并查看排序后的单元格关键词:

外部应用示例:单元格排序

请注意,关键词以相反的排序顺序显示。

总结

在本章中,我们学习了如何通过各种方法转换数据来改善浏览体验。特别是,我们看到了如何从.jpeg.pngBLOB列中显示缩略图和全尺寸图像的概述,如何生成链接,格式化日期,仅显示文本的部分,以及如何执行外部程序来重新格式化单元格内容。

下一章将介绍 phpMyAdmin 对 MySQL 5.0 和 5.1 版本中的新功能的支持。

第十七章:MySQL 5 中添加的支持功能

MySQL 5.0 引入了许多新功能,平息了许多声称 MySQL 不如竞争对手产品的开发人员和行业观察者的声音。视图、存储过程、触发器、标准的information_schema,以及(最近)性能分析机制现在都存在于 MySQL 的范围内。这些功能在本章中进行了介绍。

在 MySQL 5.1 的新功能中,与 Web 界面相关的功能(例如,分区和事件)也受到 phpMyAdmin 的支持,并在本章中进行了介绍。

支持视图

MySQL 5.0 引入了对命名和可更新视图的支持(更多详细信息可在dev.mysql.com/doc/refman/5.5/en/views.html)找到)。视图是一个派生表(将其视为虚拟表),其定义存储在数据库中。对一个或多个表(甚至是视图)执行的SELECT语句可以存储为视图,并且也可以进行查询。

视图可以用于:

  • 限制列的可见性(例如,不显示薪资信息)

  • 限制行的可见性(例如,不显示特定世界地区的数据)

  • 隐藏更改后的表结构(以便旧应用程序可以继续工作)

与在许多表上定义繁琐的特定列权限相比,更容易准备一个包含这些表中有限列集的视图。然后我们可以授予整个视图的权限。

在从 5.0 之前的版本升级后,要在服务器上激活对视图的支持,管理员必须执行mysql_upgrade程序,如 MySQL 手册中所述(dev.mysql.com/doc/refman/5.0/en/upgrading-from-previous-series.html)。

注意

每个用户必须具有适当的SHOW_VIEWCREATE_VIEW权限才能查看或操作视图。这些权限存在于全局(服务器)、数据库和表级别。

创建视图意味着用户对涉及的表具有权限,或者至少具有SELECTUPDATE等权限来操作视图中提到的所有列。

从结果创建视图

我们可以利用 phpMyAdmin 的搜索(在表级别)或查询(在数据库级别)功能来构建一个相当复杂的查询,执行它,然后轻松地从结果中创建一个视图。我们将看到这是如何完成的。

我们提到视图可以用来限制列(实际上也包括表)的可见性。假设一本书的页数是高度机密的信息。我们打开book表,点击搜索,并选择不包括page_count列的列子集(我们可能需要打开选项滑块)。

从结果创建视图

点击Go会生成一个结果页面,在查询结果操作部分我们会看到一个CREATE VIEW链接。我们使用这个链接来访问视图创建面板,其中已经有了AS框中的基础查询。我们需要为这个视图选择一个名称(这里我们使用book_public_info),并且我们可以选择为它设置不同的列名(这里我们使用number, title),如下截图所示:

从结果创建视图

其他选项可能会影响视图的行为,并在 MySQL 手册中有解释(dev.mysql.com/doc/refman/5.5/en/create-view.html)。LOCAL CHECK OPTION子句会影响可更新视图的行为(这在前面引用的 MySQL 手册页面中有解释)。

点击Go生成我们要求的视图。此时,视图已经创建。如果我们刷新浏览器的页面,然后访问marc_book数据库,我们将看到以下截图:

从结果创建视图

在主面板中,我们看到了新创建的视图的信息。目前视图的行数指示为~0(稍后在本章的控制行计数以提高性能部分中会详细介绍),类型列中显示视图。视图没有排序或大小相关联。

主面板和视图

由于视图与表相似,它的名称与普通表的名称一样。单击视图名称时,会显示一个类似于表的面板,但是菜单选项比普通表少。事实上,有些操作在视图上是没有意义的,例如导入。这是因为视图实际上不包含数据。但是,其他操作,如浏览,是完全可以接受的。

让我们浏览以下截图中显示的视图:

主面板和视图

我们注意到,在生成的 SQL 查询中,我们没有看到原始的CREATE VIEW语句。原因是我们正在使用SELECT语句从视图中进行选择,隐藏了我们从视图中提取数据的事实。然而,导出视图的结构将显示 MySQL 如何内部存储我们的视图:

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `book_public_info` AS
select `book`.`isbn` AS `number`,`book`.`title` AS `title` from `book`;

主面板的菜单可能看起来类似于表的菜单。但是在必要时,phpMyAdmin 会生成处理视图的适当语法。

注意

要对现有视图执行操作,用户需要在视图级别具有适当的权限,但不一定需要在涉及此视图的表上具有任何权限。这是我们可以实现列和表的隐藏。

控制行计数以提高性能

phpMyAdmin 有一个配置参数$cfg['MaxExactCountViews'],用于控制 phpMyAdmin 的行计数阶段。有时,一个视图包含许多巨大的表,浏览它会导致大量的虚拟行出现。因此,该参数的默认值为 0 确保视图不进行行计数。在这种情况下,当浏览视图时,我们会看到相当奇怪的结果:显示行 0 - -1(共 0 行,查询耗时 0.0006 秒)。这比减慢服务器速度更可接受。

尽管如此,如果我们希望看到视图的更准确的行数,我们可以在该参数中放入一个较大的值,该值作为行计数阶段的上限。

支持例程-存储过程和函数

phpMyAdmin 在开始支持存储过程和函数之前花了一些时间。原因是这些是作为数据库的一部分保存的代码块(类似于子程序)。作为一个 Web 界面的 phpMyAdmin 更倾向于使用鼠标快速执行的操作。

尽管如此,phpMyAdmin 有一些功能允许开发人员创建这样的例程,保存它们,调用它们进行一些修改,并删除它们。

通过CALL语句访问存储过程,我们可以传递参数(更多细节请参阅dev.mysql.com/doc/refman/5.5/en/call.html))。另一方面,函数可以从 SQL 语句(例如SELECT)中访问,并且类似于其他 MySQL 内部函数,因此返回一个值。

需要CREATE ROUTINEALTER ROUTINE权限才能创建、查看和删除存储过程或函数。需要EXECUTE权限来运行例程,尽管该权限通常会自动授予例程的创建者。

创建存储过程

我们将创建一个过程,通过添加特定数量的页面来更改特定书籍的页数。该过程的输入参数是书籍的 ISBN 和要添加的页数。我们正在使用 SQL 查询框(参考第十一章)来输入这个过程。

更改分隔符

标准的 SQL 分隔符是分号,这个字符将被用来在我们的存储过程中分隔 SQL 语句。然而,CREATE PROCEDURE语句本身就是一个 SQL 语句;因此,我们必须想办法告诉 MySQL 解析器这个语句在哪里结束。查询框中有一个分隔符输入框,默认包含一个分号。因此,我们将其更改为另一个字符串,按照惯例是双斜杠"//"

更改分隔符

输入存储过程

然后我们在主查询框中输入存储过程的代码:

CREATE PROCEDURE `add_page`(IN param_isbn VARCHAR(25),
IN param_pages INT, OUT param_message VARCHAR(100))
BEGIN
IF param_pages > 100 THEN
SET param_message = 'the number of pages is too big';
ELSE
UPDATE book SET page_count = page_count + param_pages WHERE
isbn=param_isbn;
SET param_message = 'success';
END IF;
END
//

点击Go,如果语法正确,我们会收到一个成功消息。如果不正确,那么是时候检查我们的打字能力或调试我们的语法了。不幸的是,MySQL 没有存储过程调试器。

测试存储过程

同样,在查询框中,我们通过输入以下语句来测试我们的存储过程。在这里,我们使用了一个 SQL 变量@message,它将接收OUT参数param_message的内容:

call add_page('1-234567-22-0', 4, @message);
SELECT @message;

如果一切顺利,我们应该看到@message变量包含success

然后我们可以验证这本书的页数是否增加了。我们还需要测试有问题的情况:

call add_page('1-234567-22-0', 101, @message);
SELECT @message;

现在可以调用这个存储过程(例如)从您的 PHP 脚本中使用mysqli扩展,这是推荐的访问 MySQL 4.1 及以上版本提供的所有功能的扩展。

操作存储过程和函数

存储过程存储在数据库中,不与特定表绑定。因此,用于操作存储过程和函数的接口可以在数据库级别找到,在结构页面下的例程滑块下,如果已经定义了至少一个例程,则会出现该滑块。

操作存储过程和函数

第一个图标将这个存储过程的文本带入查询框进行编辑。第二个图标用于删除这个存储过程。在编辑存储过程时,我们注意到文本已经被稍微修改。

DROP PROCEDURE `add_page`//
CREATE DEFINER=`marc`@`%` PROCEDURE `add_page`(IN param_isbn VARCHAR(25), IN param_pages INT, OUT param_message VARCHAR(100))
BEGIN
IF param_pages > 100 THEN
SET param_message = 'the number of pages is too big';
ELSE
UPDATE book SET page_count = page_count + param_pages WHERE
isbn=param_isbn;
SET param_message = 'success';
END IF;
END

首先出现一个DROP PROCEDURE语句。这是正常的,因为 MySQL 没有提供一个允许更改存储过程主体的语句。因此,我们必须每次想要更改它时删除一个存储过程。ALTER PROCEDURE语句确实存在,但它只能改变存储过程的特性,例如添加注释。然后,显示了一个DEFINER子句。它是在创建时生成的,指示谁创建了这个存储过程。

在这一点上,我们对代码进行任何需要的更改,并点击Go来保存这个存储过程。

注意

也许会有诱惑打开结构页面上的book表,查找操作这个表的存储过程列表,比如我们的add_page()存储过程。然而,所有存储过程都存储在数据库级别,代码本身(UPDATE book)和存储过程存储的地方之间没有直接的链接。

手动创建一个函数

函数类似于存储过程。然而,函数可能只返回一个值,而存储过程可以有多个OUT参数。另一方面,从SELECT语句中使用存储函数可能更自然,因为它避免了需要一个中间的 SQL 变量来保存OUT参数的值。

函数的目标是什么?例如,函数可以用来计算订单的总成本,包括税费和运费。将这个逻辑放在数据库中而不是在应用程序级别有助于记录应用程序-数据库接口。它还避免了在每个需要处理这个逻辑的应用程序中重复业务逻辑。

我们不应该混淆 MySQL 5.0 函数和UDF(用户定义函数),它们存在于 MySQL 5.0 之前。UDF 由用 C 或 C++编写的代码组成,编译成共享对象,并通过CREATE FUNCTION语句和SONAME关键字引用。

phpMyAdmin 对函数的处理在许多方面类似于我们在例程中所涵盖的内容:

  • 一个查询框,用于输入函数

  • 使用分隔符

  • 操作已定义的函数的机制

让我们定义一个函数,根据其代码检索国家名称。我更喜欢在函数定义内清楚地标识参数使用param_前缀和局部变量使用var_前缀。我们将使用我们信任的 SQL 查询框再次输入函数的代码,并指示该框使用//作为分隔符。

CREATE FUNCTION get_country_name(param_country_code CHAR(2))
RETURNS VARCHAR(50)
READS SQL DATA
BEGIN
DECLARE var_country_name VARCHAR(50) DEFAULT 'not found';
SELECT description
FROM country
WHERE code = param_country_code
INTO var_country_name;
RETURN var_country_name;
END
//

我们应该注意,我们新创建的函数可以在数据库的结构页面上看到,以及它的朋友add_page过程:

手动创建函数

测试函数

要测试我们刚刚创建的函数,请在查询框中输入以下查询(参见[第十一章]:(ch11.html "第十一章。输入 SQL 语句"))

SELECT CONCAT('ca->', get_country_name('ca'), ', zz->',
get_country_name('zz')) as test;

这将产生以下结果:

ca->Canada, zz->not found

导出存储过程和函数

在导出数据库时,存储过程和函数会出现在 SQL 导出中。这是因为在导出页面的对象创建选项对话框中默认选择了添加 CREATE PROCEDURE / FUNCTION / EVENT复选框(在自定义导出模式中可以看到)。以下是与存储过程和函数相关的导出文件部分:

DELIMITER $$
--
-- Procedures
--
CREATE DEFINER=`marc`@`%` PROCEDURE `add_page`(IN param_isbn
VARCHAR(25), IN param_pages INT, OUT param_message VARCHAR(100))
BEGIN
IF param_pages > 100 THEN
SET param_message = 'the number of pages is too big';
ELSE
UPDATE book SET page_count = page_count + param_pages WHERE
isbn=param_isbn;
SET param_message = 'success';
END IF;
END$$
--
-- Functions
--
CREATE DEFINER=`marc`@`%` FUNCTION `get_country_name`
(param_country_code CHAR(2)) RETURNS varchar(50) CHARSET latin1
READS SQL DATA
BEGIN
DECLARE var_country_name VARCHAR(50) DEFAULT 'not found';
SELECT description into var_country_name FROM country WHERE
code = param_country_code;
RETURN var_country_name;
END$$
DELIMITER ;

执行触发器代码

触发器是我们与表关联的代码,当发生某些操作时执行,例如,在book表中的新INSERT语句之后。操作不需要在 phpMyAdmin 中发生。

与与整个数据库相关的例程不同,每个表的触发器可以从该特定表的结构页面访问。

注意

在 MySQL 5.1.6 之前,我们需要SUPER权限来创建和删除触发器。在 5.1.6 版本中,特权系统中添加了TRIGGER表级特权。因此,用户不再需要强大的SUPER权限来执行这些任务。

为了执行以下练习,我们将需要在我们的author表中添加一个新的INTtotal_page_count

这里的想法是,每次创建一本书时,它的页数将被添加到该作者的书的总页数中。有些人可能主张最好不要为总数保留单独的列,而是在需要时每次计算总数。实际上,在处理这种情况时必须做出设计决策。我们是否需要非常快速地检索总页数,例如用于网页目的?从具有数千行的生产表中计算此值的响应时间是多少?无论如何,由于我需要它作为一个例子,这里的设计决策很容易做出。

我们不要忘记,在将其添加到表的结构后,total_page_count列应该最初用正确的总数进行填充。(但是,这不是我们触发器的目的。)

手动创建触发器

当前的 phpMyAdmin 版本没有触发器创建界面。因此,我们在查询框中输入触发器定义时要特别注意在分隔符框中输入//

CREATE TRIGGER after_book_insert AFTER INSERT ON book
FOR EACH ROW
BEGIN
UPDATE author
SET total_page_count = total_page_count + NEW.page_count
WHERE id = NEW.author_id;
END
//

稍后,我们的book表的结构页面显示了一个新的触发器部分,可以像例程一样使用,用于编辑或删除触发器,如下面的屏幕截图所示:

手动创建触发器

测试触发器

与测试存储过程或函数相反,触发器中没有CALL序列,也没有在SELECT语句中执行触发器的函数。每当发生定义的操作(例如书籍INSERT)时,代码将执行(在我们的案例中是在插入后)。因此,我们只需插入一本新书,就可以看到author.total_page_count列被更新。

当然,完全自动管理此列将涉及在book表上创建AFTER UPDATEAFTER DELETE触发器。

使用 information_schema

在 SQL:2003 标准中,通过称为information_schema的结构提供对数据字典(或数据库元数据)的访问。由于这是标准的一部分,并且已经存在于其他数据库系统中,决定将此功能实现到 MySQL 中是一个非常好的决定。

注意

MySQL 添加了一些标准之外的信息,例如INFORMATION_SCHEMA.COLUMNS.COLUMN_TYPE。请注意,如果您在软件项目中使用此信息,可能无法在其他 SQL 实现中移植。

phpMyAdmin 用户将information_schema视为包含视图的普通数据库。这些视图描述了托管在此服务器上的数据库结构的许多方面。以下屏幕截图显示了可以看到的部分内容(实际上,对于此数据库唯一可能的操作是SELECT):

使用 information_schema

在内部,phpMyAdmin 可以调用information_schema,而不是相应的SHOW语句来检索元数据。这种行为由$cfg['Servers'][$i]['DisableIS']指令控制。当服务器托管数百个数据库或表时,一些涉及information_schemaWHERE子句的SELECT操作非常慢(等待时间长达几分钟),而 MySQL 团队尚未解决这个问题;这就是为什么此指令默认设置为true,从而避免使用information_schema

$cfg['Servers'][$i]['hide_db']参数可用于隐藏这个对于对 MySQL 水平不够熟悉的用户来说突然出现的数据库。这可能取决于他们在 MySQL 中的专业水平。在 phpMyAdmin 的多用户安装中,我们无法满足每个人对于此参数值的期望。

分区

MySQL 5.1 提供了用户定义的分区(参考dev.mysql.com/doc/refman/5.1/en/partitioning.html)。它允许我们根据需要设置规则,将表的部分分布到文件系统中。在 phpMyAdmin 中使用此功能需要了解其语法,因为有许多分区类型。此外,对于每种分区类型,分区的数量和与每个分区关联的值过于随机,无法在 Web 界面上轻松表示。

创建带有分区的表

让我们尝试通过创建名为test的表并添加一个id列来测试。在连接到 MySQL 5.1 服务器时,如果在表创建面板上,phpMyAdmin 会显示一个分区定义对话框,如下屏幕截图所示:

创建带有分区的表

在这里,我们输入一个PARTITION BY RANGE子句,它将在id列上创建分区:

PARTITION BY RANGE (id) (
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN (30000)
);

维护分区

对于已定义分区的表,操作页面显示了一个分区维护对话框,我们可以:

  • 选择一个分区,然后请求一个操作,比如重建

  • 移除分区

维护分区

导出分区定义

最后,在 SQL 模式下导出此test表会生成带有嵌入式注释的语句,MySQL 5.1 服务器将识别并解释这些语句以重新创建相同的分区:

CREATE TABLE `test` (
`id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id)
(PARTITION p0 VALUES LESS THAN (1000) ENGINE = MyISAM,
PARTITION p1 VALUES LESS THAN (2000) ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN (3000) ENGINE = MyISAM) */;

探索事件调度程序

事件调度程序(dev.mysql.com/doc/refman/5.1/en/events.html),是 MySQL 5.1 的另一个新功能,允许创建根据时间表自动运行的任务。时间表非常灵活,允许例如,从 2011 年 5 月 18 日午夜开始,每十秒运行一次语句。这些可以是一次性事件或定期事件。

激活调度程序

我们应该首先验证调度程序是否在我们的服务器上处于活动状态。如果没有,我们需要激活它。否则,什么也不会发生!我们将首先在查询框中输入以下语句:

SHOW VARIABLES LIKE 'event%';

接下来,我们在结果中查找名为event_scheduler的变量。如果此变量设置为OFF,我们需要要求系统管理员(或具有SUPER特权的人)执行以下语句:

SET GLOBAL event_scheduler = ON;

授予 EVENT 权限

每个想要创建或删除事件的用户都需要EVENT权限,可以是全局的,也可以是计划添加事件的数据库上的权限。有关授予此类权限的详细信息,请参阅第十九章。

创建事件

当前的 phpMyAdmin 版本没有一个界面,我们可以在其中选择CREATE EVENT语句的各个部分。因此,唯一剩下的方法是使用 SQL 查询框来输入语句并理解其语法!在这里,我们将使用一个完全虚构的例子:

CREATE EVENT add_page_count
ON SCHEDULE
EVERY 1 MINUTE
DO
UPDATE author set total_page_count = total_page_count + 1
WHERE id = 1;

现在,您可以偶尔浏览author表,看到作者 1 的计数器递增,从而获得一些乐趣。

操作事件

事件与单个数据库相关,这就是为什么在marc_book数据库的Structure页面上看到一个Events滑块。激活它会显示以下面板:

操作事件

事实上,这是一个经常发生的事件。我们可以使用第一个图标来编辑事件(这将导致删除和重新创建事件),使用第二个图标来删除事件。

导出

可以通过选择Add CREATE PROCEDURE / FUNCTION / EVENT选项,在 SQL 数据库导出文件的末尾生成与事件相关的语句。请记住,一些事件可能有过期时间。因此,除非在创建事件时使用了ON COMPLETION PRESERVE子句,否则它们可能在您创建它们和尝试导出它们之间消失。

总结

MySQL 5.0 的新功能帮助产品符合标准。尽管 phpMyAdmin 对这些功能的支持有限(尤其是缺乏面向语法的编辑器),但它具有一组基本的功能,可用于处理视图、例程、触发器和information_schema。phpMyAdmin 还支持 MySQL 5.1 的分区和事件。

下一章介绍了使用跟踪功能,允许通过 phpMyAdmin 记录对 MySQL 数据库所做的更改。

第十八章:跟踪变化

本章将研究如何使用跟踪机制,以记录从 phpMyAdmin 界面进行的结构和数据更改,并获取有关此类更改的报告。

了解跟踪系统的目标

每个软件应用程序都有自己的想法,对于其用户来说,跟踪哪些变化是重要的。本节描述了其他应用程序中存在的跟踪系统,并将它们与 phpMyAdmin 提供的系统进行了比较。

其他软件应用程序中的跟踪

访问显示信息系统的所有更改的历史数据是许多软件产品中被视为理所当然的功能。任何严肃的文字处理软件的“撤消”功能就是能够回到过去的一个例子,尽管是一步一步的。更复杂的例子是 MediaWiki 的历史功能(维基百科的核心软件)。它使我们能够回到给定页面的任何状态,查看任何两个版本之间的更改,甚至将任何旧版本标记为当前版本。跟踪信息包括作者(或 IP 地址)、更改的日期和时间以及评论。

在 MySQL 本身中,日志系统(binlog)记录对数据库所做的所有更改;但是,在这种情况下,目标是双重的:

  • 允许主从同步

  • 通过mysqlbinlog命令行实用程序启用恢复

phpMyAdmin 中的跟踪

phpMyAdmin 的跟踪系统允许用户指定要跟踪的表,因此可以称为选择加入系统。默认情况下,除非开发人员选择这样做,否则不会跟踪任何表;当开发人员为表激活跟踪时,即使由其他人执行,更改也开始记录。只记录通过 phpMyAdmin 进行的更改。

此外,对于给定的表,我们可以指示我们有兴趣跟踪哪些语句。语句列表分为两组:数据定义和数据操作。

假设一个团队正在进行涉及对表结构进行更改的项目。启用跟踪并假设每个开发人员都使用自己的帐户登录到 MySQL,现在我们可以访问历史数据,包括有关哪个开发人员删除了一些关键列的信息!当然,这种跟踪并不是防篡改的;毕竟,它存储在 MySQL 表中,因此此跟踪信息的安全性取决于谁可以访问跟踪表。

先决条件

phpMyAdmin 配置存储包含跟踪机制的所有元数据。如果我们之前实现了此存储(例如,对于以前的 phpMyAdmin 版本,如 3.1 或更早版本),我们可以使用当前 phpMyAdmin 版本的scripts/create_tables.sql来升级配置存储,以添加缺少的表(在我们的情况下,pma_tracking表)。原因是该脚本通过使用CREATE TABLE IF NOT EXISTS pma_tracking``语句谨慎地创建此表,从而确保如果表已经存在,则不会创建该表。

注意

在 phpMyAdmin 3.3.3 中,pma_tracking中的data_sql列的类型从TEXT更改为LONGTEXT,在create_tables.sql脚本中。因此,如果我们在 3.3.3 版本之前运行了此脚本,重要的是在我们自己的pma_tracking表中手动进行此更改。

配置基本跟踪机制

config.inc.php中,对于特定 MySQL 服务器的配置,$cfg['Servers'][$i]['tracking']应包含跟踪表的名称;建议的名称是pma_tracking,以匹配scripts/create_tables.sql中的默认值。

注意

如果此指令留空,则在此服务器上无法进行跟踪(我们将看不到跟踪菜单)。

默认情况下,跟踪必须针对每个表进行激活。如果我们希望跟踪机制自动开启所有未来的表和视图,可以将$cfg['Servers'][$i]['tracking_version_auto_create']设置为TRUE。请注意,这仅适用于未来的表和视图——我们仍然需要为现有的表激活跟踪。

使用自动创建的优势在于我们不必考虑它;跟踪是从表的诞生开始的。这种不便之处是我们无法选择要跟踪的语句;这些将从默认列表中获取(请参阅本章后面的“选择要跟踪的语句”部分)。

其他配置指令将在相关部分中讨论。

原则

本节定义了跟踪机制的重要原则:版本控制、快照和跟踪信息的归档问题。

版本控制

使用版本号是我们熟悉的事情;例如,本书描述了 phpMyAdmin 版本 3.4.x。然而,在这一点上,我们必须确切地理解为什么要使用版本号。

关于软件版本控制的良好参考资料可以在维基百科的en.wikipedia.org/wiki/Software_versioning找到。这篇文章提到可以使用版本名称,但版本号更常见。更重要的是,它指出版本号“对应于软件的新发展”。

如果我们将这个原则应用到数据库开发中,那么当一个表即将发生重大变化时,决定是否为该表创建新版本应该由开发团队做出。触发新版本的变化有多重要是团队内部解释的问题。至少有一个决定是容易做出的:版本 1 始终代表我们首次为特定表启用跟踪的时刻。

在跟踪数据操作语句的情况下,我们还应该注意到变化可能与数据本身有关,而不一定与结构有关。

注意

phpMyAdmin 的跟踪系统只使用正整数作为版本号;不可能使用小数点,比如"1.1"。

拍摄当前结构的快照

每次创建新版本时,跟踪系统都会拍摄表的当前结构和索引的快照,并在跟踪系统中创建一个新条目。在这个条目中存储了数据库名称、表名称、版本号、创建日期和完整的结构信息。

注意

这个跟踪快照不包含表的数据!因此,跟踪系统不能替代备份系统。

在快照被拍摄后,表的整个生命周期中,所有被跟踪的语句都会与这个快照一起存储。因此,表的跟踪版本包括快照以及在拍摄快照后进行的所有更改,直到启动新版本。

理解归档问题

当一个表被删除时,它的跟踪信息会被保留,除非我们决定将其删除。这个影响将在后面的“删除跟踪信息”部分中讨论。

启动单个表的跟踪

在这一部分,我们将在“表”视图中使用“跟踪”菜单来开始收集author表发生的变化。因此,我们打开author表,然后点击“跟踪”,会出现以下屏幕:

启动单个表的跟踪

这个面板告诉我们,我们即将创建表的版本 1;这是我们预期的。我们可以选择数据定义和数据操作语句;现在我们将它们全部标记,然后点击“创建版本”按钮。下一部分将解释如何指定要在上面显示的面板中出现的语句。

创建版本 1 后,会显示以下确认面板:

为一个表启动跟踪

我们注意到发生了两个不同的动作:

  • 版本 1 本身的创建

  • 为这个表激活跟踪

实际上,一个表可能存在一个或多个版本,每个版本包含从某个时间点开始的快照和自此快照以来的更改;但这与表是否处于跟踪状态并且更改正在记录无关。

在这个面板中,我们看到将在选择要跟踪的语句停用和启用跟踪部分中涵盖的子面板。

选择要跟踪的语句

$cfg['Servers'][$i]['tracking_default_statements']包含一个由逗号分隔的字符串。这些是在我们可以选择要跟踪哪些语句的面板中提供的语句。默认语句列表定义如下;请注意 PHP 中允许字符串连接的点字符的存在:

$cfg['Servers'][$i]['tracking_default_statements'] =
'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,' .
'CREATE INDEX,DROP INDEX,' .
'INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,' .
'CREATE VIEW,ALTER VIEW,DROP VIEW,' .
'CREATE DATABASE,ALTER DATABASE,DROP DATABASE';

测试跟踪机制

我们现在准备验证这个跟踪系统是否真的有效!由于系统应该跟踪ALTER TABLE语句,我们将进行一个轻微的结构更改,看看会发生什么。我们转到作者表的结构面板,选择姓名列,并将其大小从30增加到40个字符(详细步骤请参阅第五章)。

我们会收到一条消息,如下截图所示:

测试跟踪机制

我们将执行另一个动作,这次与数据本身有关——将作者John Smith的电话号码更改为111-2222

为了确保这些动作被跟踪系统记录下来,让我们编制一份报告。

跟踪报告

回到跟踪面板(仍然在作者视图中),我们点击版本 1 的跟踪报告,生成如下截图所示的报告:

跟踪报告

实际上,报告是附加在主要跟踪信息之前的;我们可以点击关闭,回到之前的位置。

我们可以看到,在跟踪报告标题下,显示了被跟踪的语句列表。然后我们有一个选择器,确定我们是否要在报告中查看与之对应的语句:

  • 结构和数据

  • 仅结构

  • 仅数据

我们还可以指定要生成报告的日期和时间范围。还可以指示我们要报告的用户(星号代表所有用户)。

报告的主要部分包括语句本身;这里我们看到四个语句。第一个语句是一个DROP TABLE语句,如果我们需要导出这个版本并将其重新导入,这将有用。第二个语句(CREATE TABLE)包含了在初始化版本 1 时拍摄的快照。然后我们看到对应于我们执行的操作的ALTER TABLEUPDATE语句。

如何导出结构将在本章后面的导出版本部分中介绍。

确定跟踪状态

让我们覆盖界面中所有可以确定表的跟踪活动的地方。首先,在视图中,我们可以看到一个消息,位于菜单选项卡下方,说明对于这个表,跟踪已激活,如下截图所示:

确定跟踪状态

跟踪面板本身,状态列告诉我们最新版本的跟踪是激活还是未激活。实际上,当我们为表创建另一个版本时,我们会发现只有当前版本可以具有激活的跟踪状态,因为以前的版本现在只包含历史数据。

确定跟踪状态

数据库视图中,系统跟踪的每个表(具有活跃或非活跃状态)都显示为一个眼睛图标,颜色或灰色取决于其状态。在下面的示例中,眼睛是彩色的:

确定跟踪状态

这个眼睛图标是可点击的,可以将我们带到这个特定表的跟踪面板。

最后,在数据库视图中,跟踪菜单为我们提供了所有表的概览。首先呈现被跟踪的表,然后是未被跟踪的表。对于任何一类别,我们都有链接可以查看更多信息或开始跟踪:

确定跟踪状态

对于被跟踪的表,以下表格提供了所呈现信息的细分,以及可用的链接:

标题或链接 描述
数据库 表位于哪个数据库
被跟踪的表
最新版本 最新的被跟踪版本;看到这个表有多少版本存在很有趣
创建时间 此版本创建时间
更新时间 上次为此表存储的跟踪语句是什么时候
状态 活跃或非活跃
操作 删除链接可用于删除所有跟踪(请参阅本章后面的删除跟踪信息部分)
显示 | 版本 进入此表的视图,并显示跟踪版本
显示 | 跟踪报告 进入此表的视图,并显示跟踪报告
显示 | 结构快照 进入此表的视图,并显示结构快照(请参阅本章后面的结构快照部分)

对于未被跟踪的表,跟踪表链接允许我们直接在跟踪面板中进入此表的视图,从而创建版本 1 以开始跟踪机制。

停用和激活跟踪

从特定表的跟踪页面,立即停用按钮(作为切换,变为立即激活) 是我们希望停止(暂时或永久)进一步存储跟踪语句的按钮。存储的过去语句将保持不变,与当前版本相关的跟踪数据。

结构快照

视图的跟踪面板中,结构快照链接显示了在创建此版本时表的过去状态。该面板显示了存储的 SQL 代码以及熟悉的 phpMyAdmin 结构面板格式的可视化表示。

结构快照

导出版本

由于在创建特定版本时存储了完整的 SQL 代码以及自那时起发生的所有跟踪语句,我们可能希望以可执行形式重用它们。在跟踪报告面板的底部,有一个导出为对话框可用,提供了三种导出变体。如果我们选择SQL 转储(文件下载)菜单选项,那么为此版本存储的所有语句将转移到一个文件中,我们可以保存到我们的工作站。对于author表,这将产生一个包含以下行的文件:

# Tracking report for table `author`
# 2011-10-14 14:24:12
DROP TABLE IF EXISTS `author`;
CREATE TABLE `author` (
`id` int(11) NOT NULL,
`name` varchar(30) NOT NULL,
`phone` varchar(30) CHARACTER SET latin1 DEFAULT NULL,
`country_code` char(2) NOT NULL,
`total_page_count` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `author` CHANGE `name` `name` VARCHAR(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
UPDATE `author` SET `phone` = '111-2222' WHERE `author`.`id` = 1;

如果我们选择SQL 转储选项,语句将显示在屏幕上的文本区域中;从这一点上,我们可以剪切和粘贴 SQL 代码或点击Go来运行它。作为预防措施,额外的语句会在代码的顶部生成;这些语句处理了在其中表将被创建的另一个数据库的创建。当然,用户必须有创建此数据库的权限。

最后,SQL 执行选项允许直接执行当前数据库中存储的语句。但是,由于这些语句可能反映表的旧状态,因此会发出警告消息;我们可能不想恢复到这个旧状态。此外,默认情况下,第一个语句是DROP TABLE,这取决于是否有外键约束阻止删除表。

创建一个新版本

如前所述,我们可以决定为某个表标记一个新的里程碑;换句话说,我们可以开始一个新版本。现在我们将创建一个新版本作为练习。

author表的跟踪面板中,我们看到了创建版本 2的对话框(因为最高的是当前版本 1):

创建一个新版本

我们注意到每个版本可以跟踪自己的一组语句;在这方面,版本是彼此独立的。在这里,我们决定版本 2 将仅跟踪数据定义语句。现在我们看到了与这些版本的状态相关的一些有趣的东西,如下面的屏幕截图所示:

创建一个新版本

实际上,版本 1 被自动标记为不活跃;它进入了某种历史状态。我们还可以查看版本 2 的快照,其中反映了name列是VARCHAR(40)

快速访问跟踪信息

当我们在一个表的跟踪面板中时,一个快捷对话框允许我们直接转到任何其他已跟踪表的跟踪面板。

为了探索这个功能,让我们现在创建book表的版本 1。完成后,我们检查显示版本按钮旁边的下拉列表,如下面的屏幕截图所示:

快速访问跟踪信息

这个列表与查看跟踪面板中数据库marc_book已跟踪表部分时所看到的类似,但无需返回到此面板。

删除跟踪信息

跟踪系统的一个特性可能不明显的是,当相应的表被删除时,表的所有版本以及其整个生命周期的跟踪信息仍然保留。原因是保持历史信息完整,以防我们以后创建具有相同名称的表。

让我们复制author表(如果需要,请参阅第九章),并将其命名为author_copy。然后我们在这个新表上激活跟踪。最后一个操作是删除author_copy表。即使我们在正常的表列表中不再看到它,在数据库marc_book跟踪面板中却不同。

删除跟踪信息

此时,我们可以回到过去,看看已删除表的版本的跟踪报告和快照。如果我们真的想要删除表曾经存在的所有证据,那么我们可以使用删除链接来销毁跟踪数据(在随后的确认面板中单击确定后)。

总结

在本章中,我们概述了语句跟踪功能所带来的好处,然后介绍了用于创建和维护表版本的所有面板。

下一章将涵盖 MySQL 服务器的管理,重点是管理用户帐户和权限。

第十九章:管理 MySQL 服务器

本章讨论了系统管理员如何使用 phpMyAdmin 服务器管理功能进行日常用户帐户维护、服务器验证和服务器保护。还涵盖了非管理员如何从 phpMyAdmin 获取服务器信息的主题。

服务器管理主要通过服务器视图完成,可以通过 phpMyAdmin 主页上可用的菜单选项卡访问。

管理用户及其权限

权限页面(仅在我们以特权用户身份登录时可见)包含了管理 MySQL 用户帐户的对话框。它还包含了管理全局、数据库和表级别权限的对话框。此页面是分层的。在编辑用户的权限时,我们可以看到全局权限以及特定于数据库的权限。然后,在查看用户的特定于数据库的权限时,我们可以查看并编辑该用户在该数据库中的任何表的权限。

用户概述

当我们进入权限页面时显示的第一页称为用户概述。这显示了所有用户帐户及其全局权限的摘要,如下面的屏幕截图所示:

用户概述

从这个页面,我们可以:

  • 通过编辑权限链接编辑用户的权限

  • 通过用户导出链接导出用户的权限定义

  • 使用复选框通过删除所选用户对话框删除用户

  • 访问添加新用户对话框可用的页面

显示的用户列表具有以下特征的列:

特征
用户 我们正在定义的用户帐户。
主机 此用户帐户将连接到 MySQL 服务器的机器名称或 IP 地址。这里的%值表示所有主机。
密码 如果定义了密码,则包含,如果没有定义,则包含。密码本身无法从 phpMyAdmin 的界面或直接查看mysql.user表中看到,因为它是使用单向哈希算法加密的。
全局权限 用户的全局权限列表。
授权 如果用户可以将他/她的权限授予他人,则包含
操作 包含一个链接,用于编辑此用户的权限或导出它们。

导出权限

这个功能在我们需要在另一个 MySQL 服务器上创建具有相同密码和权限的用户时非常有用。单击导出用户marc会产生以下面板:

导出权限

然后只需选择这些GRANT语句,并将它们粘贴到另一个已登录到另一个 MySQL 服务器的 phpMyAdmin 窗口的 SQL 框中。

权限重新加载

用户概述页面底部显示了以下消息:

Note: phpMyAdmin gets the users' privileges directly from MySQL's privilege tables. The content of these tables may differ from the privileges the server uses, if they have been changed manually. In this case, you should reload the privileges before you continue.

在这里,“重新加载权限”文本是可点击的。有效权限(服务器基于其访问决策的权限)是位于服务器内存中的权限。从用户概述页面进行的权限修改在内存中和mysql数据库中都进行了修改。直接对mysql数据库进行的修改不会立即生效。重新加载权限操作会从数据库中读取权限,并使其在内存中生效。

添加用户

添加新用户链接打开了一个用户帐户创建对话框。首先,我们看到的是我们将描述帐户本身的面板,如下面的屏幕截图所示:

添加用户

添加新用户对话框的第二部分是我们将指定用户的全局权限的地方,这些权限适用于整个服务器(请参阅本章的分配全局权限部分),如下面的屏幕截图所示:

添加用户

输入用户名

用户名菜单提供两个选择。我们可以选择使用文本字段:并在框中输入用户名,或者我们可以选择任何用户来创建匿名用户(空用户)。有关匿名用户的更多详细信息,请参见dev.mysql.com/doc/refman/5.5/en/connection-access.html。让我们选择使用文本字段:并输入bill

分配主机值

默认情况下,此菜单设置为任何主机,主机值为%本地选择意味着localhost使用主机表选择(在主机字段中创建空值)意味着在mysql.host表中查找特定于数据库的权限。选择使用文本字段:允许我们输入我们想要的确切主机值。让我们选择本地

设置密码

即使可以创建一个没有密码的用户(选择无密码选项),最好还是有一个密码。我们必须输入两次(因为我们看不到输入的内容)以确认预期的密码。安全密码应该有超过八个字符,并且应该包含大写和小写字母,数字和特殊字符的混合。因此,建议使用 phpMyAdmin 生成密码-这在启用 JavaScript 的浏览器中是可能的。在生成密码对话框中,点击生成按钮会在屏幕上输入一个随机密码(明文),并在密码重新输入输入字段中填入生成的密码。在这一点上,我们应该记住密码,以便将其传递给用户。

理解数据库创建的权限

一个常见的约定是将用户的权限分配给与该用户同名的数据库。为了实现这一点,用户数据库部分提供了创建具有相同名称并授予所有权限的数据库单选按钮。选择此复选框会自动化该过程,通过创建数据库(如果尚不存在)并分配相应的权限。请注意,使用此方法,每个用户将被限制为一个数据库(用户bill,数据库bill)。

另一种可能性是允许用户创建具有与其用户名相同前缀的数据库。因此,另一个选择授予通配符名称(username_%)的所有权限通过分配通配符权限来执行此功能。有了这个设置,用户bill可以创建数据库bill_test, bill_2, bill_payroll等;在这种情况下,phpMyAdmin 不会预先创建数据库。

分配全局权限

全局权限决定用户对所有数据库的访问权限。因此,有时这些被称为超级用户权限。普通用户不应该拥有这些权限,除非有充分的理由。此外,如果拥有全局权限的用户帐户受到损害,损害可能会更大。

如果我们真的在创建一个超级用户,我们将选择他或她需要的每个全局权限。这些权限进一步分为数据,结构管理组。

在我们的例子中,bill将不会拥有任何全局权限。

限制使用的资源

我们可以限制此用户在此服务器上使用的资源(例如,每小时的最大查询数)。零表示没有限制。我们不会对bill施加任何资源限制。

以下屏幕截图显示了在点击创建用户之前创建此用户定义的屏幕状态(其余字段设置为默认值):

限制使用的资源

编辑用户配置文件

每当我们在用户概述页面上为用户点击编辑权限时,用于编辑用户配置文件的页面就会出现。让我们尝试为我们新创建的用户bill尝试一下。此页面有四个部分,每个部分都有自己的Go按钮。因此,每个部分都是独立操作的,并且具有不同的目的。

编辑全局权限

编辑用户权限的部分与添加新用户对话框看起来一样,并用于查看和更改全局权限。

分配特定于数据库的权限

在这个部分,我们定义用户可以访问的数据库,以及他/她在这些数据库上的确切权限。

分配特定于数据库的权限

如前面的截图所示,我们看到None,因为我们尚未定义任何权限。定义数据库权限有两种方式。首先,我们可以从下拉菜单中选择一个现有的数据库,如下截图所示:

分配特定于数据库的权限

这仅为所选数据库分配权限。其次,我们还可以选择使用文本字段:并输入数据库名称。我们可以输入一个不存在的数据库名称,以便用户稍后可以创建它(前提是我们在下一个面板中给予他/她CREATE权限)。我们还可以使用特殊字符,如下划线和百分号,作为通配符。

例如,在这里输入bill会使他能够创建一个bill数据库,输入bill%会使他能够创建以bill开头的任何名称的数据库。在我们的例子中,我们将输入bill并点击Go

下一个屏幕用于设置billbill数据库上的权限,并创建特定于表的权限。

要了解特定权限的含义,我们可以将鼠标悬停在权限名称上(始终为英文),并且会出现关于此权限的解释。我们在这个数据库上给予bill SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEXDROP权限,然后点击Go

分配特定于数据库的权限

在分配了权限之后,界面仍停留在原地,以便我们可以进一步细化这些权限。目前我们无法分配特定于表的权限,因为数据库尚不存在。

要返回到bill的一般权限页面,请点击'bill'@'localhost'标题。

这将使我们回到以下熟悉的页面,除了一个部分的变化:

分配特定于数据库的权限

我们看到billbill数据库上的现有权限(我们可以点击编辑权限链接进行编辑,或点击撤销链接进行撤销),并且我们可以为bill在另一个数据库上添加权限。我们还可以看到billbill数据库上没有特定于表的权限。

更改密码

更改密码对话框是编辑用户页面的一部分,我们可以使用它来更改bill的密码或删除密码。删除密码将使bill可以无密码登录。对话框提供了密码哈希选项的选择,并建议保持默认的MySQL 4.1+哈希。有关哈希的更多详细信息,请访问dev.mysql.com/doc/refman/5.1/en/password-hashing.html

更改登录信息或复制用户

此对话框可用于更改用户的登录信息,或将其登录信息复制到新用户。例如,假设 Bill 打电话告诉我们,他更喜欢登录名billy而不是bill。我们只需在用户名后添加一个y,然后选择从用户表中删除旧的单选按钮,如下截图所示:

更改登录信息或复制用户

点击Go, bill后,mysql数据库中将不再存在bill。此外,他的所有权限,包括对bill数据库的权限,都将被转移到新用户billy。但是,bill的用户定义仍将存在于内存中,因此仍然有效。如果我们选择了从用户表中删除旧用户并重新加载权限选项,bill的用户定义将立即失效。

或者,我们可以基于bill创建另一个用户,通过使用保留旧用户选项。我们可以通过选择不更改密码选项将密码转移到新用户,或者通过两次输入新密码来更改密码。撤销所有活动权限…选项立即终止了该用户的当前有效权限,即使他或她当前已登录。

删除用户

权限页面的用户概述部分删除用户。我们选择要删除的用户。然后(在删除选定的用户中)我们可以选择删除与要删除的用户同名的数据库选项,以删除以这些用户命名的任何数据库。点击Go有效地删除了选定的用户。

数据库信息

数据库页面旨在创建新数据库,并快速获取每个数据库的权限信息。还可以用来获取这些数据库的全局统计信息,而无需在导航面板中单击每个数据库。当我们进入数据库页面时,我们会看到现有数据库的列表:

数据库信息

我们还看到一个启用统计信息链接。默认情况下,统计信息是未启用的,因为计算所有数据库中所有表的数据和索引大小可能会消耗宝贵的 MySQL 服务器资源。

启用统计信息

如果我们点击启用统计信息链接,会出现一个修改后的页面。对于每个数据库,我们可以得到该数据库中表的默认排序规则,以及该数据库中表的数量和所有表的总行数。接下来是有关表数据部分使用的空间的信息,然后是所有索引占用的空间,以及所有表的总空间。接下来,在开销列标题下呈现了通过优化该数据库中的一些表可以回收的空间。最后,我们可以看到复制信息,然后是检查权限链接:

启用统计信息

排序统计信息

默认情况下,统计信息列表按数据库名称按升序排序。如果我们需要找到具有最多表的数据库或占用最多空间的数据库,只需简单点击总计列标题,列表将相应地排序。第二次点击将反转排序顺序。

检查数据库权限

点击检查权限图标或链接会显示特定数据库上的所有权限。用户的全局权限可能会显示在这里,因为它也允许他或她访问这个数据库。我们还可以看到特定于这个数据库的权限。编辑权限链接会带我们到另一个页面,用于编辑用户的权限。

检查数据库权限

我们注意到这个面板还包含添加新用户链接。点击这个链接是创建一个具有对我们当前正在检查的数据库的权限的用户的便捷方式。事实上,在从这个链接进入用户创建面板后,数据库创建或授予权限对话框中显示并默认选择了第四个选项,如下截图所示:

检查数据库权限

删除选定的数据库

要删除一个或多个数据库,我们转到服务器视图,单击数据库菜单选项;在要删除的数据库名称旁边打勾;然后单击所选项下的删除链接。然后我们会得到一个确认屏幕。两个数据库(mysql和虚拟的information_schema)不能被选择;第一个是为了避免犯大错并删除所有我们的账户,第二个不能被选择,因为这不是一个真正的数据库。

注意

这是一个不应轻率对待的操作,可能明智的是首先将整个数据库导出备份。

服务器信息

管理员和普通用户都可以从监控服务器并获取有关其一般配置和行为的信息中受益。状态,变量进程菜单选项可用于获取有关 MySQL 服务器的信息,或者对特定进程进行操作。

验证服务器状态

服务器状态统计反映了 MySQL 服务器的总活动,包括(但不限于)从 phpMyAdmin 发送的查询生成的活动。

单击状态菜单选项会生成有关服务器的运行时信息。页面有几个部分。首先,我们获取有关已运行时间和启动时间的信息。然后,我们获取流量和连接的总值和平均值(其中ø表示平均值),如下面的屏幕截图所示:

验证服务器状态

接下来,显示有关查询的统计信息(在屏幕截图中部分显示)。每小时、每分钟和每秒的平均查询次数很好地指示了服务器的负载。

查询统计后是有关执行的每个 MySQL 语句的统计信息,包括:

  • 每个语句执行的绝对次数

  • 执行的小时平均值

  • 与所有语句相比,该语句的执行百分比

演示顺序按利用率降序排列;在下面的屏幕截图中,我们看到set option语句是此服务器上最常接收的语句,占37.40%

验证服务器状态

查询统计之后,单击显示查询图表链接会生成一个显示此服务器上流行查询类型的图表,如下面的屏幕截图所示:

验证服务器状态

根据 MySQL 版本,还会显示许多其他包含服务器信息的部分。

服务器变量

变量页面显示了 MySQL 服务器的各种设置,这些设置可以在my.cnf MySQL 配置文件中定义。这些值无法在 phpMyAdmin 内更改。

服务器进程

进程页面可供超级用户和普通用户使用。普通用户只能看到属于他们自己的进程,而超级用户可以看到所有进程。

此页面列出了服务器上的所有活动进程。有一个终止链接,允许我们终止特定进程,如下面的屏幕截图所示:

服务器进程

此示例仅有两个正在运行的进程,包括由SHOW PROCESSLIST命令本身创建的进程。此进程无法终止,因为当我们看到页面时,它已经不再运行。在繁忙的服务器上,我们会看到更多正在运行的进程。

存储引擎

有关各种存储引擎的信息以两级格式提供。首先,引擎选项卡显示了当前 MySQL 版本的可能引擎的概述。在此服务器上启用的引擎的名称是可点击的。

存储引擎

其次,单击一个引擎名称会显示有关其设置的详细面板。将鼠标悬停在上标数字上会显示有关特定设置的更多信息。

可用字符集和校对规则

主页上的“字符集”菜单选项卡打开了“服务器”视图的“字符集”页面,其中列出了 MySQL 服务器支持的字符集和校对规则。每个字符集的默认校对规则显示为不同的背景颜色(使用在$cfg['BrowseMarkerColor']中定义的行标记颜色)。

检查二进制日志

如果我们的服务器上激活了 MySQL 的二进制日志记录,那么“服务器”视图中的菜单会发生变化,出现一个“二进制日志”选项卡。该选项卡通过SHOW BINLOG EVENTS命令提供了访问接口。该命令生成了更新了我们服务器上数据的 SQL 语句列表。这个列表可能非常庞大,目前 phpMyAdmin 没有使用分页技术限制其显示。因此,我们可能会达到浏览器的内存限制,这取决于我们使用的特定浏览器。

在下面的截图中,我们选择要检查的二进制日志(除非服务器只有一个二进制日志),然后显示语句:

检查二进制日志

总结

本章介绍了系统管理员可以使用的各种功能,如用户帐户管理、权限管理、数据库权限检查和服务器状态验证。适当的了解 MySQL 权限系统对于充分维护 MySQL 服务器至关重要,本章提出了围绕用户及其权限概念的练习。

附录,故障排除和支持,描述了在哪里获取支持以使 phpMyAdmin 高效运行。

附录 A. 故障排除和支持

这个附录 A 提出了解决一些常见问题的指南,并提供了如何避免这些问题的提示。它还解释了如何与开发团队互动以获取支持、错误报告和贡献。

故障排除

多年来,开发团队收到了许多支持请求,其中许多请求只需进行简单的验证就可以避免。

系统要求

Documentation.html文件的开头部分(包含在 phpMyAdmin 软件中)讨论了我们正在使用的特定 phpMyAdmin 版本的系统要求。这些要求必须得到满足,并且环境必须得到正确配置,以避免出现问题。

一些看起来像是 phpMyAdmin 错误的问题实际上是由服务器环境引起的。有时,Web 服务器没有正确配置来解释.php文件,或者 Web 服务器内部的 PHP 组件没有使用mysqlmysqli扩展运行。MySQL 帐户可能配置错误。这种情况可能发生在家庭服务器和托管服务器上。

当我们怀疑出现问题时,我们可以尝试一个简单的 PHP 脚本test.php,其中包含以下代码块,以检查 PHP 组件是否正确回答:

<?php
echo 'hello';
?>

我们应该看到hello消息。如果这个有效,我们可以尝试另一个脚本:

<?php
phpinfo();
?>

这个脚本显示了关于 PHP 组件的信息,包括可用的扩展。我们至少应该看到一个关于 MySQL 的部分(证明mysql扩展可用),其中提供了关于 MySQL客户端 API 版本的信息。

我们还可以尝试其他连接到 MySQL 的 PHP 脚本,以查看问题是否比 phpMyAdmin 不工作更普遍。一般来说,我们应该运行每个组件的最新稳定版本。

验证基本配置

我们应该始终仔细检查我们执行安装的方式,包括正确的权限和所有权。在修改config.inc.php时可能会出现拼写错误。

解决常见错误

为了帮助解决问题,我们应该首先确定错误消息的来源。以下是可能生成错误消息的各种组件:

  • MySQL 服务器:这些消息是由 phpMyAdmin 中继的,显示MySQL said后跟着消息

  • Web 服务器的 PHP 组件:例如,解析器错误

  • Web 服务器:错误可以从浏览器中看到,或者在 Web 服务器的日志文件中看到

  • Web 浏览器:例如,JavaScript 错误

寻求支持

支持的起点是 phpMyAdmin 官方网站phpmyadmin.net,其中有关于文档和支持的部分。在那里你会找到链接到讨论论坛和各种跟踪器的链接,比如:

  • 错误跟踪器

  • 功能请求跟踪器

  • 翻译跟踪器

  • 补丁跟踪器

  • 支持跟踪器

常见问题

产品的Documentation.html文件包含了一个详尽的常见问题解答部分,其中有编号的问题和答案。建议首先查阅这个常见问题解答部分以获取帮助。

帮助论坛

开发团队建议您使用产品的论坛搜索遇到的问题,然后在打开错误报告之前开始一个新的论坛讨论。

创建 SourceForge 帐户

强烈建议创建(免费)SourceForge 用户帐户并在论坛上使用它。这样可以更好地跟踪问题和答案。

选择主题标题

在开始新的论坛主题时,仔细选择摘要标题非常重要。像“帮帮我!”、“帮助新手!”、“问题”或“phpMyAdmin 错误!”这样的标题很难处理,因为答案都是针对这些标题的,进一步的参考变得困难。在帮助论坛中使用过的更好的标题包括:

  • “使用 UploadDir 导入”

  • “用户无法登录但 root 可以”

  • “我可以期望表有多大”

  • “持续登录提示”

  • “无法添加外键”

阅读答案

由于人们会阅读并几乎总是回答您的问题,因此在论坛中对答案进行反馈确实可以帮助回答问题的人,也可以帮助其他遇到相同问题的人。

使用支持跟踪器

支持跟踪器是另一个寻求支持的地方。此外,如果我们提交了一个实际上是支持请求的错误报告,该报告将被移动到支持跟踪器。如果您在您的个人资料中配置了电子邮件转发的 SourceForge 用户帐户,您将收到此跟踪器更改的通知。

使用错误跟踪器

在这个跟踪器中,我们看到尚未修复的错误,以及已经为下一个版本修复的错误。为下一个版本修复的错误保持“打开”状态,以避免重复的错误报告,但它们的优先级降低。

环境描述

由于开发人员将尝试重现提到的问题,因此描述您的环境有助于解决问题。这个描述可以很简短,但应包含以下内容:

  • phpMyAdmin 版本(团队,但是期望它是当前稳定版本)

  • Web 服务器名称和版本

  • PHP 版本

  • MySQL 版本

  • 浏览器名称和版本

通常情况下,除非我们注意到错误只涉及一个操作系统,否则不需要指定服务器或客户端正在运行的操作系统。例如,FAQ 5.1 描述了一个问题,用户无法创建超过十四个字段的表。这只发生在 Windows 98 下。

错误描述

我们应该准确描述发生了什么(包括任何错误消息、预期结果和实际结果)。如果报告只描述一个问题(除非问题明显相关),那么它们将更容易管理。

有时,附加一个简短的导出文件到错误报告可能有助于开发人员重现问题。欢迎截图。

项目的贡献

自 1998 年 phpMyAdmin 成立以来,数百人贡献了翻译、新功能的代码、建议和错误修复。

代码库

开发团队维护着一个不断发展的代码库,他们定期发布版本。在phpmyadmin.net上,“改进”页面解释了任何人如何贡献,并提供了关于项目的git源代码库的指针。如果贡献(翻译更新、补丁、新功能等)是针对最新的代码库而不是过时的 phpMyAdmin 版本,那么它将被视为更高优先级。另一个有关使用 Git 的有用指南页面位于wiki.phpmyadmin.net/pma/Git

翻译更新

查看项目当前的 65 种语言列表,您会注意到它们的维护程度并不相同。自从项目迁移到基于gettext的本地化系统以来,鼓励每个人贡献翻译。该项目正在使用一个配备Pootle软件的翻译服务器,位于l10n.cihar.com/projects/phpmyadmin。也可以使用该服务器来翻译 phpMyAdmin 的Documentation.html

补丁

如果以git format-patch的形式提交到当前代码库的补丁,并解释解决的问题或实现的新功能,开发团队可以更轻松地管理补丁。主要贡献者将在Documentation.html中得到官方认可。

posted @ 2024-05-21 12:36  绝不原创的飞龙  阅读(220)  评论(0)    收藏  举报