MySQL 快速指南



MySQL - 简介

什么是数据库?

数据库是一个独立的应用程序,用于存储数据的集合。每个数据库都拥有一个或多个用于创建、访问、管理、搜索和复制其所保存数据的 distinct API。

也可以使用其他类型的数据库,例如文件系统上的文件或内存中大型哈希表,但使用这些类型的系统进行数据获取和写入将不会那么快速和容易。

如今,我们使用关系数据库管理系统 (RDBMS) 来存储和管理海量数据。这被称为关系数据库,因为所有数据都存储在不同的表中,并且使用主键或其他称为外键的键来建立关系。

关系数据库管理系统 (RDBMS)是一种软件,它:

  • 使您能够实现具有表、列和索引的数据库。

  • 保证各个表行之间的参照完整性。

  • 自动更新索引。

  • 解释 SQL 查询并组合来自各个表的信息。

RDBMS 术语

在我们开始解释 MySQL 数据库系统之前,让我们回顾一些与数据库相关的定义。

  • 数据库 - 数据库是相关数据的表的集合。

  • - 表是一个包含数据的矩阵。数据库中的表看起来像一个简单的电子表格。

  • - 一列(数据元素)包含一种相同类型的数据,例如邮政编码列。

  • - 行(= 元组、条目或记录)是一组相关数据,例如一个订阅的数据。

  • 冗余 - 为了使系统更快,重复存储数据。

  • 主键 - 主键是唯一的。一个键值在一个表中不能出现两次。使用键,您只能找到一行。

  • 外键 - 外键是连接两个表的链接。

  • 复合键 - 复合键(组合键)是一个由多列组成的键,因为一列不足以唯一。

  • 索引 - 数据库中的索引类似于书后面的索引。

  • 参照完整性 - 参照完整性确保外键值始终指向现有行。

MySQL 数据库

MySQL 是一种快速、易于使用的 RDBMS,被许多大小企业使用。MySQL 由瑞典公司 MySQL AB 开发、销售和支持。MySQL 变得如此流行是有许多原因的:

  • MySQL 在开源许可下发布。因此,您无需付费即可使用它。

  • MySQL 本身就是一个非常强大的程序。它处理了最昂贵和最强大的数据库包的大部分功能。

  • MySQL 使用众所周知的标准 SQL 数据语言。

  • MySQL 可在许多操作系统和许多语言(包括 PHP、PERL、C、C++、JAVA 等)上运行。

  • MySQL 运行速度非常快,即使在大型数据集上也能很好地运行。

  • MySQL 对 PHP(最受推崇的 Web 开发语言)非常友好。

  • MySQL 支持大型数据库,一张表最多可容纳 5000 万行或更多。表的默认文件大小限制为 4GB,但您可以将其(如果您的操作系统可以处理)增加到理论上的 800 万 TB(TB)的限制。

  • MySQL 可定制。开源 GPL 许可证允许程序员修改 MySQL 软件以适应他们自己的特定环境。

开始之前

在开始本教程之前,您应该具备我们 PHP 和 HTML 教程中介绍的基本知识。

本教程主要关注在 PHP 环境中使用 MySQL。本教程中提供的许多示例对 PHP 程序员都非常有用。

我们建议您参考我们的PHP 教程

MySQL - 安装

所有 MySQL 下载文件都位于 MySQL 下载。选择您需要的MySQL Community Server 版本号以及您将运行它的平台。

在 Linux/UNIX 上安装 MySQL

在 Linux 系统上安装 MySQL 的推荐方法是通过 RPM。MySQL AB在其网站上提供以下 RPM 下载:

  • MySQL − MySQL 数据库服务器管理数据库和表,控制用户访问并处理 SQL 查询。

  • MySQL-client − MySQL 客户端程序,使连接到服务器并与服务器交互成为可能。

  • MySQL-devel − 在编译使用 MySQL 的其他程序时非常方便的库和头文件。

  • MySQL-shared − MySQL 客户端的共享库。

  • MySQL-bench − MySQL 数据库服务器的基准测试和性能测试工具。

此处列出的 MySQL RPM 都是在SuSE Linux 系统上构建的,但它们通常也可以在其他 Linux 版本上毫无困难地运行。

现在,您需要按照以下步骤进行安装:

  • 使用root用户登录系统。

  • 切换到包含 RPM 的目录。

  • 执行以下命令安装 MySQL 数据库服务器。记住用您的 RPM 文件名替换斜体中的文件名。

[root@host]# rpm -i MySQL-5.0.9-0.i386.rpm

上述命令负责安装 MySQL 服务器,创建 MySQL 用户,创建必要的配置并自动启动 MySQL 服务器。

您可以在 /usr/bin 和 /usr/sbin 中找到所有与 MySQL 相关的二进制文件。所有表和数据库都将创建在 /var/lib/mysql 目录中。

以下代码块包含一个可选但推荐的步骤,以相同方式安装其余的 RPM:

[root@host]# rpm -i MySQL-client-5.0.9-0.i386.rpm
[root@host]# rpm -i MySQL-devel-5.0.9-0.i386.rpm
[root@host]# rpm -i MySQL-shared-5.0.9-0.i386.rpm
[root@host]# rpm -i MySQL-bench-5.0.9-0.i386.rpm

在 Windows 上安装 MySQL

现在,任何 Windows 版本上的默认安装都比以前容易得多,因为 MySQL 现在带有简洁的安装程序包。只需下载安装程序包,将其解压缩到任何位置并运行 setup.exe 文件即可。

默认安装程序 setup.exe 将引导您完成简单的过程,并默认将所有内容安装在 C:\mysql 下。

第一次从命令提示符启动服务器以测试服务器。转到mysqld 服务器的位置(可能是 C:\mysql\bin),然后键入:

mysqld.exe --console

注意 − 如果您使用的是 NT,则必须使用 mysqld-nt.exe 而不是 mysqld.exe

如果一切顺利,您将看到一些关于启动和InnoDB的消息。如果没有,您可能存在权限问题。确保保存数据的目录可访问数据库进程运行的任何用户(可能是 MySQL)。

MySQL 不会将自身添加到开始菜单,也没有特别好的 GUI 方法来停止服务器。因此,如果您倾向于通过双击 mysqld 可执行文件来启动服务器,则应记住使用 mysqladmin、任务列表、任务管理器或其他特定于 Windows 的方法手动停止该进程。

验证 MySQL 安装

成功安装 MySQL 后,基本表已初始化,并且服务器已启动:您可以通过一些简单的测试来验证一切是否按预期运行。

使用 mysqladmin 实用程序获取服务器状态

使用mysqladmin二进制文件检查服务器版本。此二进制文件在 Linux 上位于 /usr/bin,在 Windows 上位于 C:\mysql\bin。

[root@host]# mysqladmin --version

它将在 Linux 上产生以下结果。它可能因您的安装而异:

mysqladmin  Ver 8.23 Distrib 5.0.9-0, for redhat-linux-gnu on i386

如果您没有收到这样的消息,则您的安装可能存在一些问题,您需要一些帮助才能解决它。

使用 MySQL 客户端执行简单的 SQL 命令

您可以通过 MySQL 客户端并使用mysql命令连接到您的 MySQL 服务器。目前,您不需要提供任何密码,因为默认情况下它将设置为空白。

您可以只使用以下命令:

[root@host]# mysql

它应该会返回 mysql> 提示符。现在,您已连接到 MySQL 服务器,您可以在 mysql> 提示符下执行所有 SQL 命令,如下所示:

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
|   mysql  | 
|   test   |  
+----------+
2 rows in set (0.13 sec)

安装后步骤

MySQL 为 root MySQL 用户提供了一个空密码。成功安装数据库和客户端后,您需要设置一个 root 密码,如下面的代码块所示:

[root@host]# mysqladmin -u root password "new_password";

现在要连接到您的 MySQL 服务器,您需要使用以下命令:

[root@host]# mysql -u root -p
Enter password:*******

UNIX 用户还希望将 MySQL 目录放入 PATH 中,这样您就不必每次想要使用命令行客户端时都输入完整路径。

对于 bash,它将类似于:

export PATH = $PATH:/usr/bin:/usr/sbin

在启动时运行 MySQL

如果您想在启动时运行 MySQL 服务器,请确保在 /etc/rc.local 文件中包含以下条目。

/etc/init.d/mysqld start

此外,您应该在 /etc/init.d/ 目录中拥有 mysqld 二进制文件。

MySQL - 管理

运行和关闭 MySQL 服务器

首先检查您的 MySQL 服务器是否正在运行。您可以使用以下命令进行检查:

ps -ef | grep mysqld

如果您的 MySql 正在运行,则您将在结果中看到mysqld进程。如果服务器未运行,则可以使用以下命令启动它:

root@host# cd /usr/bin
./safe_mysqld &

现在,如果您想关闭正在运行的 MySQL 服务器,则可以使用以下命令:

root@host# cd /usr/bin
./mysqladmin -u root -p shutdown
Enter password: ******

设置 MySQL 用户帐户

要向 MySQL 添加新用户,您只需向数据库mysql中的user表添加新条目。

以下程序是一个添加新用户guest的示例,该用户具有 SELECT、INSERT 和 UPDATE 权限,密码为guest123;SQL 查询为:

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

mysql> INSERT INTO user 
   (host, user, password, 
   select_priv, insert_priv, update_priv) 
   VALUES ('localhost', 'guest', 
   PASSWORD('guest123'), 'Y', 'Y', 'Y');
