实用篇 | MySQL 学习笔记


MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS (Relational Database Management System:关系数据库管理系统) 应用软件之一。


文章目录

  • **实用篇 | MySQL 学习笔记**
    • **一、MySQL 启动 | 关闭 | 重启 服务操作命令**
      • ● **启动** MySQL 命令
      • ● **关闭** MySQL 命令
      • ● **重启** MySQL 命令
      • ● **设置** utf8 MySQL 命令
    • **二、MySQL 连接 | 退出 命令**
    • **三、MySQL 常用数据库命令操作**
      • **● CREATE DATABASE** 创建数据库
      • **● DROP DATABASE** 删除数据库
      • **● USE \** 选择数据库
      • **● MySQL** 查询当前数据库
      • **● CREATE TABLE** 创建数据表
      • **● DROP TABLE** 删除数据表
      • **● INSERT** 插入数据
      • **● SELECT** 查询语句
      • **● WHERE** 条件查询语句
      • **● BINARY** 关键字 区分大小写查询
      • **● UPDATE** 更新 / 修改字段值
      • **● DELETE** 删除数据语句
      • **● LIKE** 指定多个字符串查询语句
      • **● UNION** 操作符
      • **● MySQL** 排序
      • **● GROUP BY** 语句
      • ● **JOIN** 联合多表查询
      • **● NULL** 值处理
      • **● ALTER** 修改数据
      • 1、修改字段类型及名称
      • 2、ALTER TABLE 对 Null 值和默认值的影响
      • 3、ALTER \ SET DEFAULT 修改字段默认值
      • 4、RENAME TO 修改表名
      • **● MySQL** 索引
      • 1、普通索引
        • ● CREATE INDEX 创建索引
        • ● ADD INDEX 修改表结构 (添加索引)
        • ● 创建表的时候直接指定
        • ● DROP INDEX 删除索引的语法
      • 2、唯一索引
        • ● CREATE UNIQUE INDEX 创建索引
        • ● ADD UNIQUE 修改表结构
        • ● 创建表的时候直接指定
      • 3、使用 ALTER 命令添加和删除索引
      • 4、使用 ALTER 命令添加和删除主键
      • 5、显示索引信息
      • **● MySQL** 临时表
      • **● MySQL** 元数据
      • **● MySQL** 序列使用
      • 1、使用 AUTO_INCREMENT
      • 2、获取 AUTO_INCREMENT 值
      • 3、重置序列
      • 4、设置序列的开始值
      • **● MySQL** 处理重复数据
      • 1、防止表中出现重复数据
      • 2、统计重复数据
      • 3、过滤重复数据
      • 4、删除重复数据
      • **● MySQL** 导出数据
      • 1、使用 SELECT ... INTO OUTFILE 语句导出数据
      • 2、SELECT ... INTO OUTFILE 语句有以下属性:
      • 3、导出表作为原始数据
      • 4、导出 SQL 格式的数据
      • 5、将数据表及数据库拷贝至其他主机
      • **● MySQL** 导入数据
      • 1、mysql 命令导入
      • 2、source 命令导入
      • 3、使用 LOAD DATA 导入数据
      • 4、使用 mysqlimport 导入数据
      • 5、mysqlimport 的常用选项介绍
      • **● MySQL** 运算符
      • 1、算术运算符
      • 2、比较运算符
      • 3、逻辑运算符
      • 4、位运算符
      • 5、运算符优先级
    • **四、MySQL 数据类型**
      • 1、数值类型
      • 2、日期和时间类型
      • 3、字符串类型
    • **五、MySQL 正则表达式**
    • **六、MySQL 事务处理**
      • 1、事务控制语句
      • 2、MYSQL 事务处理主要有两种方法
    • **七、MySQL 函数**
      • 1、字符串函数
      • 2、数字函数
      • 3、日期函数
      • 4、高级函数
    • **八、FOREIGN KEY 外键约束**
      • 1、CREATE TABLE 时的 FOREIGN KEY 外键约束
      • 2、ALTER TABLE 时的 FOREIGN KEY 外键约束
      • 3、撤销 FOREIGN KEY 外键约束