Query OK, 1 row affected (0.20 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 1 row affected (0.01 sec)

mysql> SELECT host, user, password FROM user WHERE user = 'guest';
+-----------+---------+------------------+
|    host   |   user  |     password     |    
+-----------+---------+------------------+
| localhost |  guest  | 6f8c114b58f2ce9e |
+-----------+---------+------------------+
1 row in set (0.00 sec)

添加新用户时,请记住使用 MySQL 提供的 PASSWORD() 函数加密新密码。如上例所示,密码 mypass 加密为 6f8c114b58f2ce9e。

请注意 FLUSH PRIVILEGES 语句。这告诉服务器重新加载授权表。如果您不使用它,则至少在服务器重新启动之前,您将无法使用新用户帐户连接到 MySQL。

您还可以通过在执行 INSERT 查询时将以下列的值设置为“Y”来为新用户指定其他权限,或者您可以稍后使用 UPDATE 查询更新它们。

  • Select_priv
  • Insert_priv
  • Update_priv
  • Delete_priv
  • Create_priv
  • Drop_priv
  • Reload_priv
  • Shutdown_priv
  • Process_priv
  • File_priv
  • Grant_priv
  • References_priv
  • Index_priv
  • Alter_priv

另一种添加用户帐户的方法是使用 GRANT SQL 命令。以下示例将为名为TUTORIALS的特定数据库添加用户zara,密码为zara123

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

mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
   -> ON TUTORIALS.*
   -> TO 'zara'@'localhost'
   -> IDENTIFIED BY 'zara123';

这还将在名为user的 MySQL 数据库表中创建一个条目。

注意 − 在您在 SQL 命令末尾给出分号 (;) 之前,MySQL 不会终止命令。

/etc/my.cnf 文件配置

在大多数情况下,您不应该触摸此文件。默认情况下,它将包含以下条目:

[mysqld]
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock

[mysql.server]
user = mysql
basedir = /var/lib

[safe_mysqld]
err-log = /var/log/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid

在这里,您可以为错误日志指定不同的目录,否则您不应更改此表中的任何条目。

MySQL 管理命令

以下是您将不时使用来处理 MySQL 数据库的重要 MySQL 命令列表:

  • USE 数据库名 − 这将用于在 MySQL 工作区中选择数据库。

  • SHOW DATABASES − 列出 MySQL DBMS 可访问的数据库。

  • SHOW TABLES − 选择数据库后(使用 use 命令),显示数据库中的表。

  • SHOW COLUMNS FROM 表名: 显示表的属性、属性类型、键信息、是否允许 NULL、默认值以及表的其他信息。

  • SHOW INDEX FROM 表名 − 显示表上所有索引的详细信息,包括 PRIMARY KEY。

  • SHOW TABLE STATUS LIKE 表名\G − 报告 MySQL DBMS 性能和统计详细信息。

在下一章中,我们将讨论如何在 MySQL 中使用 PHP 语法。

MySQL - PHP 语法

MySQL 与各种编程语言(如 PERL、C、C++、JAVA 和 PHP)结合使用效果非常好。在这些语言中,PHP 由于其 Web 应用程序开发能力而成为最流行的一种。

本教程重点介绍在 PHP 环境中使用 MySQL。如果您对使用 PERL 的 MySQL 感兴趣,则可以考虑阅读PERL教程。

PHP 提供各种函数来访问 MySQL 数据库和操作 MySQL 数据库中的数据记录。您需要像调用任何其他 PHP 函数一样调用 PHP 函数。

与 MySQL 一起使用的 PHP 函数具有以下通用格式:

mysql_function(value,value,...);

函数名称的第二部分特定于该函数,通常是一个描述函数功能的词。以下是我们将在教程中使用的两个函数:

mysqli_connect($connect);
mysqli_query($connect,"SQL statement");

以下示例显示了调用任何 MySQL 函数的 PHP 通用语法。

<html>
   <head>
      <title>PHP with MySQL</title>
   </head>
   
   <body>
      <?php
         $retval = mysql_function(value, [value,...]);
         if( !$retval ) {
            die ( "Error: a related error message" );
         }
         // Otherwise MySQL  or PHP Statements
      ?>
   </body>
</html>

从下一章开始,我们将看到所有重要的 MySQL 功能以及 PHP。

MySQL - 连接

使用 MySQL 二进制文件连接 MySQL

您可以在命令提示符下使用mysql二进制文件建立 MySQL 数据库。

示例

这是一个从命令提示符连接到 MySQL 服务器的简单示例:

[root@host]# mysql -u root -p
Enter password:******

这将为您提供 mysql> 命令提示符,您可以在其中执行任何 SQL 命令。以下是上述命令的结果:

以下代码块显示了上述代码的结果:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2854760 to server version: 5.0.9

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

在上例中,我们使用了root作为用户,但您也可以使用任何其他用户。任何用户都可以执行允许该用户执行的所有 SQL 操作。

您可以随时使用 mysql> 提示符下的exit命令断开与 MySQL 数据库的连接。

mysql> exit
Bye

使用 PHP 脚本连接 MySQL

PHP 提供mysql_connect()函数来打开数据库连接。此函数接受五个参数,并在成功时返回 MySQL 链接标识符,在失败时返回 FALSE。

语法

connection mysql_connect(server,user,passwd,new_link,client_flag);

序号 参数和说明
1

服务器

可选 − 运行数据库服务器的主机名。如果未指定,则默认值为localhost:3306

2

用户

可选 − 访问数据库的用户名。如果未指定,则默认为拥有服务器进程的用户名称。

3

密码

可选 − 访问数据库的用户的密码。如果未指定,则默认为空密码。

4

new_link

可选 − 如果使用相同的参数对 mysql_connect() 进行第二次调用,则不会建立新的连接;相反,将返回已打开连接的标识符。

5

client_flags

可选 − 以下常量的组合:

  • MYSQL_CLIENT_SSL − 使用 SSL 加密。

  • MYSQL_CLIENT_COMPRESS − 使用压缩协议。

  • MYSQL_CLIENT_IGNORE_SPACE − 允许函数名后有空格。

  • MYSQL_CLIENT_INTERACTIVE − 允许交互式超时,在关闭连接之前等待几秒钟的空闲时间。

您可以随时使用另一个 PHP 函数mysql_close()断开与 MySQL 数据库的连接。此函数接受一个参数,该参数是mysql_connect()函数返回的连接。

语法

bool mysql_close ( resource $link_identifier );

如果未指定资源,则关闭上次打开的数据库。如果成功关闭连接,则此函数返回 true,否则返回 false。

示例

尝试以下示例以连接到 MySQL 服务器:

<html>
   <head>
      <title>Connecting MySQL Server</title>
   </head>
   <body>
      <?php
         $dbhost = 'localhost:3306';
         $dbuser = 'guest';
         $dbpass = 'guest123';
         $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
         if(! $conn ) {
            die('Could not connect: ' . mysql_error());
         }
         echo 'Connected successfully';
         mysql_close($conn);
      ?>
   </body>
</html>

MySQL - 创建数据库

使用 mysqladmin 创建数据库

创建或删除 MySQL 数据库需要特殊的权限。因此,假设您拥有 root 用户的访问权限,您可以使用 mysql **mysqladmin** 二进制文件创建任何数据库。

示例

以下是一个创建名为 **TUTORIALS** 数据库的简单示例:

[root@host]# mysqladmin -u root -p create TUTORIALS
Enter password:******

这将创建一个名为 TUTORIALS 的 MySQL 数据库。

使用 PHP 脚本创建数据库

PHP 使用 **mysql_query** 函数来创建或删除 MySQL 数据库。此函数接受两个参数,成功时返回 TRUE,失败时返回 FALSE。

语法

bool mysql_query( sql, connection );

序号 参数和说明
1

sql

必需 - 创建或删除 MySQL 数据库的 SQL 查询

2

连接

可选 - 如果未指定,则使用 mysql_connect 最后打开的连接。

示例

以下是如何创建数据库的示例:

<html>
   <head>
      <title>Creating MySQL Database</title>
   </head>
   
   <body>
      <?php
         $dbhost = 'localhost:3036';
         $dbuser = 'root';
         $dbpass = 'rootpassword';
         $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
         if(! $conn ) {
            die('Could not connect: ' . mysql_error());
         }
         echo 'Connected successfully<br />';
         $sql = 'CREATE DATABASE TUTORIALS';
         $retval = mysql_query( $sql, $conn );
         
         if(! $retval ) {
            die('Could not create database: ' . mysql_error());
         }
         echo "Database TUTORIALS created successfully\n";
         mysql_close($conn);
      ?>
   </body>
</html>

删除 MySQL 数据库

使用 mysqladmin 删除数据库

创建或删除 MySQL 数据库需要特殊的权限。因此,假设您拥有 root 用户的访问权限,您可以使用 mysql **mysqladmin** 二进制文件创建任何数据库。

删除任何数据库时要小心,因为您将丢失数据库中所有可用数据。

以下是如何删除上一章中创建的数据库 (TUTORIALS) 的示例:

[root@host]# mysqladmin -u root -p drop TUTORIALS
Enter password:******

这将给您一个警告,并确认您是否真的要删除此数据库。

Dropping the database is potentially a very bad thing to do.
Any data stored in the database will be destroyed.

Do you really want to drop the 'TUTORIALS' database [y/N] y
Database "TUTORIALS" dropped

使用 PHP 脚本删除数据库

PHP 使用 **mysql_query** 函数来创建或删除 MySQL 数据库。此函数接受两个参数,成功时返回 TRUE,失败时返回 FALSE。

语法

bool mysql_query( sql, connection );

序号 参数和说明
1

sql

必需 - 创建或删除 MySQL 数据库的 SQL 查询

2

连接

可选 - 如果未指定,则使用 mysql_connect 最后打开的连接。

示例

尝试以下示例来删除数据库:

<html>
   <head>
      <title>Deleting MySQL Database</title>
   </head>
   
   <body>
      <?php
         $dbhost = 'localhost:3036';
         $dbuser = 'root';
         $dbpass = 'rootpassword';
         $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
         if(! $conn ) {
            die('Could not connect: ' . mysql_error());
         }
         echo 'Connected successfully<br />';
         $sql = 'DROP DATABASE TUTORIALS';
         $retval = mysql_query( $sql, $conn );
         
         if(! $retval ) {
            die('Could not delete database: ' . mysql_error());
         }
         echo "Database TUTORIALS deleted successfully\n";
         mysql_close($conn);
      ?>
   </body>
</html>

**警告** - 使用 PHP 脚本删除数据库时,不会提示您进行任何确认。因此,删除 MySQL 数据库时要小心。

选择 MySQL 数据库

连接到 MySQL 服务器后,需要选择一个数据库来进行操作。这是因为 MySQL 服务器上可能存在多个数据库。

从命令提示符选择 MySQL 数据库

从 mysql> 提示符选择数据库非常简单。您可以使用 SQL 命令 **use** 来选择数据库。

示例

以下是如何选择名为 **TUTORIALS** 数据库的示例:

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

现在,您已选择 TUTORIALS 数据库,所有后续操作都将在 TUTORIALS 数据库上执行。

**注意** - 所有数据库名称、表名称和表字段名称都区分大小写。因此,在执行任何 SQL 命令时,必须使用正确的名称。

使用 PHP 脚本选择 MySQL 数据库

PHP 提供函数 **mysql_select_db** 来选择数据库。成功时返回 TRUE,失败时返回 FALSE。

语法

bool mysql_select_db( db_name, connection );

序号 参数和说明
1

db_name

必需 - 要选择的 MySQL 数据库名称

2

连接

可选 - 如果未指定,则使用 mysql_connect 最后打开的连接。

示例

以下是一个显示如何选择数据库的示例。

<html>
   <head>
      <title>Selecting MySQL Database</title>
   </head>
   
   <body>
      <?php
         $dbhost = 'localhost:3036';
         $dbuser = 'guest';
         $dbpass = 'guest123';
         $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
         if(! $conn ) {
            die('Could not connect: ' . mysql_error());
         }
         echo 'Connected successfully';
         mysql_select_db( 'TUTORIALS' );
         
         mysql_close($conn);
      ?>
   </body>
</html>

MySQL - 数据类型

正确定义表中的字段对于数据库的整体优化非常重要。您应该只使用真正需要的字段类型和大小。例如,如果您知道只需要使用 2 个字符,则不要定义一个 10 个字符宽的字段。这些类型的字段(或列)也称为数据类型,根据您将存储在这些字段中的**数据类型**命名。

MySQL 使用许多不同的数据类型,分为三类:

  • 数值型
  • 日期和时间
  • 字符串类型。

现在让我们详细讨论它们。

数值数据类型

MySQL 使用所有标准 ANSI SQL 数值数据类型,因此如果您是从其他数据库系统迁移到 MySQL,这些定义会让您感觉熟悉。

以下列表显示了常见的数值数据类型及其描述:

  • **INT** - 一个普通大小的整数,可以是有符号的或无符号的。如果是带符号的,允许的范围是从 -2147483648 到 2147483647。如果是无符号的,允许的范围是从 0 到 4294967295。您可以指定最多 11 位的宽度。

  • **TINYINT** - 一个非常小的整数,可以是有符号的或无符号的。如果是带符号的,允许的范围是从 -128 到 127。如果是无符号的,允许的范围是从 0 到 255。您可以指定最多 4 位的宽度。

  • **SMALLINT** - 一个小的整数,可以是有符号的或无符号的。如果是带符号的,允许的范围是从 -32768 到 32767。如果是无符号的,允许的范围是从 0 到 65535。您可以指定最多 5 位的宽度。

  • **MEDIUMINT** - 一个中等大小的整数,可以是有符号的或无符号的。如果是带符号的,允许的范围是从 -8388608 到 8388607。如果是无符号的,允许的范围是从 0 到 16777215。您可以指定最多 9 位的宽度。

  • **BIGINT** - 一个大的整数,可以是有符号的或无符号的。如果是带符号的,允许的范围是从 -9223372036854775808 到 9223372036854775807。如果是无符号的,允许的范围是从 0 到 18446744073709551615。您可以指定最多 20 位的宽度。

  • **FLOAT(M,D)** - 一个浮点数,不能是无符号的。您可以定义显示长度 (M) 和小数位数 (D)。这不是必需的,默认为 10,2,其中 2 是小数位数,10 是总位数(包括小数位)。FLOAT 的小数精度可以达到 24 位。

  • **DOUBLE(M,D)** - 一个双精度浮点数,不能是无符号的。您可以定义显示长度 (M) 和小数位数 (D)。这不是必需的,默认为 16,4,其中 4 是小数位数。DOUBLE 的小数精度可以达到 53 位。REAL 是 DOUBLE 的同义词。

  • **DECIMAL(M,D)** - 一个未打包的浮点数,不能是无符号的。在未打包的小数中,每个小数对应一个字节。需要定义显示长度 (M) 和小数位数 (D)。NUMERIC 是 DECIMAL 的同义词。

日期和时间类型

MySQL 日期和时间数据类型如下:

  • **DATE** - YYYY-MM-DD 格式的日期,介于 1000-01-01 和 9999-12-31 之间。例如,1973 年 12 月 30 日将存储为 1973-12-30。

  • **DATETIME** - YYYY-MM-DD HH:MM:SS 格式的日期和时间组合,介于 1000-01-01 00:00:00 和 9999-12-31 23:59:59 之间。例如,1973 年 12 月 30 日下午 3:30 将存储为 1973-12-30 15:30:00。

  • **TIMESTAMP** - 1970 年 1 月 1 日午夜到 2037 年某个时间之间的timestamp。这看起来像之前的 DATETIME 格式,只是数字之间没有连字符;1973 年 12 月 30 日下午 3:30 将存储为 19731230153000 (YYYYMMDDHHMMSS)。

  • **TIME** - 以 HH:MM:SS 格式存储时间。

  • **YEAR(M)** - 以 2 位或 4 位格式存储年份。如果长度指定为 2(例如 YEAR(2)),YEAR 可以介于 1970 年到 2069 年(70 到 69)之间。如果长度指定为 4,则 YEAR 可以是 1901 年到 2155 年。默认长度为 4。

字符串类型

尽管数值和日期类型很有趣,但您存储的大多数数据都将采用字符串格式。此列表描述了 MySQL 中常见的字符串数据类型。

  • **CHAR(M)** - 长度在 1 到 255 个字符之间的固定长度字符串(例如 CHAR(5)),存储时在右侧用空格填充到指定的长度。不需要定义长度,但默认值为 1。

  • **VARCHAR(M)** - 长度在 1 到 255 个字符之间的可变长度字符串。例如,VARCHAR(25)。创建 VARCHAR 字段时必须定义长度。

  • **BLOB 或 TEXT** - 最大长度为 65535 个字符的字段。BLOB 是“二进制大型对象”,用于存储大量二进制数据,例如图像或其他类型的文件。定义为 TEXT 的字段也保存大量数据。两者之间的区别在于,存储数据的排序和比较在 BLOB 中**区分大小写**,而在 TEXT 字段中**不区分大小写**。您不必为 BLOB 或 TEXT 指定长度。

  • **TINYBLOB 或 TINYTEXT** - 最大长度为 255 个字符的 BLOB 或 TEXT 列。您不必为 TINYBLOB 或 TINYTEXT 指定长度。

  • **MEDIUMBLOB 或 MEDIUMTEXT** - 最大长度为 16777215 个字符的 BLOB 或 TEXT 列。您不必为 MEDIUMBLOB 或 MEDIUMTEXT 指定长度。

  • **LONGBLOB 或 LONGTEXT** - 最大长度为 4294967295 个字符的 BLOB 或 TEXT 列。您不必为 LONGBLOB 或 LONGTEXT 指定长度。

  • **ENUM** - 枚举,这是一个用于列表的专业术语。定义 ENUM 时,您正在创建一个必须从中选择值的项目列表(或者可以为 NULL)。例如,如果您希望字段包含“A”或“B”或“C”,则应将 ENUM 定义为 ENUM ('A', 'B', 'C'),只有这些值(或 NULL)才能填充该字段。

在下一章中,我们将讨论如何在 MySQL 中创建表。

创建 MySQL 表

首先,表创建命令需要以下详细信息:

  • 表名
  • 字段名
  • 每个字段的定义

语法

以下是如何创建 MySQL 表的通用 SQL 语法:

CREATE TABLE table_name (column_name column_type);

现在,我们将在 **TUTORIALS** 数据库中创建以下表。

create table tutorials_tbl(
   tutorial_id INT NOT NULL AUTO_INCREMENT,
   tutorial_title VARCHAR(100) NOT NULL,
   tutorial_author VARCHAR(40) NOT NULL,
   submission_date DATE,
   PRIMARY KEY ( tutorial_id )
);

这里,一些项目需要解释:

  • 字段属性 **NOT NULL** 用于表示我们不希望此字段为 NULL。因此,如果用户尝试创建具有 NULL 值的记录,则 MySQL 将引发错误。

  • 字段属性 **AUTO_INCREMENT** 告诉 MySQL继续为 id 字段添加下一个可用数字。

  • 关键字 **PRIMARY KEY** 用于将列定义为主键。您可以使用逗号分隔的多个列来定义主键。

从命令提示符创建表

从 mysql> 提示符创建 MySQL 表很容易。您将使用 SQL 命令 **CREATE TABLE** 来创建表。

示例

以下是一个示例,它将创建 **tutorials_tbl**:

root@host# mysql -u root -p
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> CREATE TABLE tutorials_tbl(
   -> tutorial_id INT NOT NULL AUTO_INCREMENT,
   -> tutorial_title VARCHAR(100) NOT NULL,
   -> tutorial_author VARCHAR(40) NOT NULL,
   -> submission_date DATE,
   -> PRIMARY KEY ( tutorial_id )
   -> );
Query OK, 0 rows affected (0.16 sec)
mysql>

**注意** - 在 SQL 命令末尾添加分号 (;) 之前,MySQL 不会终止命令。

使用 PHP 脚本创建表

要在任何现有数据库中创建新表,您需要使用 PHP 函数 **mysql_query()**。您将使用正确的 SQL 命令将其作为第二个参数传递以创建表。

示例

以下程序是使用 PHP 脚本创建表的示例:

<html>
   <head>
      <title>Creating MySQL Tables</title>
   </head>
   
   <body>
      <?php
         $dbhost = 'localhost:3036';
         $dbuser = 'root';
         $dbpass = 'rootpassword';
         $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
         if(! $conn ) {
            die('Could not connect: ' . mysql_error());
         }
         echo 'Connected successfully<br />';
         $sql = "CREATE TABLE tutorials_tbl( ".
            "tutorial_id INT NOT NULL AUTO_INCREMENT, ".
            "tutorial_title VARCHAR(100) NOT NULL, ".
            "tutorial_author VARCHAR(40) NOT NULL, ".
            "submission_date DATE, ".
            "PRIMARY KEY ( tutorial_id )); ";
         mysql_select_db( 'TUTORIALS' );
         $retval = mysql_query( $sql, $conn );
         
         if(! $retval ) {
            die('Could not create table: ' . mysql_error());
         }
         echo "Table created successfully\n";
         mysql_close($conn);
      ?>
   </body>
</html>

删除 MySQL 表

删除现有的 MySQL 表很容易,但在删除任何现有表时需要非常小心,因为删除表后将无法恢复丢失的数据。

语法

以下是如何删除 MySQL 表的通用 SQL 语法:

DROP TABLE table_name ;

从命令提示符删除表

要从命令提示符删除表,我们需要在 mysql> 提示符下执行 DROP TABLE SQL 命令。

示例

以下程序是一个删除 **tutorials_tbl** 的示例:

root@host# mysql -u root -p
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> DROP TABLE tutorials_tbl
Query OK, 0 rows affected (0.8 sec)
mysql>

使用 PHP 脚本删除表

要删除任何数据库中已存在的表,需要使用PHP函数mysql_query()。你需要将正确的SQL命令作为其第二个参数传入,以删除表。

示例

<html>
   <head>
      <title>Creating MySQL Tables</title>
   </head>
   
   <body>
      <?php
         $dbhost = 'localhost:3036';
         $dbuser = 'root';
         $dbpass = 'rootpassword';
         $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
         if(! $conn ) {
            die('Could not connect: ' . mysql_error());
         }
         echo 'Connected successfully<br />';
         $sql = "DROP TABLE tutorials_tbl";
         mysql_select_db( 'TUTORIALS' );
         $retval = mysql_query( $sql, $conn );
         
         if(! $retval ) {
            die('Could not delete table: ' . mysql_error());
         }
         echo "Table deleted successfully\n";
         mysql_close($conn);
      ?>
   </body>
</html>

MySQL - INSERT 查询

要将数据插入MySQL表,需要使用SQLINSERT INTO命令。你可以使用mysql>提示符或使用PHP之类的脚本将数据插入MySQL表。

语法

以下是将数据插入MySQL表的INSERT INTO命令的通用SQL语法:

INSERT INTO table_name ( field1, field2,...fieldN )
   VALUES
   ( value1, value2,...valueN );

要插入字符串数据类型,需要将所有值放在双引号或单引号中。例如"value"

从命令提示符插入数据

要从命令提示符插入数据,我们将使用SQL INSERT INTO命令将数据插入MySQL表tutorials_tbl。

示例

以下示例将在tutorials_tbl表中创建3条记录:

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

mysql> INSERT INTO tutorials_tbl 
   ->(tutorial_title, tutorial_author, submission_date)
   ->VALUES
   ->("Learn PHP", "John Poul", NOW());
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tutorials_tbl
   ->(tutorial_title, tutorial_author, submission_date)
   ->VALUES
   ->("Learn MySQL", "Abdul S", NOW());
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO tutorials_tbl
   ->(tutorial_title, tutorial_author, submission_date)
   ->VALUES
   ->("JAVA Tutorial", "Sanjay", '2007-05-06');
Query OK, 1 row affected (0.01 sec)
mysql>

注意 - 请注意,所有箭头符号(->)都不是SQL命令的一部分。它们指示新行,并且在按下回车键时,如果没有在命令的每一行末尾给出分号,MySQL提示符会自动创建它们。

在上面的示例中,我们没有提供tutorial_id,因为在表创建时,我们为此字段提供了AUTO_INCREMENT选项。因此,MySQL会自动处理这些ID的插入。这里,NOW()是MySQL函数,它返回当前日期和时间。

使用PHP脚本插入数据

你可以将相同的SQL INSERT INTO命令放入PHP函数mysql_query()中,以将数据插入MySQL表。

示例

此示例将从用户处获取三个参数,并将它们插入到MySQL表中:

<html>

   <head>
      <title>Add New Record in MySQL Database</title>
   </head>

   <body>
      <?php
         if(isset($_POST['add'])) {
            $dbhost = 'localhost:3036';
            $dbuser = 'root';
            $dbpass = 'rootpassword';
            $conn = mysql_connect($dbhost, $dbuser, $dbpass);
         
            if(! $conn ) {
               die('Could not connect: ' . mysql_error());
            }

            if(! get_magic_quotes_gpc() ) {
               $tutorial_title = addslashes ($_POST['tutorial_title']);
               $tutorial_author = addslashes ($_POST['tutorial_author']);
            } else {
               $tutorial_title = $_POST['tutorial_title'];
               $tutorial_author = $_POST['tutorial_author'];
            }

            $submission_date = $_POST['submission_date'];
   
            $sql = "INSERT INTO tutorials_tbl ".
               "(tutorial_title,tutorial_author, submission_date) "."VALUES ".
               "('$tutorial_title','$tutorial_author','$submission_date')";
               mysql_select_db('TUTORIALS');
            $retval = mysql_query( $sql, $conn );
         
            if(! $retval ) {
               die('Could not enter data: ' . mysql_error());
            }
         
            echo "Entered data successfully\n";
            mysql_close($conn);
         } else {
      ?>
   
      <form method = "post" action = "<?php $_PHP_SELF ?>">
         <table width = "600" border = "0" cellspacing = "1" cellpadding = "2">
            <tr>
               <td width = "250">Tutorial Title</td>
               <td>
                  <input name = "tutorial_title" type = "text" id = "tutorial_title">
               </td>
            </tr>
         
            <tr>
               <td width = "250">Tutorial Author</td>
               <td>
                  <input name = "tutorial_author" type = "text" id = "tutorial_author">
               </td>
            </tr>
         
            <tr>
               <td width = "250">Submission Date [   yyyy-mm-dd ]</td>
               <td>
                  <input name = "submission_date" type = "text" id = "submission_date">
               </td>
            </tr>
      
            <tr>
               <td width = "250"> </td>
               <td> </td>
            </tr>
         
            <tr>
               <td width = "250"> </td>
               <td>
                  <input name = "add" type = "submit" id = "add"  value = "Add Tutorial">
               </td>
            </tr>
         </table>
      </form>
   <?php
      }
   ?>
   </body>
</html>

在进行数据插入时,最好使用函数get_magic_quotes_gpc()来检查是否设置了magic_quote的当前配置。如果此函数返回false,则使用函数addslashes()在引号前添加反斜杠。

你可以进行许多验证来检查输入的数据是否正确,并采取相应的措施。

MySQL - SELECT 查询

SQLSELECT命令用于从MySQL数据库中提取数据。你可以在mysql>提示符以及PHP之类的脚本中使用此命令。

语法

以下是从MySQL表中提取数据的SELECT命令的通用SQL语法:

SELECT field1, field2,...fieldN 
FROM table_name1, table_name2...
[WHERE Clause]
[OFFSET M ][LIMIT N]
  • 你可以使用逗号分隔一个或多个表,以使用WHERE子句包含各种条件,但WHERE子句是SELECT命令的可选部分。

  • 你可以在单个SELECT命令中提取一个或多个字段。

  • 你可以用星号(*)代替字段。在这种情况下,SELECT将返回所有字段。

  • 你可以使用WHERE子句指定任何条件。

  • 你可以使用OFFSET指定SELECT从何处开始返回记录。默认情况下,偏移量从零开始。

  • 你可以使用LIMIT属性限制返回的数量。

从命令提示符提取数据

这将使用SQL SELECT命令从MySQL表tutorials_tbl中提取数据。

示例

以下示例将返回tutorials_tbl表中的所有记录:

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT * from tutorials_tbl 
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|           1 | Learn PHP      | John Poul       | 2007-05-21      |
|           2 | Learn MySQL    | Abdul S         | 2007-05-21      |
|           3 | JAVA Tutorial  | Sanjay          | 2007-05-21      |
+-------------+----------------+-----------------+-----------------+
3 rows in set (0.01 sec)

mysql>

使用PHP脚本提取数据

你可以将相同的SQL SELECT命令放入PHP函数mysql_query()中。此函数用于执行SQL命令,然后另一个PHP函数mysql_fetch_array()可以用来提取所有选定的数据。此函数将行作为关联数组、数字数组或两者都返回。如果没有更多行,则此函数返回FALSE。

以下程序是一个简单的示例,它将演示如何从tutorials_tbl表中提取/显示记录。

示例

以下代码块将显示tutorials_tbl表中的所有记录。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   
   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }
   $sql = 'SELECT tutorial_id, tutorial_title, tutorial_author, submission_date FROM tutorials_tbl';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }
   
   while($row = mysql_fetch_array($retval, MYSQL_ASSOC)) {
      echo "Tutorial ID :{$row['tutorial_id']}  <br> ".
         "Title: {$row['tutorial_title']} <br> ".
         "Author: {$row['tutorial_author']} <br> ".
         "Submission Date : {$row['submission_date']} <br> ".
         "--------------------------------<br>";
   } 
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

行的内容被赋值给变量$row,然后打印该行中的值。

注意 - 记住,当你想要直接将数组值插入字符串时,一定要使用花括号。

在上面的示例中,常量MYSQL_ASSOC用作PHP函数mysql_fetch_array()的第二个参数,以便它将行作为关联数组返回。使用关联数组,你可以通过使用字段名称而不是索引来访问字段。

PHP提供了另一个名为mysql_fetch_assoc()的函数,它也返回行作为关联数组。

示例

以下示例使用mysql_fetch_assoc()函数显示tutorial_tbl表中的所有记录。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   
   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }
   
   $sql = 'SELECT tutorial_id, tutorial_title, tutorial_author, submission_date
      FROM tutorials_tbl';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }
   
   while($row = mysql_fetch_assoc($retval)) {
      echo "Tutorial ID :{$row['tutorial_id']}  <br> ".
         "Title: {$row['tutorial_title']} <br> ".
         "Author: {$row['tutorial_author']} <br> ".
         "Submission Date : {$row['submission_date']} <br> ".
         "--------------------------------<br>";
   } 
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

你也可以使用常量MYSQL_NUM作为PHP函数mysql_fetch_array()的第二个参数。这将导致函数返回一个带有数字索引的数组。

示例

尝试以下示例,使用MYSQL_NUM参数显示tutorials_tbl表中的所有记录。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);

   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }
   
   $sql = 'SELECT tutorial_id, tutorial_title, tutorial_author, submission_date
      FROM tutorials_tbl';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }
   
   while($row = mysql_fetch_array($retval, MYSQL_NUM)) {
      echo "Tutorial ID :{$row[0]}  <br> ".
         "Title: {$row[1]} <br> ".
         "Author: {$row[2]} <br> ".
         "Submission Date : {$row[3]} <br> ".
         "--------------------------------<br>";
   }
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