一、MySQL 启动 | 关闭 | 重启 服务操作命令

启动 MySQL 命令
service mysqld start
关闭 MySQL 命令
service mysqld stop
重启 MySQL 命令
service mysqld restart
设置 utf8 MySQL 命令
set character_set_client=utf8;
set character_set_connection=utf8;
set character_set_database=utf8;
set character_set_results=utf8;
set character_set_server=utf8;

二、MySQL 连接 | 退出 命令

● 连接命令:

mysql -u root -p

● 输入密码:

Enter password:******

输出示例:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11 to server version: 5.0.9Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

● 退出命令:

mysql> exit
Bye

三、MySQL 常用数据库命令操作

● CREATE DATABASE 创建数据库
CREATE DATABASE RUNOOB;
● DROP DATABASE 删除数据库
DROP DATABASE RUNOOB;
● USE <DATABASE> 选择数据库
USE RUNOOB;
● MySQL 查询当前数据库
SELECT DATABASE();
● CREATE TABLE 创建数据表

以下例子中我们将在 RUNOOB 数据库中创建数据表 runoob_tbl

CREATE TABLE IF NOT EXISTS `runoob_tbl`(`runoob_id` INT UNSIGNED AUTO_INCREMENT,`runoob_title` VARCHAR(100) NOT NULL,`runoob_author` VARCHAR(40) NOT NULL,`submission_date` DATE,PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

实例解析:

  • 如果你不想字段为 NULL 可以设置字段的属性为 NOT NULL, 在操作数据库时如果输入该字段的数据为 NULL ,就会报错。
  • AUTO_INCREMENT 定义列为自增的属性,一般用于主键,数值会自动加 1
  • PRIMARY KEY 关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。
  • ENGINE 设置存储引擎,CHARSET 设置编码。
● DROP TABLE 删除数据表
DROP TABLE runoob_tbl;
● INSERT 插入数据
root@host# mysql -u root -p password;
Enter password:*******mysql> use RUNOOB;
Database changed
mysql> INSERT INTO runoob_tbl -> (runoob_title, runoob_author, submission_date)-> VALUES-> ("学习 PHP", "菜鸟教程", NOW());
Query OK, 1 rows affected, 1 warnings (0.01 sec)mysql> INSERT INTO runoob_tbl-> (runoob_title, runoob_author, submission_date)-> VALUES-> ("学习 MySQL", "菜鸟教程", NOW());
Query OK, 1 rows affected, 1 warnings (0.01 sec)mysql> INSERT INTO runoob_tbl-> (runoob_title, runoob_author, submission_date)-> VALUES-> ("JAVA 教程", "RUNOOB.COM", '2016-05-06');mysql> INSERT INTO runoob_tbl-> (runoob_title, runoob_author, submission_date)-> VALUES-> ("学习 Python", "RUNOOB.COM", '2016-03-06');
Query OK, 1 rows affected (0.00 sec)
mysql>
● SELECT 查询语句
mysql> SELECT * FROM `runoob_tbl`;
+-----------+--------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+--------------+---------------+-----------------+
|         1 | 学习 PHP     | 菜鸟教程        | 2022-07-22      |
|         2 | 学习 MySQL   | 菜鸟教程        | 2022-07-23      |
|         3 | 学习 C++     | RUNOOB.COM     | 2016-05-06      |
|         4 | 学习 Python  | RUNOOB.COM     | 2016-03-06      |
+-----------+--------------+---------------+-----------------+
3 rows in set (0.03 sec)
● WHERE 条件查询语句
SELECT * FROM runoob_tbl WHERE runoob_author='菜鸟教程';
● BINARY 关键字 区分大小写查询

使用 BINARY 关键字区分大小写,所以 runoob_author=‘runoob.com’ 的查询条件是没有数据的。

mysql> SELECT * from runoob_tbl WHERE BINARY runoob_author='runoob.com';
Empty set (0.01 sec)mysql> SELECT * from runoob_tbl WHERE BINARY runoob_author='RUNOOB.COM';
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3         | JAVA 教程      | RUNOOB.COM    | 2016-05-06      |
| 4         | 学习 Python    | RUNOOB.COM    | 2016-03-06      |
+-----------+---------------+---------------+-----------------+
2 rows in set (0.01 sec)
● UPDATE 更新 / 修改字段值

以下实例将更新数据表中 runoob_id3runoob_title 字段值:

mysql> UPDATE runoob_tbl SET runoob_title='学习 C++' WHERE runoob_id=3;
Query OK, 1 rows affected (0.01 sec)mysql> SELECT * from runoob_tbl WHERE runoob_id=3;
+-----------+--------------+---------------+-----------------+
| runoob_id | runoob_title | runoob_author | submission_date |
+-----------+--------------+---------------+-----------------+
| 3         | 学习 C++      | RUNOOB.COM    | 2016-05-06      |
+-----------+--------------+---------------+-----------------+
1 rows in set (0.01 sec)
● DELETE 删除数据语句

以下实例将删除 runoob_tbl 表中 runoob_id3 的记录:

mysql> use RUNOOB;
Database changed
mysql> DELETE FROM runoob_tbl WHERE runoob_id=3;
Query OK, 1 row affected (0.23 sec)
● LIKE 指定多个字符串查询语句

以下是我们将 runoob_tbl 表中获取 runoob_author 字段中以 COM 为结尾的的所有记录:(%代表任意多个字符)

mysql> use RUNOOB;
Database changed
mysql> SELECT * from runoob_tbl WHERE runoob_author LIKE '%COM';
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 4         | 学习 Python    | RUNOOB.COM    | 2016-03-06      |
+-----------+---------------+---------------+-----------------+
2 rows in set (0.01 sec)
● UNION 操作符

描述:MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。

语法格式:MySQL UNION 操作符

SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];