以上三个示例将产生相同的结果。

释放内存

最好在每个SELECT语句结束时释放游标内存。这可以通过使用PHP函数mysql_free_result()来完成。以下程序是演示如何使用它的示例。

示例

尝试以下示例:

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);

   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }
   
   $sql = 'SELECT tutorial_id, tutorial_title, tutorial_author, submission_date
      FROM tutorials_tbl';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }
   
   while($row = mysql_fetch_array($retval, MYSQL_NUM)) {
      echo "Tutorial ID :{$row[0]}  <br> ".
         "Title: {$row[1]} <br> ".
         "Author: {$row[2]} <br> ".
         "Submission Date : {$row[3]} <br> ".
         "--------------------------------<br>";
   }
   mysql_free_result($retval);
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

在提取数据时,你可以编写任意复杂的代码,但过程将与上述相同。

MySQL - WHERE子句

我们已经看到了SQLSELECT命令,用于从MySQL表中提取数据。我们可以使用称为WHERE子句的条件子句来过滤结果。使用此WHERE子句,我们可以指定选择条件,以从表中选择所需的记录。

语法

以下代码块包含使用WHERE子句从MySQL表中提取数据的SELECT命令的通用SQL语法:

SELECT field1, field2,...fieldN table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
  • 你可以使用逗号分隔一个或多个表,以使用WHERE子句包含各种条件,但WHERE子句是SELECT命令的可选部分。

  • 你可以使用WHERE子句指定任何条件。

  • 你可以使用ANDOR运算符指定多个条件。

  • WHERE子句也可以与DELETE或UPDATE SQL命令一起使用,以指定条件。

WHERE子句在任何编程语言中都像if条件一样工作。此子句用于将给定值与MySQL表中可用的字段值进行比较。如果来自外部的给定值等于MySQL表中可用的字段值,则返回该行。

以下是可与WHERE子句一起使用的运算符列表。

假设字段A包含10,字段B包含20,则:

运算符 描述 示例
= 检查两个操作数的值是否相等,如果相等,则条件为真。 (A = B) 为假。
!= 检查两个操作数的值是否相等,如果不相等,则条件为真。 (A != B) 为真。
> 检查左操作数的值是否大于右操作数的值,如果是,则条件为真。 (A > B) 为假。
< 检查左操作数的值是否小于右操作数的值,如果是,则条件为真。 (A < B) 为真。
>= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件为真。 (A >= B) 为假。
<= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件为真。 (A <= B) 为真。

当你想要从表中提取选定的行时,WHERE子句非常有用,尤其是在使用MySQL连接时。连接在另一章中讨论。

通常的做法是使用主键搜索记录以加快搜索速度。

如果给定的条件与表中的任何记录都不匹配,则查询将不返回任何行。

从命令提示符提取数据

这将使用带有WHERE子句的SQL SELECT命令从MySQL表tutorials_tbl中提取选定的数据。

示例

以下示例将返回tutorials_tbl表中作者姓名为Sanjay的所有记录。

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT * from tutorials_tbl WHERE tutorial_author = 'Sanjay';
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|      3      | JAVA Tutorial  |      Sanjay     |    2007-05-21   |      
+-------------+----------------+-----------------+-----------------+
1 rows in set (0.01 sec)

mysql>

除非对字符串执行LIKE比较,否则比较不区分大小写。你可以使用BINARY关键字使搜索区分大小写,如下所示:

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT * from tutorials_tbl \
   WHERE BINARY tutorial_author = 'sanjay';
Empty set (0.02 sec)

mysql>

使用PHP脚本提取数据

你可以将带有WHERE CLAUSE的相同SQL SELECT命令放入PHP函数mysql_query()中。此函数用于执行SQL命令,然后另一个PHP函数mysql_fetch_array()可以用来提取所有选定的数据。此函数将行作为关联数组、数字数组或两者都返回。如果没有更多行,则此函数返回FALSE。

示例

以下示例将返回tutorials_tbl表中作者姓名为Sanjay的所有记录:

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);

   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }

   $sql = 'SELECT tutorial_id, tutorial_title, 
      tutorial_author, submission_date
      FROM tutorials_tbl
      WHERE tutorial_author = "Sanjay"';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );

   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }

   while($row = mysql_fetch_array($retval, MYSQL_ASSOC)) {
      echo "Tutorial ID :{$row['tutorial_id']}  <br> ".
      "Title: {$row['tutorial_title']} <br> ".
      "Author: {$row['tutorial_author']} <br> ".
      "Submission Date : {$row['submission_date']} <br> ".
      "--------------------------------<br>";
   } 

   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

MySQL - UPDATE查询

可能需要修改MySQL表中的现有数据。你可以使用SQLUPDATE命令来做到这一点。这将修改任何MySQL表的任何字段值。

语法

以下代码块包含修改MySQL表中数据的UPDATE命令的通用SQL语法:

UPDATE table_name SET field1 = new-value1, field2 = new-value2
[WHERE Clause]
  • 你可以同时更新一个或多个字段。
  • 你可以使用WHERE子句指定任何条件。
  • 你可以一次更新单个表中的值。

当你想要更新表中的选定行时,WHERE子句非常有用。

从命令提示符更新数据

这将使用带有WHERE子句的SQL UPDATE命令更新MySQL表tutorials_tbl中的选定数据。

示例

以下示例将更新tutorial_id为3的记录的tutorial_title字段。

root@host# mysql -u root -p password;
Enter password:*******

mysql> use TUTORIALS;
Database changed

mysql> UPDATE tutorials_tbl 
   -> SET tutorial_title = 'Learning JAVA' 
   -> WHERE tutorial_id = 3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>

使用PHP脚本更新数据

可以使用SQL UPDATE命令(带或不带WHERE子句)在PHP函数mysql_query()中。此函数将以类似于在mysql>提示符下执行的方式执行SQL命令。

示例

以下示例更新tutorial_id为3的记录的tutorial_title字段。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   
   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }

   $sql = 'UPDATE tutorials_tbl
      SET tutorial_title="Learning JAVA"
      WHERE tutorial_id=3';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not update data: ' . mysql_error());
   }
   echo "Updated data successfully\n";
   mysql_close($conn);
?>

MySQL - DELETE 查询

如果要从任何MySQL表中删除记录,可以使用SQL命令DELETE FROM。可以在mysql>提示符下以及在任何脚本(如PHP)中使用此命令。

语法

以下代码块包含DELETE命令的通用SQL语法,用于从MySQL表中删除数据。

DELETE FROM table_name [WHERE Clause]
  • 如果没有指定WHERE子句,则将从给定的MySQL表中删除所有记录。

  • 你可以使用WHERE子句指定任何条件。

  • 一次只能删除单个表中的记录。

当要删除表中选定的行时,WHERE子句非常有用。

从命令提示符删除数据

这将使用带有WHERE子句的SQL DELETE命令来删除MySQL表tutorials_tbl中的选定数据。

示例

以下示例将删除tutorial_tbl中tutorial_id为3的记录。

root@host# mysql -u root -p password;
Enter password:*******

mysql> use TUTORIALS;
Database changed

mysql> DELETE FROM tutorials_tbl WHERE tutorial_id=3;
Query OK, 1 row affected (0.23 sec)

mysql>

使用PHP脚本删除数据

可以使用SQL DELETE命令(带或不带WHERE子句)在PHP函数mysql_query()中。此函数将以与在mysql>提示符下执行相同的方式执行SQL命令。

示例

尝试以下示例以删除tutorial_tbl中tutorial_id为3的记录。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   
   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }

   $sql = 'DELETE FROM tutorials_tbl WHERE tutorial_id = 3';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );

   if(! $retval ) {
      die('Could not delete data: ' . mysql_error());
   }
   echo "Deleted data successfully\n";
   mysql_close($conn);
?>

MySQL - LIKE子句

我们已经了解了用于从MySQL表中提取数据的SQL SELECT命令。我们还可以使用称为WHERE子句的条件子句来选择所需的记录。

当我们需要进行精确匹配时,带有“等于”号(=)的WHERE子句运行良好,例如"tutorial_author = 'Sanjay'"。但是,可能需要过滤所有tutorial_author名称包含“jay”的结果。这可以使用SQL LIKE子句以及WHERE子句来处理。

如果SQL LIKE子句与%字符一起使用,则它将像UNIX中的元字符(*)一样工作,同时列出命令提示符下的所有文件或目录。如果没有%字符,LIKE子句与WHERE子句一起使用的“等于”号完全相同。

语法

以下代码块包含SELECT命令以及LIKE子句的通用SQL语法,用于从MySQL表中提取数据。

SELECT field1, field2,...fieldN table_name1, table_name2...
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
  • 你可以使用WHERE子句指定任何条件。

  • 可以使用LIKE子句以及WHERE子句。

  • 可以使用LIKE子句代替等于号。

  • 当LIKE与%符号一起使用时,它将像元字符搜索一样工作。

  • 可以使用ANDOR运算符指定多个条件。

  • WHERE...LIKE子句也可以与DELETE或UPDATE SQL命令一起使用以指定条件。

在命令提示符下使用LIKE子句

这将使用带有WHERE...LIKE子句的SQL SELECT命令从MySQL表tutorials_tbl中提取选定的数据。

示例

以下示例将返回tutorials_tbl表中作者姓名以jay结尾的所有记录:

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT * from tutorials_tbl 
   -> WHERE tutorial_author LIKE '%jay';
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|      3      |  JAVA Tutorial |     Sanjay      |    2007-05-21   |   
+-------------+----------------+-----------------+-----------------+
1 rows in set (0.01 sec)

mysql>

在PHP脚本中使用LIKE子句

可以在PHP函数mysql_query()中使用WHERE...LIKE子句的类似语法。此函数用于执行SQL命令,之后可以使用另一个PHP函数mysql_fetch_array()来提取所有选定的数据(如果WHERE...LIKE子句与SELECT命令一起使用)。

但是,如果WHERE...LIKE子句与DELETE或UPDATE命令一起使用,则不需要进一步的PHP函数调用。

示例

尝试以下示例以返回tutorials_tbl表中作者姓名包含jay的所有记录:

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);

   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }
   $sql = 'SELECT tutorial_id, tutorial_title, 
      tutorial_author, submission_date
      FROM tutorials_tbl
      WHERE tutorial_author LIKE "%jay%"';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }

   while($row = mysql_fetch_array($retval, MYSQL_ASSOC)) {
      echo "Tutorial ID :{$row['tutorial_id']}  <br> ".
         "Title: {$row['tutorial_title']} <br> ".
         "Author: {$row['tutorial_author']} <br> ".
         "Submission Date : {$row['submission_date']} <br> ".
         "--------------------------------<br>";
   } 
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

MySQL - 排序结果

我们已经了解了用于从MySQL表中提取数据的SQL SELECT命令。选择行时,除非您通过说明如何排序结果来指示它,否则MySQL服务器可以自由地以任何顺序返回它们。但是,您可以通过添加一个ORDER BY子句来对结果集进行排序,该子句命名要排序的列或列。

语法

以下代码块是SELECT命令以及ORDER BY子句的通用SQL语法,用于对MySQL表中的数据进行排序。

SELECT field1, field2,...fieldN table_name1, table_name2...
ORDER BY field1, [field2...] [ASC [DESC]]
  • 如果列出了该字段,则可以对任何字段上的返回结果进行排序。

  • 可以对多个字段上的结果进行排序。

  • 可以使用关键字ASC或DESC以升序或降序获取结果。默认情况下,它是升序。

  • 可以照常使用WHERE...LIKE子句来设置条件。

在命令提示符下使用ORDER BY子句

这将使用带有ORDER BY子句的SQL SELECT命令从MySQL表tutorials_tbl中提取数据。

示例

尝试以下示例,该示例以升序返回结果。

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT * from tutorials_tbl ORDER BY tutorial_author ASC
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|      2      |  Learn MySQL   |     Abdul S     |    2007-05-24   |   
|      1      |   Learn PHP    |    John Poul    |    2007-05-24   |   
|      3      | JAVA Tutorial  |     Sanjay      |    2007-05-06   |   
+-------------+----------------+-----------------+-----------------+
3 rows in set (0.42 sec)

mysql>

验证以升序列出的所有作者姓名。

在PHP脚本中使用ORDER BY子句

可以在PHP函数mysql_query()中使用ORDER BY子句的类似语法。此函数用于执行SQL命令,之后可以使用另一个PHP函数mysql_fetch_array()来提取所有选定的数据。

示例

尝试以下示例,该示例以教程作者的降序返回结果。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   
   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }
   $sql = 'SELECT tutorial_id, tutorial_title, 
      tutorial_author, submission_date
      FROM tutorials_tbl
      ORDER BY  tutorial_author DESC';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }

   while($row = mysql_fetch_array($retval, MYSQL_ASSOC)) {
      echo "Tutorial ID :{$row['tutorial_id']}  <br> ".
         "Title: {$row['tutorial_title']} <br> ".
         "Author: {$row['tutorial_author']} <br> ".
         "Submission Date : {$row['submission_date']} <br> ".
         "--------------------------------<br>";
   } 
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

使用MySQL连接

在前面的章节中,我们一次从一个表中获取数据。这对于简单的任务来说已经足够了,但在大多数现实世界的MySQL用法中,您通常需要在单个查询中从多个表中获取数据。

可以在单个SQL查询中使用多个表。在MySQL中连接是指将两个或多个表合并成一个表。

可以在SELECT、UPDATE和DELETE语句中使用连接来连接MySQL表。我们还将看到LEFT JOIN的示例,它与简单的MySQL JOIN不同。

在命令提示符下使用连接

假设我们在TUTORIALS中有两个表tcount_tbltutorials_tbl。现在看看下面给出的例子:

示例

以下示例:

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT * FROM tcount_tbl;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
|      mahran     |       20       |     
|      mahnaz     |      NULL      |        
|       Jen       |      NULL      |          
|      Gill       |       20       |          
|    John Poul    |        1       |      
|     Sanjay      |        1       |        
+-----------------+----------------+
6 rows in set (0.01 sec)
mysql> SELECT * from tutorials_tbl;
+-------------+----------------+-----------------+-----------------+
| tutorial_id | tutorial_title | tutorial_author | submission_date |
+-------------+----------------+-----------------+-----------------+
|      1      |  Learn PHP     |     John Poul   |    2007-05-24   |   
|      2      |  Learn MySQL   |      Abdul S    |    2007-05-24   |   
|      3      | JAVA Tutorial  |      Sanjay     |    2007-05-06   |   
+-------------+----------------+-----------------+-----------------+
3 rows in set (0.00 sec)
mysql>

现在,我们可以编写一个SQL查询来连接这两个表。此查询将从表tutorials_tbl中选择所有作者,并将从tcount_tbl中提取相应的教程数量。

mysql> SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count
   -> FROM tutorials_tbl a, tcount_tbl b
   -> WHERE a.tutorial_author = b.tutorial_author;
+-------------+-----------------+----------------+
| tutorial_id | tutorial_author | tutorial_count |
+-------------+-----------------+----------------+
|      1      |    John Poul    |        1       |
|      3      |     Sanjay      |        1       |
+-------------+-----------------+----------------+
2 rows in set (0.01 sec)
mysql>

在PHP脚本中使用连接

可以在PHP脚本中使用任何上述SQL查询。只需要将SQL查询传递到PHP函数mysql_query()中,然后就可以照常提取结果。

示例

以下示例:

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   
   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }

   $sql = 'SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count
      FROM tutorials_tbl a, tcount_tbl b
      WHERE a.tutorial_author = b.tutorial_author';

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );

   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }

   while($row = mysql_fetch_array($retval, MYSQL_ASSOC)) {
      echo "Author:{$row['tutorial_author']}  <br> ".
         "Count: {$row['tutorial_count']} <br> ".
         "Tutorial ID: {$row['tutorial_id']} <br> ".
         "--------------------------------<br>";
   } 
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

MySQL LEFT JOIN

MySQL左连接与简单的连接不同。MySQL LEFT JOIN对左侧的表给予额外的考虑。

如果执行LEFT JOIN,则会获得以相同方式匹配的所有记录,此外,还会为连接左侧表中的每个不匹配记录获得额外的记录:从而确保(在我的示例中)每个作者都会被提及。

示例

尝试以下示例以了解LEFT JOIN。

root@host# mysql -u root -p password;
Enter password:*******
mysql> use TUTORIALS;
Database changed
mysql> SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count
   -> FROM tutorials_tbl a LEFT JOIN tcount_tbl b
   -> ON a.tutorial_author = b.tutorial_author;
+-------------+-----------------+----------------+
| tutorial_id | tutorial_author | tutorial_count |
+-------------+-----------------+----------------+
|      1      |    John Poul    |       1        |
|      2      |     Abdul S     |      NULL      |
|      3      |     Sanjay      |       1        |
+-------------+-----------------+----------------+
3 rows in set (0.02 sec)

您需要进行更多练习才能熟悉连接。这是MySQL/SQL中稍微有点复杂的概念,在进行实际示例时会变得更加清晰。

处理MySQL NULL值

我们已经了解了带有WHERE子句的SQL SELECT命令,用于从MySQL表中提取数据,但是当我们尝试给出比较字段或列值与NULL的条件时,它不能正常工作。

为了处理这种情况,MySQL提供了三个运算符:

  • IS NULL - 如果列值为NULL,则此运算符返回true。

  • IS NOT NULL - 如果列值不为NULL,则此运算符返回true。

  • <=> - 此运算符比较值,即使对于两个NULL值,它(与=运算符不同)也为true。

涉及NULL的条件是特殊的。不能使用= NULL或!= NULL来查找列中的NULL值。此类比较总是失败,因为不可能判断它们是真还是假。有时,即使NULL = NULL也会失败。

要查找是或不是NULL的列,请使用IS NULLIS NOT NULL

在命令提示符下使用NULL值

假设TUTORIALS数据库中有一个名为tcount_tbl的表,它包含名为tutorial_authortutorial_count的两列,其中NULL tutorial_count表示该值为未知。

示例

尝试以下示例:

root@host# mysql -u root -p password;
Enter password:*******

mysql> use TUTORIALS;
Database changed

mysql> create table tcount_tbl
   -> (
   -> tutorial_author varchar(40) NOT NULL,
   -> tutorial_count  INT
   -> );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tcount_tbl
   -> (tutorial_author, tutorial_count) values ('mahran', 20);

mysql> INSERT INTO tcount_tbl
   -> (tutorial_author, tutorial_count) values ('mahnaz', NULL);

mysql> INSERT INTO tcount_tbl
   -> (tutorial_author, tutorial_count) values ('Jen', NULL);

mysql> INSERT INTO tcount_tbl
   -> (tutorial_author, tutorial_count) values ('Gill', 20);

mysql> SELECT * from tcount_tbl;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
|     mahran      |       20       |
|     mahnaz      |      NULL      |
|      Jen        |      NULL      |
|     Gill        |       20       |
+-----------------+----------------+
4 rows in set (0.00 sec)

mysql>

您可以看到=和!=不适用于NULL值,如下所示:

mysql> SELECT * FROM tcount_tbl WHERE tutorial_count = NULL;
Empty set (0.00 sec)

mysql> SELECT * FROM tcount_tbl WHERE tutorial_count != NULL;
Empty set (0.01 sec)

要查找tutorial_count列是或不是NULL的记录,应按以下程序中所示编写查询。

mysql> SELECT * FROM tcount_tbl 
   -> WHERE tutorial_count IS NULL;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
|     mahnaz      |      NULL      |
|      Jen        |      NULL      |
+-----------------+----------------+
2 rows in set (0.00 sec)
mysql> SELECT * from tcount_tbl 
   -> WHERE tutorial_count IS NOT NULL;
+-----------------+----------------+
| tutorial_author | tutorial_count |
+-----------------+----------------+
|     mahran      |       20       |
|     Gill        |       20       |
+-----------------+----------------+
2 rows in set (0.00 sec)

在PHP脚本中处理NULL值

可以使用if...else条件根据NULL值准备查询。

示例

以下示例从外部获取tutorial_count,然后将其与表中可用的值进行比较。

<?php
   $dbhost = 'localhost:3036';
   $dbuser = 'root';
   $dbpass = 'rootpassword';
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);

   if(! $conn ) {
      die('Could not connect: ' . mysql_error());
   }

   if( isset($tutorial_count )) {
      $sql = 'SELECT tutorial_author, tutorial_count
         FROM  tcount_tbl
         WHERE tutorial_count = $tutorial_count';
   } else {
      $sql = 'SELECT tutorial_author, tutorial_count
         FROM  tcount_tbl
         WHERE tutorial_count IS $tutorial_count';
   }

   mysql_select_db('TUTORIALS');
   $retval = mysql_query( $sql, $conn );
   
   if(! $retval ) {
      die('Could not get data: ' . mysql_error());
   }

   while($row = mysql_fetch_array($retval, MYSQL_ASSOC)) {
      echo "Author:{$row['tutorial_author']}  <br> ".
         "Count: {$row['tutorial_count']} <br> ".
         "--------------------------------<br>";
   } 
   echo "Fetched data successfully\n";
   mysql_close($conn);
?>

MySQL - 正则表达式

您已经了解了使用LIKE ...%的MySQL模式匹配。MySQL支持另一种基于正则表达式和REGEXP运算符的模式匹配操作。如果您了解PHP或PERL,那么您很容易理解,因为这种匹配与那些编写正则表达式的脚本语言相同。

以下是可以在REGEXP运算符一起使用的模式表。