参数

  • expression1, expression2, … expression_n: 要检索的列。
  • tables: 要检索的数据表。
  • WHERE conditions: 可选, 检索条件。
  • DISTINCT: 可选,删除结果集中重复的数据。默认情况下 UNION 操作符已经删除了重复数据,所以 DISTINCT 修饰符对结果没啥影响。
  • ALL: 可选,返回所有结果集,包含重复数据。

下面是选自 “Websites” 表的数据:

mysql> SELECT * FROM Websites;
+----+--------------+---------------------------+-------+---------+
| id | name         | url                       | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1  | Google       | https://www.google.cm/    | 1     | USA     |
| 2  | 淘宝          | https://www.taobao.com/   | 13    | CN      |
| 3  | 菜鸟教程      | http://www.runoob.com/    | 4689  | CN      |
| 4  | 微博          | http://weibo.com/         | 20    | CN      |
| 5  | Facebook     | https://www.facebook.com/ | 3     | USA     |
| 7  | stackoverflow | http://stackoverflow.com/ |   0 | IND     |
+----+---------------+---------------------------+-------+---------+

下面是 “apps” APP 的数据:

mysql> SELECT * FROM apps;
+----+------------+-------------------------+---------+
| id | app_name   | url                     | country |
+----+------------+-------------------------+---------+
|  1 | QQ APP     | http://im.qq.com/       | CN      |
|  2 | 微博 APP | http://weibo.com/       | CN      |
|  3 | 淘宝 APP | https://www.taobao.com/ | CN      |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)

下面的 SQL 语句从 “Websites”“apps” 表中选取所有 不同的 country(无重复值):

SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;

执行以上 SQL 输出结果如下:

注释:UNION 不能用于列出两个表中所有的 country。如果一些网站和 APP 来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!


SQL UNION ALL 实例

下面的 SQL 语句使用 UNION ALL 从 “Websites” 和 “apps” 表中选取 所有的 country(也有重复的值):

SELECT country FROM Websites
UNION ALL
SELECT country FROM apps
ORDER BY country;

执行以上 SQL 输出结果如下:


带有 WHERE 的 SQL UNION ALL

下面的 SQL 语句使用 UNION ALL“Websites” 和 “apps” 表中选取 所有的 中国 (CN) 的数据(也有重复的值):

SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;

执行以上 SQL 输出结果如下:

● MySQL 排序

读取 runoob_tbl 表中所有数据并按 submission_date 字段的 ASC 升序 | DESC 降序 排列:

mysql> use RUNOOB;
Database changed
mysql> SELECT * from runoob_tbl ORDER BY submission_date ASC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3         | 学习 Java      | RUNOOB.COM    | 2015-05-01      |
| 4         | 学习 Python    | RUNOOB.COM    | 2016-03-06      |
| 1         | 学习 PHP       | 菜鸟教程       | 2017-04-12      |
| 2         | 学习 MySQL     | 菜鸟教程       | 2017-04-12      |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)mysql> SELECT * from runoob_tbl ORDER BY submission_date DESC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1         | 学习 PHP       | 菜鸟教程       | 2017-04-12      |
| 2         | 学习 MySQL     | 菜鸟教程       | 2017-04-12      |
| 4         | 学习 Python    | RUNOOB.COM    | 2016-03-06      |
| 3         | 学习 Java      | RUNOOB.COM    | 2015-05-01      |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)
● GROUP BY 语句

本章节实例使用到了以下表结构及数据,使用前我们可以先将以下数据导入数据库中:

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;-- -------------------------------------
--  Table structure for `employee_tbl`
-- -------------------------------------
DROP TABLE IF EXISTS `employee_tbl`;
CREATE TABLE `employee_tbl` (`id` int(11) NOT NULL,`name` char(10) NOT NULL DEFAULT '',`date` datetime NOT NULL,`signin` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登录次数',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- -------------------------------------
--  Records of `employee_tbl`
-- -------------------------------------
BEGIN;
INSERT INTO `employee_tbl` VALUES ('1', '小明', '2016-04-22 15:25:33', '1'), ('2', '小王', '2016-04-20 15:25:47', '3'), ('3', '小丽', '2016-04-19 15:26:02', '2'), ('4', '小王', '2016-04-07 15:26:14', '4'), ('5', '小明', '2016-04-11 15:26:40', '4'), ('6', '小明', '2016-04-04 15:26:54', '2');
COMMIT;SET FOREIGN_KEY_CHECKS = 1;

导入成功后,执行以下 SQL 语句:

mysql> set names utf8;
mysql> SELECT * FROM employee_tbl;
+----+--------+---------------------+--------+
| id | name   | date                | signin |
+----+--------+---------------------+--------+
|  1 | 小明   | 2016-04-22 15:25:33 |      1 |
|  2 | 小王   | 2016-04-20 15:25:47 |      3 |
|  3 | 小丽   | 2016-04-19 15:26:02 |      2 |
|  4 | 小王   | 2016-04-07 15:26:14 |      4 |
|  5 | 小明   | 2016-04-11 15:26:40 |      4 |
|  6 | 小明   | 2016-04-04 15:26:54 |      2 |
+----+--------+---------------------+--------+
6 rows in set (0.00 sec)

接下来我们使用 GROUP BY 语句 将数据表按名字进行分组,并统计每个人有多少条记录:

mysql> SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
+--------+----------+
| name   | COUNT(*) |
+--------+----------+
| 小丽  |        1 |
| 小明  |        3 |
| 小王  |        2 |
+--------+----------+
3 rows in set (0.01 sec)

使用 WITH ROLLUP 可以实现在分组统计数据基础上再进行相同类型总的统计**(SUM,AVG,COUNT…)**。

例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数:

mysql> SELECT name, SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name   | signin_count |
+--------+--------------+
| 小丽  |            2 |
| 小明  |            7 |
| 小王  |            7 |
| NULL   |           16 |
+--------+--------------+
4 rows in set (0.00 sec)

其中记录 NULL 表示所有人的登录次数。

我们可以使用 coalesce 来设置一个可以取代 **NULL **的名称,coalesce 语法:

select coalesce(a,b,c);

参数说明:如果 a==null 则选择 b;如果 b==null 则选择 c;如果 a!=null 则选择 **a;**如果 a b c 都为 null 则返回为 null(没意义)。

以下实例中如果名字为空我们使用总数代替:

mysql> SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '总数')    | signin_count |
+--------------------------+--------------+
| 小丽                      |            2 |
| 小明                      |            7 |
| 小王                      |            7 |
| 总数                      |           16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)
JOIN 联合多表查询