模式 模式匹配的内容
^ 字符串开头
$ 字符串结尾
. 任何单个字符
[...] 方括号之间列出的任何字符
[^...] 方括号之间未列出的任何字符
p1|p2|p3 替换;匹配模式p1、p2或p3中的任何一个
* 前面元素的零个或多个实例
+ 前面元素的一个或多个实例
{n} 前面元素的n个实例
{m,n} 前面元素的m到n个实例

示例

现在,根据上表,您可以设计各种类型的SQL查询来满足您的需求。在这里,我列出了一些供您理解。

假设我们有一个名为person_tbl的表,它有一个名为name的字段:

查找所有以'st'开头的名称的查询:

mysql> SELECT name FROM person_tbl WHERE name REGEXP '^st';

查找所有以'ok'结尾的名称的查询:

mysql> SELECT name FROM person_tbl WHERE name REGEXP 'ok$';

查找所有包含'mar'的名称的查询:

mysql> SELECT name FROM person_tbl WHERE name REGEXP 'mar';

查找所有以元音开头并以'ok'结尾的名称的查询:

mysql> SELECT FirstName FROM intque.person_tbl WHERE FirstName REGEXP '^[aeiou].*ok$';

MySQL - 事务

事务是一组按顺序执行的数据库操作,这些操作的执行如同一个单一的工作单元。换句话说,除非组中的每个单独操作都成功,否则事务永远不会完成。如果事务中的任何操作失败,则整个事务将失败。

实际上,您会将许多SQL查询组合到一个组中,并将它们一起作为事务的一部分执行。

事务的属性

事务具有以下四个标准属性,通常用首字母缩写词ACID表示:

  • 原子性 (Atomicity) − 确保工作单元中的所有操作都成功完成;否则,事务将在发生故障的点中止,之前的操作将回滚到其以前的状态。

  • 一致性 (Consistency) − 确保数据库在成功提交事务后正确更改状态。

  • 隔离性 (Isolation) − 使事务能够独立运行,并且彼此透明。

  • 持久性 (Durability) − 确保已提交事务的结果或影响在系统故障的情况下仍然存在。

在 MySQL 中,事务以语句BEGIN WORK 开始,并以COMMITROLLBACK 语句结束。开始和结束语句之间的 SQL 命令构成事务的主体。

COMMIT 和 ROLLBACK

这两个关键字CommitRollback 主要用于 MySQL 事务。

  • 成功完成事务后,应发出 COMMIT 命令,以便对所有相关表所做的更改生效。

  • 如果发生故障,应发出 ROLLBACK 命令,以将事务中引用的每个表恢复到其先前状态。

您可以通过设置名为AUTOCOMMIT 的会话变量来控制事务的行为。如果将 AUTOCOMMIT 设置为 1(默认值),则每个 SQL 语句(无论是否在事务中)都被视为一个完整的事务,并在完成时默认提交。

当 AUTOCOMMIT 设置为 0 时,通过发出SET AUTOCOMMIT = 0 命令,后续的语句序列将像事务一样,在发出显式的 COMMIT 语句之前不会提交任何活动。

您可以使用mysql_query() 函数在 PHP 中执行这些 SQL 命令。

事务的通用示例

此事件序列与使用的编程语言无关。可以使用任何语言创建逻辑路径来创建应用程序。

您可以使用mysql_query() 函数在 PHP 中执行这些 SQL 命令。

  • 通过发出 SQL 命令BEGIN WORK 开始事务。

  • 发出一个或多个 SQL 命令,例如 SELECT、INSERT、UPDATE 或 DELETE。

  • 检查是否没有错误,并且一切符合您的要求。

  • 如果有任何错误,则发出 ROLLBACK 命令,否则发出 COMMIT 命令。

MySQL 中支持事务的表类型

您不能直接使用事务,但在某些例外情况下可以。但是,它们并不安全且无法保证。如果您计划在 MySQL 编程中使用事务,则需要以特殊方式创建表。许多类型的表支持事务,但最常用的是InnoDB

支持 InnoDB 表需要在从源代码编译 MySQL 时使用特定的编译参数。如果您的 MySQL 版本不支持 InnoDB,请要求您的互联网服务提供商构建支持 InnoDB 表类型的 MySQL 版本,或者下载并安装适用于 Windows 或 Linux/UNIX 的MySQL-Max 二进制发行版,并在开发环境中使用该表类型。

如果您的 MySQL 安装支持 InnoDB 表,只需在表创建语句中添加TYPE = InnoDB 定义即可。

例如,以下代码创建一个名为tcount_tbl 的 InnoDB 表:

root@host# mysql -u root -p password;
Enter password:*******

mysql> use TUTORIALS;
Database changed

mysql> create table tcount_tbl
   -> (
   -> tutorial_author varchar(40) NOT NULL,
   -> tutorial_count  INT
   -> ) TYPE = InnoDB;
Query OK, 0 rows affected (0.05 sec)

有关 InnoDB 的更多详细信息,您可以点击以下链接:InnoDB

您可以使用其他表类型,例如GEMINIBDB,但这取决于您的安装是否支持这两种表类型。

MySQL - ALTER 命令

当您想要更改表名、任何表字段或想要添加或删除表中的现有列时,MySQL 的ALTER 命令非常有用。

让我们从创建一个名为testalter_tbl 的表开始。

root@host# mysql -u root -p password;
Enter password:*******

mysql> use TUTORIALS;
Database changed

mysql> create table testalter_tbl
   -> (
   -> i INT,
   -> c CHAR(1)
   -> );
Query OK, 0 rows affected (0.05 sec)
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field |  Type   | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
|   i   | int(11) | YES  |     |   NULL  |       |
|   c   | char(1) | YES  |     |   NULL  |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

删除、添加或重新定位列

如果要从上面的 MySQL 表中删除现有列 i,则可以使用DROP 子句以及ALTER 命令,如下所示:

mysql> ALTER TABLE testalter_tbl  DROP i;

如果列是表中剩下的唯一列,则DROP 子句将不起作用。

要添加列,请使用 ADD 并指定列定义。以下语句将i 列恢复到 testalter_tbl:

mysql> ALTER TABLE testalter_tbl ADD i INT;

发出此语句后,testalter 将包含与您第一次创建表时相同的两列,但结构不同。这是因为默认情况下,新列添加到表的末尾。因此,即使i 最初是 mytbl 中的第一列,现在它也是最后一列。

mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field |  Type   | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
|   c   | char(1) | YES  |     |   NULL  |       |
|   i   | int(11) | YES  |     |   NULL  |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

要指示您想要表中特定位置的列,请使用 FIRST 将其设为第一列,或使用AFTER col_name 指示新列应放在 col_name 之后。

尝试以下ALTER TABLE 语句,并在每个语句之后使用SHOW COLUMNS 查看每个语句的效果:

ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT FIRST;
ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT AFTER c;

FIRST 和 AFTER 说明符仅适用于 ADD 子句。这意味着,如果您想重新定位表中的现有列,则必须先DROP 它,然后在新的位置ADD 它。

更改列定义或名称

要更改列的定义,请使用MODIFYCHANGE 子句以及 ALTER 命令。

例如,要将列c 从 CHAR(1) 更改为 CHAR(10),可以使用以下命令:

mysql> ALTER TABLE testalter_tbl MODIFY c CHAR(10);

使用CHANGE,语法略有不同。在 CHANGE 关键字之后,命名要更改的列,然后指定新定义,其中包括新名称。

尝试以下示例:

mysql> ALTER TABLE testalter_tbl CHANGE i j BIGINT;

如果您现在使用 CHANGE 将jBIGINT 转换回INT 而不更改列名,则语句将如下所示:

mysql> ALTER TABLE testalter_tbl CHANGE j j INT;

ALTER TABLE 对 NULL 和默认值属性的影响 − 当您修改或更改列时,您还可以指定列是否可以包含 NULL 值以及其默认值是什么。事实上,如果您不这样做,MySQL 会自动为这些属性赋值。

以下代码块是一个示例,其中NOT NULL 列的默认值为 100。

mysql> ALTER TABLE testalter_tbl 
   -> MODIFY j BIGINT NOT NULL DEFAULT 100;

如果您不使用上述命令,则 MySQL 将在所有列中填充 NULL 值。

更改列的默认值

您可以使用ALTER 命令更改任何列的默认值。

试试下面的例子。

mysql> ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field |  Type   | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
|   c   | char(1) | YES  |     |   NULL  |       |
|   i   | int(11) | YES  |     |   1000  |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

您可以使用 DROP 子句以及ALTER 命令从任何列中删除默认约束。

mysql> ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
mysql> SHOW COLUMNS FROM testalter_tbl;
+-------+---------+------+-----+---------+-------+
| Field |  Type   | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
|   c   | char(1) | YES  |     |   NULL  |       |
|   i   | int(11) | YES  |     |   NULL  |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

更改表类型

您可以使用TYPE 子句以及 ALTER 命令使用表类型。尝试以下示例将testalter_tbl 更改为MYISAM 表类型。

要查找表的当前类型,请使用SHOW TABLE STATUS 语句。

mysql> ALTER TABLE testalter_tbl TYPE = MYISAM;
mysql>  SHOW TABLE STATUS LIKE 'testalter_tbl'\G
*************************** 1. row ****************
           Name: testalter_tbl
           Type: MyISAM
     Row_format: Fixed
           Rows: 0
 Avg_row_length: 0
    Data_length: 0
Max_data_length: 25769803775
   Index_length: 1024
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2007-06-03 08:04:36
    Update_time: 2007-06-03 08:04:36
     Check_time: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

重命名表

要重命名表,请使用ALTER TABLE 语句的RENAME 选项。

尝试以下示例将testalter_tbl 重命名为alter_tbl

mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;

您可以使用 ALTER 命令在 MySQL 文件上创建和删除 INDEX 命令。我们将在下一章详细讨论此命令。

MySQL - 索引

数据库索引是一种数据结构,可以提高表中操作的速度。索引可以使用一个或多个列创建,为快速随机查找和高效访问记录排序提供基础。

创建索引时,应考虑哪些列将用于执行 SQL 查询,并在这些列上创建一个或多个索引。

实际上,索引也是一种表,它保存主键或索引字段以及指向实际表中每个记录的指针。

用户无法看到索引,它们仅用于加快查询速度,并将由数据库搜索引擎用于快速定位记录。

对于具有索引的表,INSERT 和 UPDATE 语句需要更多时间,而 SELECT 语句在这些表上会变快。原因是在进行插入或更新时,数据库也需要插入或更新索引值。

简单索引和唯一索引

您可以在表上创建唯一索引。唯一索引意味着两行不能具有相同的索引值。以下是创建表索引的语法。

CREATE UNIQUE INDEX index_name ON table_name ( column1, column2,...);

您可以使用一个或多个列来创建索引。

例如,我们可以使用tutorial_authortutorials_tbl 上创建索引。

CREATE UNIQUE INDEX AUTHOR_INDEX ON tutorials_tbl (tutorial_author)

您可以在表上创建简单索引。只需从查询中省略UNIQUE 关键字即可创建简单索引。简单索引允许表中出现重复值。

如果要按降序对列中的值进行索引,可以在列名后添加保留字 DESC。

mysql> CREATE UNIQUE INDEX AUTHOR_INDEX ON tutorials_tbl (tutorial_author DESC)

使用 ALTER 命令添加和删除索引

有四种类型的语句用于向表中添加索引:

  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list) − 此语句添加PRIMARY KEY,这意味着索引值必须唯一且不能为 NULL。

  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list) − 此语句创建一个索引,其值必须唯一(NULL 值除外,NULL 值可以多次出现)。

  • ALTER TABLE tbl_name ADD INDEX index_name (column_list) − 这将添加一个普通索引,其中任何值都可以出现多次。

  • ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list) − 这将创建一个特殊的 FULLTEXT 索引,用于文本搜索。

以下代码块是向现有表中添加索引的示例。

mysql> ALTER TABLE testalter_tbl ADD INDEX (c);

您可以使用DROP 子句以及 ALTER 命令删除任何索引。

尝试以下示例以删除上面创建的索引。

mysql> ALTER TABLE testalter_tbl DROP INDEX (c);

您可以使用 DROP 子句以及 ALTER 命令删除任何索引。

使用 ALTER 命令添加和删除主键

您可以以相同的方式添加主键。但请确保主键适用于非 NULL 列。

以下代码块是向现有表中添加主键的示例。这将首先使列 NOT NULL,然后将其添加为主键。

mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);

您可以按如下方式使用 ALTER 命令删除主键:

mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;

要删除不是 PRIMARY KEY 的索引,必须指定索引名称。

显示索引信息

您可以使用SHOW INDEX 命令列出与表关联的所有索引。垂直格式输出(由 \G 指定)在此语句中通常很有用,可以避免长行换行:

尝试以下示例:

mysql> SHOW INDEX FROM table_name\G
........

MySQL - 临时表

临时表在某些情况下可能非常有用,用于保存临时数据。关于临时表,最重要的一点是,它们将在当前客户端会话终止时被删除。

什么是临时表?

临时表是在 MySQL 3.23 版本中添加的。如果您使用的 MySQL 版本早于 3.23,则无法使用临时表,但可以使用堆表 (Heap Tables)

如前所述,临时表仅在会话有效期间存在。如果您在 PHP 脚本中运行代码,则在脚本执行完毕后,临时表将自动销毁。如果您通过 MySQL 客户端程序连接到 MySQL 数据库服务器,则临时表将一直存在,直到您关闭客户端或手动销毁该表。

示例

以下程序是一个示例,向您展示了临时表的使用方法。可以使用mysql_query() 函数在 PHP 脚本中使用相同的代码。

mysql> CREATE TEMPORARY TABLE SalesSummary (
   -> product_name VARCHAR(50) NOT NULL
   -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
   -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
   -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SalesSummary
   -> (product_name, total_sales, avg_unit_price, total_units_sold)
   -> VALUES
   -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
|   cucumber   |   100.25    |     90.00      |         2        |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

当您发出SHOW TABLES 命令时,您的临时表将不会列在列表中。现在,如果您注销 MySQL 会话然后发出SELECT 命令,您会发现数据库中没有可用数据。甚至您的临时表也将不存在。

删除临时表

默认情况下,当您的数据库连接终止时,所有临时表都将被 MySQL 删除。如果您仍想在两者之间删除它们,则可以通过发出DROP TABLE 命令来实现。

下面的程序演示了如何删除临时表。

mysql> CREATE TEMPORARY TABLE SalesSummary (
   -> product_name VARCHAR(50) NOT NULL
   -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
   -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
   -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SalesSummary
   -> (product_name, total_sales, avg_unit_price, total_units_sold)
   -> VALUES
   -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
|   cucumber   |   100.25    |     90.00      |         2        |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE SalesSummary;
mysql>  SELECT * FROM SalesSummary;
ERROR 1146: Table 'TUTORIALS.SalesSummary' doesn't exist

MySQL - 克隆表

你可能需要一个表的精确副本,而CREATE TABLE ... SELECT语句不适合你的目的,因为副本必须包含相同的索引、默认值等等。

你可以按照以下步骤处理这种情况:

  • 使用SHOW CREATE TABLE 获取指定源表结构、索引等的 CREATE TABLE 语句。

  • 修改该语句,将表名更改为克隆表的表名,然后执行该语句。这样,你将拥有精确的克隆表。

  • 可选地,如果你也需要复制表内容,则也要发出 INSERT INTO ... SELECT 语句。

示例

尝试以下示例,为tutorials_tbl创建克隆表。

步骤 1 - 获取有关表的完整结构。

mysql> SHOW CREATE TABLE tutorials_tbl \G;
*************************** 1. row ***************************
      Table: tutorials_tbl
Create Table: CREATE TABLE `tutorials_tbl` (
   `tutorial_id` int(11) NOT NULL auto_increment,
   `tutorial_title` varchar(100) NOT NULL default '',
   `tutorial_author` varchar(40) NOT NULL default '',
   `submission_date` date default NULL,
   PRIMARY KEY  (`tutorial_id`),
   UNIQUE KEY `AUTHOR_INDEX` (`tutorial_author`)
) TYPE = MyISAM
1 row in set (0.00 sec)

ERROR:
No query specified

步骤 2 - 重命名此表并创建另一个表。

mysql> CREATE TABLE clone_tbl (
   -> tutorial_id int(11) NOT NULL auto_increment,
   -> tutorial_title varchar(100) NOT NULL default '',
   -> tutorial_author varchar(40) NOT NULL default '',
   -> submission_date date default NULL,
   -> PRIMARY KEY  (tutorial_id),
   -> UNIQUE KEY AUTHOR_INDEX (tutorial_author)
-> ) TYPE = MyISAM;
Query OK, 0 rows affected (1.80 sec)

步骤 3 - 执行步骤 2 后,你将在数据库中创建一个克隆表。如果你想从旧表复制数据,可以使用 INSERT INTO... SELECT 语句。

mysql> INSERT INTO clone_tbl (tutorial_id,
   -> tutorial_title,
   -> tutorial_author,
   -> submission_date)
   
   -> SELECT tutorial_id,tutorial_title,
   -> tutorial_author,submission_date
   -> FROM tutorials_tbl;
Query OK, 3 rows affected (0.07 sec)
Records: 3  Duplicates: 0  Warnings: 0

最终,你将拥有你想要的精确克隆表。

MySQL - 数据库信息

获取和使用MySQL元数据

你可能需要从MySQL获取三种类型的信息。

  • 查询结果信息 - 这包括任何SELECT、UPDATE或DELETE语句影响的记录数。

  • 表和数据库信息 - 这包括与表和数据库结构相关的信息。

  • MySQL服务器信息 - 这包括数据库服务器的状态、版本号等。

在MySQL提示符下很容易获得所有这些信息,但在使用PERL或PHP API时,我们需要显式调用各种API才能获得所有这些信息。

获取查询影响的行数

现在让我们看看如何获取这些信息。

PERL示例

在DBI脚本中,受影响的行数由do( )execute( )命令返回,具体取决于你如何执行查询。

# Method 1
# execute $query using do( )
my $count = $dbh->do ($query);
# report 0 rows if an error occurred
printf "%d rows were affected\n", (defined ($count) ? $count : 0);

# Method 2
# execute query using prepare( ) plus execute( )
my $sth = $dbh->prepare ($query);
my $count = $sth->execute ( );
printf "%d rows were affected\n", (defined ($count) ? $count : 0);

PHP示例

在PHP中,调用mysql_affected_rows( )函数来找出查询更改的行数。

$result_id = mysql_query ($query, $conn_id);
# report 0 rows if the query failed
$count = ($result_id ? mysql_affected_rows ($conn_id) : 0);
print ("$count rows were affected\n");

列出表和数据库

列出数据库服务器上可用的所有数据库和表非常容易。如果你没有足够的权限,你的结果可能是null

除了以下代码块中显示的方法外,你还可以使用SHOW TABLESSHOW DATABASES查询来获取PHP或PERL中表或数据库的列表。

PERL示例

# Get all the tables available in current database.
my @tables = $dbh->tables ( );

foreach $table (@tables ){
   print "Table Name $table\n";
}

PHP示例

<?php
   $con = mysql_connect("localhost", "userid", "password");
   
   if (!$con) {
      die('Could not connect: ' . mysql_error());
   }
   $db_list = mysql_list_dbs($con);

   while ($db = mysql_fetch_object($db_list)) {
      echo $db->Database . "<br />";
   }
   mysql_close($con);
?>

获取服务器元数据

MySQL中有一些重要的命令,可以在MySQL提示符下执行,也可以使用PHP之类的脚本执行,以获取有关数据库服务器的各种重要信息。

序号 命令与描述
1

SELECT VERSION( )

服务器版本字符串

2

SELECT DATABASE( )

当前数据库名称(如果没有则为空)

3

SELECT USER( )

当前用户名

4

SHOW STATUS

服务器状态指示器

5

SHOW VARIABLES

服务器配置变量

使用MySQL序列

序列是一组按特定需求生成的整数1、2、3……序列在数据库中经常使用,因为许多应用程序要求表中的每一行都包含唯一值,而序列提供了一种生成它们简单的方法。

本章介绍如何在MySQL中使用序列。

使用AUTO_INCREMENT列

在MySQL中使用序列最简单的方法是将列定义为AUTO_INCREMENT,并将其余事情留给MySQL处理。

示例

尝试以下示例。这将创建表,然后在此表中插入几行,其中不需要提供记录 ID,因为它是MySQL自动递增的。

mysql> CREATE TABLE insect
   -> (
   -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   -> PRIMARY KEY (id),
   -> name VARCHAR(30) NOT NULL, # type of insect
   -> date DATE NOT NULL, # date collected
   -> origin VARCHAR(30) NOT NULL # where collected
);
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO insect (id,name,date,origin) VALUES
   -> (NULL,'housefly','2001-09-10','kitchen'),
   -> (NULL,'millipede','2001-09-10','driveway'),
   -> (NULL,'grasshopper','2001-09-10','front yard');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> SELECT * FROM insect ORDER BY id;
+----+-------------+------------+------------+
| id |    name     |    date    |   origin   |
+----+-------------+------------+------------+
|  1 |  housefly   | 2001-09-10 |   kitchen  |
|  2 |  millipede  | 2001-09-10 |  driveway  |
|  3 | grasshopper | 2001-09-10 | front yard |
+----+-------------+------------+------------+
3 rows in set (0.00 sec)

获取AUTO_INCREMENT值

LAST_INSERT_ID( )是一个SQL函数,因此你可以从任何理解如何发出SQL语句的客户端中使用它。否则,PERL和PHP脚本提供独占函数来检索最后一条记录的自动递增值。

PERL示例

使用mysql_insertid属性获取查询生成的AUTO_INCREMENT值。根据你发出查询的方式,可以通过数据库句柄或语句句柄访问此属性。

以下示例通过数据库句柄引用它。

$dbh->do ("INSERT INTO insect (name,date,origin)
VALUES('moth','2001-09-14','windowsill')");
my $seq = $dbh->{mysql_insertid};

PHP示例

发出生成AUTO_INCREMENT值的查询后,通过调用mysql_insert_id( )命令检索该值。

mysql_query ("INSERT INTO insect (name,date,origin)
VALUES('moth','2001-09-14','windowsill')", $conn_id);
$seq = mysql_insert_id ($conn_id);

重新编号现有序列

你可能删除了表中的许多记录,并且想要重新排序所有记录。这可以通过一个简单的技巧来完成,但是如果你的表与其他表有连接,则应非常小心地执行此操作。

如果你确定必须重新排序AUTO_INCREMENT列,那么方法是从表中删除该列,然后重新添加它。

以下示例演示如何使用此技术重新编号表中的id值

mysql> ALTER TABLE insect DROP id;
mysql> ALTER TABLE insect
   -> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
   -> ADD PRIMARY KEY (id);

从特定值开始序列

默认情况下,MySQL将从1开始序列,但你也可以在创建表时指定任何其他数字。

下面的程序是一个示例,它显示了MySQL如何从100开始序列。

mysql> CREATE TABLE insect
   -> (
   -> id INT UNSIGNED NOT NULL AUTO_INCREMENT = 100,
   -> PRIMARY KEY (id),
   -> name VARCHAR(30) NOT NULL, # type of insect
   -> date DATE NOT NULL, # date collected
   -> origin VARCHAR(30) NOT NULL # where collected
);

或者,你可以创建表,然后使用ALTER TABLE命令设置初始序列值。

mysql> ALTER TABLE t AUTO_INCREMENT = 100;

MySQL - 处理重复数据

通常,表或结果集有时包含重复记录。大多数情况下这是允许的,但有时需要停止重复记录。需要识别重复记录并将其从表中删除。本章将介绍如何防止表中出现重复记录以及如何删除已存在的重复记录。

防止表中出现重复项

你可以使用具有适当字段的表上的PRIMARY KEYUNIQUE索引来停止重复记录。

让我们举个例子 - 下表不包含此类索引或主键,因此它允许first_namelast_name的重复记录。

CREATE TABLE person_tbl (
   first_name CHAR(20),
   last_name CHAR(20),
   sex CHAR(10)
);

为了防止在此表中创建具有相同first和last name值的多个记录,请向其定义添加PRIMARY KEY。当你这样做时,还需要声明索引列为NOT NULL,因为PRIMARY KEY不允许NULL值:

CREATE TABLE person_tbl (
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10),
   PRIMARY KEY (last_name, first_name)
);

表中唯一索引的存在通常会导致发生错误,如果你将记录插入到表中,该记录会复制定义索引的列中的现有记录。

使用INSERT IGNORE命令而不是INSERT命令。如果记录不重复现有记录,则MySQL会像往常一样插入它。如果记录是重复的,则IGNORE关键字会告诉MySQL静默地丢弃它,而不会生成错误。

以下示例不会出错,同时也不会插入重复记录。

mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Jay', 'Thomas');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Jay', 'Thomas');
Query OK, 0 rows affected (0.00 sec)

使用REPLACE命令而不是INSERT命令。如果记录是新的,则与INSERT一样插入。如果它是重复的,则新记录将替换旧记录。

mysql> REPLACE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Ajay', 'Kumar');
Query OK, 1 row affected (0.00 sec)

mysql> REPLACE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Ajay', 'Kumar');
Query OK, 2 rows affected (0.00 sec)

应根据你希望实现的重复处理行为选择INSERT IGNORE和REPLACE命令。INSERT IGNORE命令保留第一组重复记录并丢弃其余记录。REPLACE命令保留最后一组重复项并擦除任何较早的重复项。

强制唯一性的另一种方法是向表添加UNIQUE索引而不是PRIMARY KEY。

CREATE TABLE person_tbl (
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10)
   UNIQUE (last_name, first_name)
);

计算和识别重复项

以下是计算表中first_name和last_name重复记录的查询。

mysql> SELECT COUNT(*) as repetitions, last_name, first_name
   -> FROM person_tbl
   -> GROUP BY last_name, first_name
   -> HAVING repetitions > 1;

此查询将返回person_tbl表中所有重复记录的列表。通常,要识别重复的值集,请按照以下步骤操作。

  • 确定哪些列包含可能重复的值。

  • 将这些列列在列选择列表中,以及COUNT(*)

  • 也在GROUP BY子句中列出这些列。

  • 添加一个HAVING子句,通过要求组计数大于一来消除唯一值。

从查询结果中消除重复项

你可以将DISTINCT命令与SELECT语句一起使用来查找表中可用的唯一记录。

mysql> SELECT DISTINCT last_name, first_name
   -> FROM person_tbl
   -> ORDER BY last_name;

DISTINCT命令的替代方法是添加一个GROUP BY子句,命名你正在选择的列。这将删除重复项并仅选择指定列中唯一值的组合。

mysql> SELECT last_name, first_name
   -> FROM person_tbl
   -> GROUP BY (last_name, first_name);

使用表替换删除重复项

如果表中存在重复记录,并且想要从该表中删除所有重复记录,请按照以下步骤操作。

mysql> CREATE TABLE tmp SELECT last_name, first_name, sex
   -> FROM person_tbl;
   -> GROUP BY (last_name, first_name);

mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;

从表中删除重复记录的一种简单方法是向该表添加INDEX或PRIMARY KEY。即使此表已经可用,你也可以使用此技术来删除重复记录,并且将来也能安全无虞。

mysql> ALTER IGNORE TABLE person_tbl
   -> ADD PRIMARY KEY (last_name, first_name);

MySQL和SQL注入

如果你通过网页获取用户输入并将其插入到MySQL数据库中,则你可能让自己容易受到称为SQL注入的安全问题的影响。本章将教你如何帮助防止这种情况发生,并帮助你保护你的脚本和MySQL语句。

SQL注入通常发生在你向用户索取输入(例如他们的姓名)时,他们提供的不是姓名,而是你将在不知情的情况下在数据库上运行的MySQL语句。

永远不要信任用户提供的数据,只有在验证后才能处理此数据;通常,这是通过模式匹配完成的。在下面的示例中,用户名仅限于字母数字字符加下划线,长度在8到20个字符之间 - 根据需要修改这些规则。

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM users WHERE username = $matches[0]");
} else  {
   echo "username not accepted";
}

为了演示这个问题,请考虑以下摘录。

// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name = '{$name}'");

函数调用应该从users表中检索一条记录,其中name列与用户指定的name匹配。在正常情况下,$name只包含字母数字字符和空格。但是在这里,通过将全新的查询附加到$name,对数据库的调用变成了灾难。注入的DELETE查询删除了users中的所有记录。

幸运的是,如果你使用MySQL,mysql_query()函数不允许查询堆叠或在一个函数调用中执行多个查询。如果你尝试堆叠查询,则调用会失败。

但是,其他PHP数据库扩展(例如SQLitePostgreSQL)会愉快地执行堆叠查询,执行在一个字符串中提供的所有查询,并创建一个严重的安全问题。

防止SQL注入

你可以在PERL和PHP等脚本语言中巧妙地处理所有转义字符。PHP的MySQL扩展提供函数mysql_real_escape_string()来转义对MySQL而言特殊的输入字符。

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}

$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name = '{$name}'");

LIKE难题

为了解决LIKE难题,自定义转义机制必须将用户提供的%和_字符转换为字面量。使用addcslashes(),这是一个允许你指定要转义的字符范围的函数。

$sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
// $sub == \%something\_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");

MySQL - 数据库导出

将表数据导出到文本文件的简单方法是使用SELECT...INTO OUTFILE语句,该语句将查询结果直接导出到服务器主机上的文件。

使用SELECT ... INTO OUTFILE语句导出数据

此语句的语法将常规SELECT命令与INTO OUTFILE filename组合在末尾。默认输出格式与LOAD DATA命令相同。因此,以下语句将tutorials_tbl表导出到/tmp/tutorials.txt,作为一个制表符分隔、换行符终止的文件。

mysql> SELECT * FROM tutorials_tbl 
   -> INTO OUTFILE '/tmp/tutorials.txt';

您可以使用各种选项更改输出格式,以指示如何引用和分隔列和记录。要以CRLF结尾的行导出tutorial_tbl表为CSV格式,请使用以下代码。

mysql> SELECT * FROM passwd INTO OUTFILE '/tmp/tutorials.txt'
   -> FIELDS TERMINATED BY ',' ENCLOSED BY '"'
   -> LINES TERMINATED BY '\r\n';

SELECT ... INTO OUTFILE语句具有以下特性:

  • 输出文件由MySQL服务器直接创建,因此文件名应指示您希望将文件写入服务器主机上的哪个位置。没有类似于LOAD DATALOCAL版本的语句。

  • 您必须拥有MySQL FILE权限才能执行SELECT ... INTO语句。

  • 输出文件必须不存在。这可以防止MySQL覆盖可能重要的文件。

  • 您应该在服务器主机上拥有登录帐户或某种方法可以从该主机检索文件。否则,SELECT ... INTO OUTFILE命令很可能对您毫无价值。

  • 在UNIX下,创建的文件是世界可读的,并且属于MySQL服务器。这意味着虽然您可以读取该文件,但您可能无法删除它。

将表导出为原始数据

mysqldump程序用于复制或备份表和数据库。它可以将表输出写入原始数据文件或作为一组INSERT语句,这些语句可以重新创建表中的记录。

要将表作为数据文件转储,必须指定一个--tab选项,该选项指示MySQL服务器要写入文件的目录。

例如,要将TUTORIALS数据库中的tutorials_tbl表转储到/tmp目录中的文件,请使用如下所示的命令。

$ mysqldump -u root -p --no-create-info \
   --tab=/tmp tutorials tutorials_tbl
password ******

以SQL格式导出表内容或定义

要以SQL格式将表导出到文件,请使用以下命令。

$ mysqldump -u root -p TUTORIALS tutorials_tbl > dump.txt
password ******

这将创建一个内容如下所示的文件。

-- MySQL dump 8.23
--
-- Host: localhost    Database: TUTORIALS
---------------------------------------------------------
-- Server version       3.23.58

--
-- Table structure for table `tutorials_tbl`
--

CREATE TABLE tutorials_tbl (
   tutorial_id int(11) NOT NULL auto_increment,
   tutorial_title varchar(100) NOT NULL default '',
   tutorial_author varchar(40) NOT NULL default '',
   submission_date date default NULL,
   PRIMARY KEY  (tutorial_id),
   UNIQUE KEY AUTHOR_INDEX (tutorial_author)
) TYPE = MyISAM;

--
-- Dumping data for table `tutorials_tbl`
--

INSERT INTO tutorials_tbl 
   VALUES (1,'Learn PHP','John Poul','2007-05-24');
INSERT INTO tutorials_tbl 
   VALUES (2,'Learn MySQL','Abdul S','2007-05-24');
INSERT INTO tutorials_tbl 
   VALUES (3,'JAVA Tutorial','Sanjay','2007-05-06');

要转储多个表,请在数据库名称参数后命名所有表。要转储整个数据库,请不要在数据库后命名任何表,如以下代码块所示。

$ mysqldump -u root -p TUTORIALS > database_dump.txt
password ******

要备份主机上所有可用的数据库,请使用以下代码。

$ mysqldump -u root -p --all-databases > database_dump.txt
password ******

MySQL 3.23.12版本中提供了--all-databases选项。此方法可用于实现数据库备份策略。

将表或数据库复制到另一个主机

如果要将表或数据库从一台MySQL服务器复制到另一台MySQL服务器,请使用带数据库名称和表名称的mysqldump

在源主机上运行以下命令。这会将完整的数据库转储到dump.txt文件中。

$ mysqldump -u root -p database_name table_name > dump.txt
password *****

您可以像上面解释的那样,在不使用特定表名称的情况下复制完整的数据库。

现在,将dump.txt文件ftp到另一台主机,并使用以下命令。在运行此命令之前,请确保您已在目标服务器上创建了database_name。

$ mysql -u root -p database_name < dump.txt
password *****

另一种无需使用中间文件即可实现此目的的方法是,将mysqldump的输出直接通过网络发送到远程MySQL服务器。如果您能够从源数据库所在的服务器主机连接到这两台服务器,请使用以下命令(确保您具有这两台服务器的访问权限)。

$ mysqldump -u root -p database_name \
   | mysql -h other-host.com database_name

在mysqldump中,命令的一半连接到本地服务器并将转储输出写入管道。命令的另一半连接到other-host.com上的远程MySQL服务器。它读取管道的输入并将每个语句发送到other-host.com服务器。

MySQL - 数据库导入 - 恢复方法

在MySQL中,有两种简单的方法可以将数据从先前备份的文件加载到MySQL数据库中。

使用LOAD DATA导入数据

MySQL提供了一个LOAD DATA语句,该语句充当批量数据加载器。这是一个示例语句,它从当前目录读取文件dump.txt并将其加载到当前数据库中的mytbl表中。

mysql> LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl;
  • 如果不存在LOCAL关键字,MySQL将使用查找绝对路径名在服务器主机上查找数据文件,该路径名完全指定文件的位置,从文件系统的根目录开始。MySQL从给定位置读取文件。

  • 默认情况下,LOAD DATA假设数据文件包含以换行符(换行符)结尾的行,并且一行中的数据值以制表符分隔。

  • 要显式指定文件格式,请使用FIELDS子句来描述一行中字段的特征,并使用LINES子句来指定行结束序列。以下LOAD DATA语句指定数据文件包含以冒号分隔的值,并且行以回车符和换行符结尾。

mysql> LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl
   -> FIELDS TERMINATED BY ':'
   -> LINES TERMINATED BY '\r\n';
  • LOAD DATA命令假设数据文件中的列顺序与表中的列顺序相同。如果并非如此,您可以指定一个列表来指示数据文件列应加载到哪些表列中。假设您的表具有列a、b和c,但数据文件中的后续列对应于列b、c和a。

您可以按以下代码块所示加载文件。

mysql> LOAD DATA LOCAL INFILE 'dump.txt' 
   -> INTO TABLE mytbl (b, c, a);

使用mysqlimport导入数据

MySQL还包含一个名为mysqlimport的实用程序,它充当LOAD DATA的包装器,因此您可以直接从命令行加载输入文件。

要将数据从dump.txt加载到mytbl,请在UNIX提示符下使用以下命令。

$ mysqlimport -u root -p --local database_name dump.txt
password *****

如果您使用mysqlimport,命令行选项将提供格式说明符。对应于前面两个LOAD DATA语句的mysqlimport命令如下所示。

$ mysqlimport -u root -p --local --fields-terminated-by = ":" \
   --lines-terminated-by = "\r\n"  database_name dump.txt
password *****

您指定选项的顺序对于mysqlimport并不重要,但它们都应该位于数据库名称之前。

mysqlimport语句使用--columns选项来指定列顺序:

$ mysqlimport -u root -p --local --columns=b,c,a \
   database_name dump.txt
password *****

处理引号和特殊字符

FIELDS子句可以指定除TERMINATED BY之外的其他格式选项。默认情况下,LOAD DATA假设值是不带引号的,并将反斜杠(\)解释为特殊字符的转义字符。要显式指示值引号字符,请使用ENCLOSED BY命令。MySQL将在输入处理过程中从数据值的末尾删除该字符。要更改默认转义字符,请使用ESCAPED BY

当您指定ENCLOSED BY 来指示应从数据值中删除引号字符时,可以通过将其加倍或在其前面加上转义字符来在数据值中包含引号字符。

例如,如果引号和转义字符为“和\,则输入值"a""b\"c"将被解释为a"b"c

对于mysqlimport,用于指定引号和转义值的相应命令行选项为--fields-enclosed-by--fields-escaped-by

广告