在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。

本章节我们将向大家介绍如何使用 MySQLJOIN 在两个或多个表中查询数据。

你可以在 SELECT, UPDATEDELETE 语句中使用 MySQLJOIN 来联合多表查询。

JOIN 按照功能大致分为如下三类:

  • INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
  • **LEFT JOIN(左连接):**获取左表所有记录,即使右表没有对应匹配的记录。
  • RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。

在命令提示符中使用 INNER JOIN

我们在 RUNOOB 数据库中有两张表 tcount_tblrunoob_tbl。两张数据表数据如下:

测试实例数据

mysql> use RUNOOB;
Database changed
mysql> SELECT * FROM tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鸟教程     | 10           |
| RUNOOB.COM    | 20           |
| Google        | 22           |
+---------------+--------------+
3 rows in set (0.01 sec)mysql> SELECT * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1         | 学习 PHP    | 菜鸟教程      | 2017-04-12      |
| 2         | 学习 MySQL  | 菜鸟教程      | 2017-04-12      |
| 3         | 学习 Java   | RUNOOB.COM       | 2015-05-01      |
| 4         | 学习 Python | RUNOOB.COM       | 2016-03-06      |
| 5         | 学习 C      | FK               | 2017-04-05      |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.01 sec)

接下来我们就使用 MySQLINNER JOIN (也可以省略 INNER 使用 JOIN,效果一样) 来连接以上两张表来读取 runoob_tbl 表中所有 runoob_author 字段在 tcount_tbl 表对应的 runoob_count 字段值:

INNER JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程       | 10             |
| 2           | 菜鸟教程       | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
+-------------+-----------------+----------------+
4 rows in set (0.00 sec)

以上 SQL 语句等价于 => INNER JOINON == ,WHERE

WHERE 子句

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a, tcount_tbl b WHERE a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程       | 10             |
| 2           | 菜鸟教程       | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
+-------------+-----------------+----------------+
4 rows in set (0.01 sec)


LEFT JOIN 左表连接

MySQL left joinjoin 有所不同。MySQL LEFT JOIN 会读取左边数据表的全部数据,即使右边表无对应数据。

尝试以下实例,以 runoob_tbl 为左表,tcount_tbl 为右表,理解 MySQL LEFT JOIN 的应用:

LEFT JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程       | 10             |
| 2           | 菜鸟教程       | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| 5           | FK              | NULL           |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

以上实例中使用了 LEFT JOIN,该语句会读取左边的数据表 runoob_tbl 的所有选取的字段数据,即使在右侧表 tcount_tbl 中 没有对应的 runoob_author 字段值。


RIGHT JOIN 右表连接

MySQL RIGHT JOIN 会读取右边数据表的全部数据,即使左边边表无对应数据。

尝试以下实例,以 runoob_tbl 为左表,tcount_tbl 为右表,理解 MySQL RIGHT JOIN 的应用:

RIGHT JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程       | 10             |
| 2           | 菜鸟教程       | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| NULL        | NULL            | 22             |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

以上实例中使用了 MySQL ,该语句会读取右边的数据表 MySQL 的所有选取的字段数据,即使在左侧表 MySQL 中没有对应的 MySQL 字段值。

● NULL 值处理

创建数据表 runoob_test_tbl

root@host# mysql -u root -p password;
Enter password:*******
mysql> use RUNOOB;
Database changed
mysql> create table runoob_test_tbl-> (-> runoob_author varchar(40) NOT NULL,-> runoob_count  INT-> );
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('RUNOOB', 20);
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('菜鸟教程', NULL);
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('Google', NULL);
mysql> INSERT INTO runoob_test_tbl (runoob_author, runoob_count) values ('FK', 20);mysql> SELECT * from runoob_test_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB        | 20           |
| 菜鸟教程     | NULL         |
| Google        | NULL         |
| FK            | 20           |
+---------------+--------------+
4 rows in set (0.01 sec)

以下实例中你可以看到 =!= 运算符是不起作用的:

mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count = NULL;
Empty set (0.00 sec)
mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count != NULL;
Empty set (0.01 sec)

查找数据表中 runoob_test_tbl 列是否为 NULL,必须使用 IS NULLIS NOT NULL,如下实例:

mysql> SELECT * FROM runoob_test_tbl WHERE runoob_count IS NULL;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鸟教程     | NULL         |
| Google        | NULL         |
+---------------+--------------+
2 rows in set (0.01 sec)mysql> SELECT * from runoob_test_tbl WHERE runoob_count IS NOT NULL;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| RUNOOB        | 20           |
| FK            | 20           |
+---------------+--------------+
2 rows in set (0.01 sec)
● ALTER 修改数据

创建数据表 testalter_tbl

root@host# mysql -u root -p password;
Enter password:*******
mysql> use RUNOOB;
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)

如下命令使用了 ALTER 命令及 DROP 子句来删除以上创建表的 i 字段:

mysql> ALTER TABLE testalter_tbl  DROP i;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

如果数据表中只剩余一个字段则无法使用 DROP 来删除字段。

MySQL 中使用 ADD 子句来向数据表中添加列,如下实例在表 testalter_tbl 中添加 i 字段,并定义数据类型:

mysql> ALTER TABLE testalter_tbl ADD i INT;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

执行以上命令后,i 字段会自动添加到数据表字段的末尾。

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)

如果你需要指定新增字段的位置,可以使用 MySQL 提供的关键字 FIRST (设定位第一列), AFTER 字段名(设定位于某个字段之后)。

尝试以下 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;

FIRSTAFTER 关键字可用于 ADDMODIFY 子句,所以如果你想重置数据表字段的位置就需要先使用 DROP 删除字段然后使用 ADD 来添加字段并设置位置。

1、修改字段类型及名称

如果需要修改字段类型及名称, 你可以在ALTER命令中使用 MODIFY 或 CHANGE 子句 。

例如,把字段 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;
mysql> ALTER TABLE testalter_tbl CHANGE j j INT;
2、ALTER TABLE 对 Null 值和默认值的影响

当你修改字段时,你可以指定是否包含值或者是否设置默认值。

以下实例,指定字段 jNOT NULL 且默认值为 100

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

如果你不设置默认值,MySQL会自动设置该字段默认为 NULL

3、ALTER <column_name> SET DEFAULT 修改字段默认值

你可以使用 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)

你也可以使用 ALTER 命令及 DROP子句来删除字段的默认值,如下实例:

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)
Changing a Table Type:

修改数据表类型,可以使用 ALTER 命令及 TYPE 子句来完成。尝试以下实例,我们将表 testalter_tbl 的类型修改为 MYISAM

**注意:**查看数据表类型可以使用 SHOW TABLE STATUS 语句。

mysql> ALTER TABLE testalter_tbl ENGINE = MYISAM;
mysql> SHOW TABLE STATUS LIKE 'testalter_tbl';
*************************** 1. row ****************Name: testalter_tblType: MyISAMRow_format: FixedRows: 0Avg_row_length: 0Data_length: 0
Max_data_length: 25769803775Index_length: 1024Data_free: 0Auto_increment: NULLCreate_time: 2007-06-03 08:04:36Update_time: 2007-06-03 08:04:36Check_time: NULLCreate_options:Comment:
1 row in set (0.00 sec)
4、RENAME TO 修改表名

如果需要修改数据表的名称,可以在 ALTER TABLE 语句中使用 RENAME 子句来实现。

尝试以下实例将数据表 testalter_tbl 重命名为 alter_tbl

mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;
● MySQL 索引
1、普通索引
● CREATE INDEX 创建索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:

CREATE INDEX indexName ON table_name (column_name)

如果是 CHAR,VARCHAR 类型,length 可以小于字段实际长度;如果是 BLOBTEXT 类型,必须指定 length

● ADD INDEX 修改表结构 (添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
● 创建表的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);
● DROP INDEX 删除索引的语法
DROP INDEX [indexName] ON mytable;

2、唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

● CREATE UNIQUE INDEX 创建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
● ADD UNIQUE 修改表结构
ALTER table mytable ADD UNIQUE [indexName] (username(length))
● 创建表的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);

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

有四种方式来添加数据表的索引: