主要跟菜鸟MYSQL来整理的,用于学习笔记。
一、数据库的基本概念
MySql是关系型数据库。
1) 术语
- 数据库:数据库是一些关联表的集合。
- 数据表:表是数据的矩阵。在一个数据库中的表类似一个Excel文件。与数据库的关系是,数据库中包含数据表。
- 列:一列数据元素包含了相同类型的数据。
- 行:或者称为一个记录,是一组相关的数据,一个记录。
- 冗余:存储两倍数据,冗余降低了性能,提高了数据的安全性。
- 主键:主键是唯一的(就是每个记录中的主键都不可能重复),一个数据表中只能包含一个主键,你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,类似书的目录。
- 参照完整性:参照的完整性要求关系中不允许引用不存在的实体,与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
- 表头(header):每一列的名称
- 列(col):具有相同数据类型的数据的集合
- 行(row):每一行用来描述某条记录的具体信息
- 值(val):行的具体信息,每个值必须与该列的数据类型相同(或者可以转换)
- 键(key):键的值在当前列中具有唯一性
二、MySQL管理
1)启动MySQL服务器
windows环境:
首先以管理员身份运行命令提示符,然后键入
net start 数据库名称
2)关闭MySQL服务器
net stop 数据库名称
3)MySQL用户设置
如果需要添加MySQL用户,只需要在mysql数据库中的user表添加新用户即可。
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', 'david',
PASSWORD('123456'), 'Y', 'Y', 'Y');
Query OK, 1 row affected (0.20 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 1 row affected (0.01 sec)
在添加用户时,用MySQL提供的PASSWORD()
函数来对密码进行加密。
password()加密函数在8.0.11中移除,使用MD5()函数代替。
注意要执行FLUSH PRIVILEGES
语句,这个命令执行后会重新载入授权表。
4)管理MySQL命令
-
选择要操作的数据库
语法
mysql> use 数据库l;
例子
mysql> use books; Database changed
-
列出MySQL数据库管理系统的数据库列表
语法
mysql> SHOW DATABASES;
例子
mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | books | | house_price_hz | | information_schema | | myemployees | | mysql | | performance_schema | | students | | sys | | test | +--------------------+ 9 rows in set (0.00 sec)
-
现实指定数据库所有的表
语法
mysql> SHOW TABLES;
例子
mysql> USE books; Database changed mysql> SHOW TABLES; +-----------------+ | Tables_in_books | +-----------------+ | author | | copy | | copy2 | | copy3 | | copy4 | +-----------------+ 5 rows in set (0.00 sec)
-
显示数据表的属性,属性类型,主键信息,是否为NULL,默认值等其他信息
语法
mysql> SHOW COLUMNS FROM 数据表;
例子
mysql> SHOW COLUMNS FROM author;
-
显示数据表的详细索引信息,包括PRIMARY KEY(主键)
mysql> SHOW INDEX FROM 数据表;
-
输出MySQL数据库管理系统的性能及统计信息
语法
SHOW TABLE STATUS LIKE [FROM db_name] [LIKE 'pattern'] \G:
例子
mysql> SHOW TABLE STATUS FROM books; # 显示数据库 books 中所有表的信息 mysql> SHOW TABLE STATUS from books LIKE 'auth%'; # 表名以auth开头的表的信息 mysql> SHOW TABLE STATUS from books LIKE 'auth%'\G; # 加上 \G,查询结果按列打印
三、MySQL连接
使用MySQL二进制方式连接
语法
登入:
[root@host]# mysql -u root -p
Enter password: ******
退出:
mysql> exit
Bye
四、MySQL创建数据库
语法
CREATE DATABASE 数据库名;
例子
mysql> CREATE DATABASE HK_U;
五、MySQL删除数据库
语法
DROP DATABASE <数据库名>;
例子
mysql> DROP DATABASE HK_U;
六、MySQL数据类型
MySQL中定义数据字段的类型对数据库的优化是非常重要的。
MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。
数值类型
MySQL支持所有标准的SQL数字类型。
这些类型包括严格数值数据类型(INTEGR,SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE RRECISION)。
关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。
BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。
作为SQL标准的拓展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
TINYINT | 1 byte | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 bytes | (-32 768,32 767) | (0,65 535) | 大整数值 |
MEDIUMINT | 3 bytes | (-8 388 608,8 388 607) | (0,16 777 215) | 大整数值 |
INT或INTEGER | 4 bytes | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
BIGINT | 8 bytes | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 极大整数值 |
FLOAT | 4 bytes | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
DOUBLE | 8 bytes | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |
日期和时间类型
表示时间值的日期和时间类型位DATETIME、DATA、TIMESTAMP、TIME和YEAR。
每个时间类型有一个有效值范围和一个“零”值,当指定不合法的MySQL不能表示的值时使用“零”值。
TIMESTAMP类型有专有的自动更新特征。
类型 | 大小 ( bytes) | 范围 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
字符串类型
字符串类型值CHAR,VARCHAR,BINARY,VARBINARY、BLOB、TEXT、ENUM和SET。
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 |
TINYBLOB | 0-255 bytes | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255 bytes | 短文本字符串 |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 |
TEXT | 0-65 535 bytes | 长文本数据 |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
注意:
char(n)和varchar(n)中括号n代表字符的个数,并不代表字节的个数,比如CHAR(30)就是指可以存储30个字符。CHAR和VARCHAR类型类似,但是它们保存和检索的方式不同,它们的最大长度和是否尾部空格被保留等方面也不同,在存储或检索过程中不进行大小写转换。
BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。
BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。
有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。
七、MySQL创建数据表
创建MySQL数据表需要以下三个要素;
- 表名
- 表字段名
- 定义每个表字段
语法
CREATE TABLE table_name (column_name column_type);
例子
CREATE TABLE IF NOT EXISTS `CityU` (
`id` INT UNSIGNED AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`loc` VARCHAR(50) NOT NULL,
`data` DATE,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
解析:
- 如果你不想字段位NULL,可以设置字段的属性为NOT NULL,在操作数据库时如果输入该字段的数据为NULL,就会报错。
- AUTO_INCREMENT 定义列为自增的属性,一般用于主键,数值会自动增加1.
- PRIMARY KEY关键字用于定义列为主键,可以使用多列来定义主键,列间以逗号分割,多列为主键时,只要它们的组合在这个表中是唯一的就ok了。
- **ENGINE ** 设置存储引擎,CHARSET 设置编码。
通过命令提示符创建表
CREATE TABLE IF NOT EXISTS CityU (
id INT UNSIGNED AUTO_INCREMENT,
title VARCHAR(100) NOT NULL,
loc VARCHAR(50) NOT NULL,
data DATE,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
注意:
区分""
和NULL
:
- 空值
""
是不占用空间的 - MySQL中的
NULL
其实是占用空间的,所谓NULL
就是什么都没有,但是在物理内存中是占有空间的
mysql> select length(NULL), length(''), length('1');
+--------------+------------+-------------+
| length(NULL) | length('') | length('1') |
+--------------+------------+-------------+
| NULL | 0 | 1 |
+--------------+------------+-------------+
1 row in set (0.00 sec)
所以从上面可以看出空值的长度为1,是不占用空间的,而的NULL长度是NULL,其实它是占用空间的,NULL列需要行中的额外空间来记录它们的值是否为NULL。
-
如果要单纯查NULL值列,则使用
is NULL
去查,单纯去查空值(’’)列,则使用=''
。建议查询方式:NULL值查询使用is null/is not null查询,而空值(’’)可以使用=或者!=、<、>等算术运算符。
-
使用 COUNT(字段) 统计会过滤掉 NULL 值,但是不会过滤掉空值。
说明:IFNULL有两个参数。 如果第一个参数字段不是
NULL
,则返回第一个字段的值。 否则,IFNULL
函数返回第二个参数的值(默认值)。
八、MySQL删除数据表
语法
DROP TABLE table_name;
在命令提示窗口中删除数据表
mysql> use my_hk;
Database changed
mysql> drop table CityU;
Query OK, 0 rows affected (0.05 sec)
九、MySQL插入数据
语法
(1)指定列名,然后对应数值插入
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value1, value2,...valueN );
(2)不指定列名,这样就要插入一个完整的数据
INSERT INTO table_name VALUES
( value1, value2,...valueN );
(3)插入多条语句
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value11, value12,...value1N ),
( value21, value22,...value2N ),
...
( valueX1, valueX2,...valueXN )
如果数据是字符串型,必须使用单引号或者双引号,如:“values”。
例子
mysql> use my_hk;
Database changed
mysql> create table CityU(
-> id int not null auto_increment,
-> major varchar(20) not null,
-> loc varchar(30) not null,
-> primary key(id))ENGINE=INNODB DEFAULT CHARSET=UTF8;
Query OK, 0 rows affected, 1 warning (0.03 sec)
mysql> insert into CityU (major, loc) values('math', 'HK');
Query OK, 1 row affected (0.01 sec)
mysql> select * from CityU;
+----+-------+-----+
| id | major | loc |
+----+-------+-----+
| 1 | math | HK |
+----+-------+-----+
1 row in set (0.00 sec)
mysql> insert into CityU values (2, 'Data Science', 'HK');
Query OK, 1 row affected (0.01 sec)
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
+----+--------------+-----+
2 rows in set (0.00 sec)
mysql> insert into CityU (major, loc) values ('English', 'SZ'), ('CS', 'SZ');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
+----+--------------+-----+
4 rows in set (0.00 sec)
mysql> insert into CityU values (5, 'English', 'GZ'), (6, 'EE', 'GZ');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
+----+--------------+-----+
6 rows in set (0.00 sec)
十、MySQL查询数据
语法
select column_name_1,column_name_2, .., column_name_n
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
- 查询语句中,可以使用一个或多个表,表之间使用逗号(,)分割,并使用
WHERE
语句来设定查询条件; SELECT
命令可以读取一条或多条记录;- 可以使用星号(*)来代替其它字段,
SELECT
语句会返回所有字段数据; - 可以使用
WHERE
来包含任何条件; - 使用
LIMIT
属性来设定返回的记录数; - 通过
OFFSET
来指定SELECT
语句开始查询的数据偏移量,more情况下偏移量为0;
例子
- 显示所有信息
-- 查看所有房价
mysql> select * from price;
- 带有
where
子语句
-- 查看上城区的房价
mysql> select * from price where district = '上城';
-
带有
LIMIT
子语句注意的是
OFFSET
指的是偏移量,就是从第几行开始取,而LIMIT
表示的是取多少行,注意!!!OFFSET
的起始是从0(零)开始计算的~~看下面这两个例子就可以明白
十一、MySQL WHERE 子句
如需有条件地从表中选取数据,可将WHERE
子句添加到SELECT
语句中。
语法
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
- 查询语句中可以使用一个或多个表,表之间用逗号
,
分割,并使用WHERE
来设定查询条件; - 可以在
WHERE
子句中指定任何条件; - 可以使用
AND
或者OR
指定一个或多个条件; WHERE
子句也可以运行于SQL
和’DELETE’或者’UPDATE’命令;WHERE
子句类似程序语言中的if
条件,根据MySQL
表中的字段值来读取指定的数据;
常用的操作符:
操作符 | 描述 | 实例 |
---|---|---|
= | 等号,检测两个值是否相等,如果相等返回true | (A = B) 返回false。 |
<>, != | 不等于,检测两个值是否相等,如果不相等返回true | (A != B) 返回 true。 |
> | 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true | (A > B) 返回false。 |
< | 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true | (A < B) 返回 true。 |
>= | 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true | (A >= B) 返回false。 |
<= | 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true | (A <= B) 返回 tru |
例子:
- SQL SELECT WHERE 子句
mysql> select * from price where district = '西湖';
-
BINARY 关键字
MySQL的
WHERE
子句的字符串是不区分大小写的,可以使用BINARY
关键字来设定WHERE
子句的字符串是区分大小写的。
mysql> select * from price where BINARY web = 'www.hao123.com'
注意:
- where:数据库中常用的
WHERE
关键字,用于在初始表中筛选,它是一个约束声明,用来约束数据,在返回结果集之前起作用。 - having: 用于对
where
和group by
查询出来的分组进行过滤,查出满足条件的分组,它是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作。
十二、MySQL UPDATE更新
如果需要修改或者更新MySQL中的数据,可以使用SQL UPDATE命令来操作。
语法
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
- 可以同时更新一个或多个字段;
- 可以在
WHERE
子句中指定任何条件; - 可以在一个单独表中同时更新数据
- 当我们要更新字段中的特定字符时,可以使用如下语句
UPDATE table_name SET field=REPLACE(field, 'old-string', 'new-string') [WHERE Clause]
例子
mysql> use my_hk;
Database changed
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
+----+--------------+-----+
6 rows in set (0.00 sec)
mysql> update CityU set major = 'math|data science' where id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
+----+-------------------+-----+
6 rows in set (0.00 sec)
mysql> insert into CityU values (7, 'EE', 'HZ'), (8, 'EE', 'HK');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
| 7 | EE | HZ |
| 8 | EE | HK |
+----+-------------------+-----+
8 rows in set (0.00 sec)
mysql> update CityU set major = REPLACE(major, 'EE', 'EE + CS');
Query OK, 3 rows affected (0.01 sec)
Rows matched: 8 Changed: 3 Warnings: 0
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
| 8 | EE + CS | HK |
+----+-------------------+-----+
8 rows in set (0.00 sec)
十三、MySQL DELETE语句
可以使用SQL的DELETE FROM
命令来删除MySQL
数据表中的记录。
语法
DELETE FROM table_name [WHERE Clause]
- 如果没有指定
WHERE
子句,MySQL表中的所有记录将被删除; - 可以在
WHERE
子句中指定任何条件; - 可以在单个表中一次性删除记录;
例子
mysql> delete from CityU where id = 8;
Query OK, 1 row affected (0.01 sec)
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
+----+-------------------+-----+
7 rows in set (0.00 sec)
注意:
``
delete
, drop
, truncate
都有删除表的作用,区别在于;
- 1.
delete
和truncate
仅仅删除表数据,drop
是连表数据和结构一起删除,打个比方,delete
是单杀,truncate
是团灭,drop
是直接把电脑摔了。 - 2、
delete
是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate
和drop
是 DDL 语句,操作完马上生效,不能回滚,打个比方,delete
是发微信说分手,后悔还可以撤回,truncate
和drop
是直接扇耳光说滚,不能反悔。 - 3、执行的速度上,
drop>truncate>delete
,打个比方,drop
是神舟火箭,truncate
是和谐号动车,delete
是自行车。
truncate
语法:
TRUNCATE TABLE table_name;
十四、MySQL LIKE子句
WHERE
子句中可以使用等号=
来设定获取数据的条件,如 “runoob_author = ‘RUNOOB.COM’”。
但是有时候我们需要获取 runoob_author 字段含有 “COM” 字符的所有记录,这时我们就需要在WHERE
子句中使用 SQL LIKE 子句。
SQL LIKE 子句中使用百分号 %
字符来表示任意字符,类似于UNIX或正则表达式中的星号 *
。如果没有使用百分号 %
, LIKE
子句与等号 =
的效果是一样的。
语法
SELECT field1, field2,...fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
- 可以在
WHERE
子句中指定任何条件; - 可以在
WHERE
子句中使用LIKE
子句; - 可以使用
LIKE
子句替换=
; LIKE
通常与%
一同使用,类似于一个元字符的搜索;- 可以使用
AND
或者OR
指定一个或多个条件; - 可以在
DELETE
或UPDATE
命令中使用WHERE...LIKE
子句来指定条件。
LIKE
匹配/模糊匹配,会与 %
和 _
结合使用。
'%a' //以a结尾的数据
'a%' //以a开头的数据
'%a%' //含有a的数据
'_a_' //三位且中间字母是a的
'_a' //两位且结尾字母是a的
'a_' //两位且开头字母是a的
- %:表示任意 0 个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
- _:表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句。
- []:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
- [^] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
- 查询内容包含通配符时,由于通配符的缘故,导致我们查询特殊字符 “%”、“_”、“[” 的语句无法正常实现,而把特殊字符用 “[ ]” 括起便可正常查询。
例子
mysql> select * from CityU where major like 'E%';
+----+---------+-----+
| id | major | loc |
+----+---------+-----+
| 3 | English | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
+----+---------+-----+
4 rows in set (0.00 sec)
十五、MySQL UNION 操作符
MySQL UNION
操作符用于连接两个以上的SELECT
语句的结果组合到一个结果集合中,多个SELECT
语句会删除重复的数据。
语法
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: 可选,返回所有结果集,包含重复数据。
例子
SQL UNION实例
mysql> select major from CityU union select major from CityU;
+-------------------+
| major |
+-------------------+
| math|data science |
| Data Science |
| English |
| CS |
| EE + CS |
+-------------------+
5 rows in set (0.00 sec)
SQL UNION ALL实例
mysql> select major from CityU union all select major from CityU;
+-------------------+
| major |
+-------------------+
| math|data science |
| Data Science |
| English |
| CS |
| English |
| EE + CS |
| EE + CS |
| math|data science |
| Data Science |
| English |
| CS |
| English |
| EE + CS |
| EE + CS |
+-------------------+
14 rows in set (0.00 sec)
带有WHERE的SQL UNION ALL
mysql> select major from CityU where id = 2 union all select major from CityU where id <> 6 order by major;
+-------------------+
| major |
+-------------------+
| CS |
| Data Science |
| Data Science |
| EE + CS |
| English |
| English |
| math|data science |
+-------------------+
7 rows in set (0.00 sec)
十六、MySQL 排序
如果需要对读取的数据进行排序,就是使用MySQL的ORDER BY
子句来设定你想按哪个字段哪种方式进行排序,然后再返回结果。
语法
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][默认 ASC]], [field2...] [ASC [DESC][默认 ASC]]
- 可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
- 可以设定多个字段来排序。
- 可以使用
ASC
或DESC
关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。 - 可以添加
WHERE...LIKE
子句来设置条件。
例子
mysql> select * from CityU order by major desc;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 3 | English | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
| 2 | Data Science | HK |
| 4 | CS | SZ |
+----+-------------------+-----+
7 rows in set (0.00 sec)
mysql> select * from CityU order by major;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 4 | CS | SZ |
| 2 | Data Science | HK |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
| 3 | English | SZ |
| 5 | English | GZ |
| 1 | math|data science | HK |
+----+-------------------+-----+
7 rows in set (0.00 sec)
注意:MySQL 排序我们知道从 MySQL 表中使用 SQL SELECT 语句来读取:MySQL 拼音排序
如果字符集采用的是 gbk
(汉字编码字符集),直接在查询语句后边添加 ORDER BY
:
SELECT *
FROM runoob_tbl
ORDER BY runoob_title;
如果字符集采用的是 utf8
(万国码),需要先对字段进行转码然后排序:
SELECT *
FROM runoob_tbl
ORDER BY CONVERT(runoob_title using gbk);
十七、MySQL GROUP BY语句
GROUP BY
语句根据一个列或者多个列对结果进行分组。
在分组的列上,我们可以使用COUNT
, SUM
, AVG
等函数。
语法
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
例子
- 创建一个数据表
CREATE TABLE `employee_tbl` (
`id` int(11) NOT NULL,
`name` char(10) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`singin` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登录次数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of `employee_tbl`
-- ----------------------------
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');
2)查看表
SELECT * FROM employee_tb1;
3)分组操作
SELECT name, COUNT(*) FROM employee_tb1 GROUP BY name;
使用 WITH ROLLUP
WITH ROLLUP
可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。
SELECT name, SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name | singin_count |
+--------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| NULL | 16 |
+--------+--------------+
4 rows in set (0.00 sec)
其中记录 NULL 表示所有人的登录次数。
我们可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法:
select coalesce(a,b,c);
参数说明:如果anull,则选择b;如果bnull,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null(没意义)
mysql> SELECT coalesce(name, '总数'), SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '总数') | singin_count |
+--------------------------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| 总数 | 16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)
十八、MySQL连接的使用
JOIN 按照功能大致分为如下三类:
- INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
- **LEFT JOIN(左连接):**获取左表所有记录,即使右表没有对应匹配的记录。
- RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
例子:
1)数据准备
-- 创建数据表 tcount_tbl
create table if not exists `tcount_tbl`(
`runoob_author` varchar(20) not null,
`runoob_count` int(5) not null
);
-- 创建数据表 runoob_tbl
create table if not exists `runoob_tbl`(
`runoob_id` int not null auto_increment,
`runoob_title` varchar(20) not null,
`runoob_author` varchar(40) not null,
`submission_date` date not null default '2018-08-08',
primary key(`runoob_id`)
)engine=InnoDB charset=utf8;
-- 插入数据
insert into tcount_tbl values('菜鸟教程', 10), ('RUNOOB.COM', 20), ('GooGle', 22);
insert into runoob_tbl (runoob_title, runoob_author, submission_date) values
('学习 PHP', '菜鸟教程', '2017-04-12'), ('学习 MySQL', '菜鸟教程', '2017-04-12'), ('学习 Java', 'RUNOOB.COM', '2015-05-01'), ('学习 Python', 'RUNOOB.COM', '2016-03-06'), ('学习 C', 'FK', '2017-04-05');
-- 查看数据
select * from tcount_tbl;
select * from runoob_tbl;
2)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;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-----------+---------------+--------------+
4 rows in set (0.00 sec)
等价的WHERE
语句
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;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-----------+---------------+--------------+
4 rows in set (0.00 sec)
3)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;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| 5 | FK | NULL |
+-----------+---------------+--------------+
5 rows in set (0.00 sec)
这里我们就看看出在inner join中没有的FK在这里出现了,这是因为left join都会将左边的表给完全的匹配完,今晚此时右边可能没有对应的记录。
4)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;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| NULL | NULL | 22 |
+-----------+---------------+--------------+
5 rows in set (0.00 sec)
这个和上面的左连接非常像,只是现在是右连接,所以右边的记录都会全部匹配。
十九、MySQL NULL值处理
当提供的查询条件字段为 NULL 时,有些命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
- IS NULL: 当列的值是 NULL,此运算符返回 true。
- IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
- <=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。
MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。
mysql> SELECT * from CityU where major IS NOT NULL;
二十、MySQL 正则表达式
MySQL 同样支持正则表达式的匹配, MySQL中使用 REGEXP
操作符来进行正则表达式匹配。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
. | 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像 ‘[.\n]’ 的模式。 |
[…] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^…] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,‘z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
例子
1)查询major中含有C的记录:
mysql> select * from CityU where major REGEXP '.*C.*';
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 4 | CS | SZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
+----+-------------------+-----+
5 rows in set (0.00 sec)
2)查询major中以C开头的记录:
mysql> select * from CityU where major REGEXP '^C.*';
+----+-------+-----+
| id | major | loc |
+----+-------+-----+
| 4 | CS | SZ |
+----+-------+-----+
1 row in set (0.00 sec)
二十一 、MySQL事务
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
- 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
- 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
- 事务用来管理 insert,update,delete 语句
一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- **原子性:**一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- **一致性:**在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- **隔离性:**数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- **持久性:**事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
注意:在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
1)事务控制语句:
-
BEGIN
或START TRANSACTION
显示地开启一个事务; -
COMMIT
也可以使用COMMIT WORK
,不过二者是等价地。COMMIT
会提交事务,并使已对数据库进行地所有修改称为永久性地; -
ROLLBACK
也可以使用ROLLBACK WORK
,不过二者是等价的,回滚会结束用户的事务,并撤销正在进行的所有未提交的修改; -
SAVEPOINT identifier
,SAVEPOINT
运行在事务中创建一个保存点,一个事务可以有多个SAVEPOINT
; -
RELEASE SAVEPOINT identifier
删除一个事务的保存点,当没有指定的保存点时,执行语句会抛出一个异常; -
ROLLBACK TO identifier
把事务回滚到标记点; -
SET TRANSCATION
用来设置事务的隔离级别,InnoDB
存储引擎提供事务的隔离级别有READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
和SERIALIZABLE
。
2)MySQL事务处理主要有两种方法:
(1)用BEGIN、ROLLBACK、COMMIT来实现
- BEGIN开始一个事务;
- ROLLBACK 事务回滚;
- COMMIT 事务确定
(2)直接用SET 来改变MySQL的自动提交模式
- SET AUTOCOMMIT = 0 禁止自动提交
- SET AUTOCOMMIT = 1 开启自动提交
例子
mysql> create table test_transcation(
-> id int(5)
-> )engine=innodb;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql> select * from test_transcation;
Empty set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_transcation value(5);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test_transcation value(6);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from test_transcation;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_transcation value(7);
Query OK, 1 row affected (0.00 sec)
-- 事务回滚
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test_transcation;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
二十二、MySQL ALTER命令
用来修改数据表名或者数据表字段。
(1)、删除字段
mysql> ALTER TABLE 表名 DROP [COLUMN] 列名;
如果同时删除多个列:
mysql> ALTER TABLE 表名 DROP [COLUMN] 列名1,
DROP [COLUMN] 列名2,
...;
注意;
-
从表中删除列会使所有数据库对象(如存储过程,视图,触发器等)依赖于列无效。 例如,您可能有一个引用列的存储过程。 删除列时,存储过程将变为无效。 要修复它,必须手动更改存储过程的代码。
-
取决于已删除列的其他应用程序的代码也必须更改,这需要时间和精力。
-
从大型表中删除列可能会影响数据库的性能。
例子:
mysql> select * from employee_tb1;
+----+------+---------------------+--------+
| id | name | data | singin |
+----+------+---------------------+--------+
| 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)
mysql> alter table employee_tb1 drop column id;
Query OK, 6 rows affected (0.08 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from employee_tb1;
+------+---------------------+--------+
| name | data | singin |
+------+---------------------+--------+
| 小明 | 2016-04-22 15:25:33 | 1 |
| 小王 | 2016-04-20 15:25:47 | 3 |
| 小丽 | 2016-04-19 15:26:02 | 2 |
| 小王 | 2016-04-07 15:26:14 | 4 |
| 小明 | 2016-04-11 15:26:40 | 4 |
| 小明 | 2016-04-04 15:26:54 | 2 |
+------+---------------------+--------+
6 rows in set (0.00 sec)
(2)、添加字段
ALTER TABLE table
ADD [COLUMN] column_name_1 column_1_definition [FIRST|AFTER existing_column],
ADD [COLUMN] column_name_2 column_2_definition [FIRST|AFTER existing_column],
...;
注意:
- MySQL允许通过指定
FIRST
关键字将新列添加到表的第一列。 它还允许您使用AFTER existing_column
子句在现有列之后添加新列。如果没有明确指定新列的位置,MySQL会将其添加为最后一列。
例子
mysql> alter table employee_tb1 add column id int(10) not null primary key auto_increment first;
Query OK, 0 rows affected, 1 warning (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> select * from employee_tb1;
+----+------+---------------------+--------+
| id | name | data | singin |
+----+------+---------------------+--------+
| 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)
(3)、添加主键
mysql> ALTER TABLE 表名 primary key(字段名);
注意:这个字段名已经存在了;否则可以使用如下方式:
mysql> ALTER TABLE 表名 ADD int(10) primary key;
(4)、修改字段类型及名称
mysql> ALTER TABLE 表名 MODIFY 字段名 定义;
例如:修改字段name为char(20);
mysql> alter table employee_tb1 modify name char(20);
Query OK, 6 rows affected (0.10 sec)
Records: 6 Duplicates: 0 Warnings: 0
(5)、ALTER TABLE 对 Null 值和默认值的影响
当你修改字段时,你可以指定是否包含值或者是否设置默认值。
mysql> ALTER TABLE 表名 MODIFY 列名 INT NOT NULL DEFAULT 100;
如果你不设置默认值,MySQL会自动设置该字段默认为 NULL。
(6)、修改字段默认值
ALTER TABLE 表名 ALTER 字段名 SET DEFAULT 值;
注意:这里修改使用了关键字ALTER
和SET
.
(7)、查看数据表类型
mysql> SHOW TABLE STATUS LIKE 'testalter_tbl'\G;
(8)、修改表名
mysql> ALTER TABLE 表名 RENAME TO 新表名;
二十三、MySQL索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
索引分单列索引和组合索引。
- 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。
- 组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
(1)、普通索引
1)创建索引:这是最基本的索引,没有任何限制
CREATE INDEX indexName ON mytable(username(length));
2)修改表结构(添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
3)创建表的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);
4)删除索引的语法
DROP INDEX [indexName] ON mytable;
(2)、唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
1)创建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
2)修改表结构
ALTER table mytable ADD UNIQUE [indexName] (username(length))
3)创建表的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);
(3)、使用ALTER命令添加和删除索引
添加:
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list);
-- 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为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 ,用于全文索引。
删除:
ALTER TABLE testalter_tbl DROP INDEX index_name;
### (4)、显示索引信息
mysql> SHOW INDEX FROM table_name; \G
二十四、MySQL临时表
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。
创建语法
CREATE TEMPORARY TABLE 临时表名(column_name column_type);
删除语法
DROP TABLE 临时表名:
二十五、复制表
完全的复制MySQL的数据表,包括表的结构,索引,默认值等。
方法一:
步骤:
- 使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。
- 复制以下命令显示的SQL语句,修改数据表名,并执行SQL语句,通过以上命令 将完全的复制数据表结构。
- 如果你想复制表的内容,你就可以使用 INSERT INTO … SELECT 语句来实现。
方法二:
- 只复制表结构到新表
CREATE TABLE 新表 select * from 旧表 where 1=2;
-- 或者
CREATE TABLE 新表 LIKE 旧表;
- 复制表结构及数据到新表
CREATE TABLE 新表 select * from 旧表;
二十四、MySQL序列使用
MySQL 序列是一组整数:1, 2, 3, …,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。
(1)、使用AUTO_INCREMENT
MySQL中最简单使用序列的方法就是使用MySQL AUTO_INCREMENT 来定义。
在定义表的时候定义:
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
);
也可使用ALTER修改
mysql> ALTER TABLE 表名 MODIFY 列名 INT NOT NULL RPIMARY KEY AUTO_INCREMENT;
(2)、获取AUTO_INCREMENT值
mysql> SELECT LAST_INSERT_ID();
(3)、设置序列的开始值
mysql> CREATE TABLE insect
-> (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id),
-> name VARCHAR(30) NOT NULL,
-> date DATE NOT NULL,
-> origin VARCHAR(30) NOT NULL
)engine=innodb auto_increment=100 charset=utf8;
或者
mysql> ALTER TABLE t AUTO_INCREMENT = 100;
二十五、MySQL处理重复数据
(1)、防止表中出现重复数据
你可以在 MySQL 数据表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
1) PRIMARY KEY
设置表中字段 first_name,last_name 数据不能重复,你可以设置双主键模式来设置数据的唯一性.
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 INTO 与 INSERT INTO 的区别就是 INSERT IGNORE 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。
2) UNIQUE
CREATE TABLE person_tbl
(
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
UNIQUE (last_name, first_name)
);
(2)、统计重复数据
mysql> SELECT COUNT(*) as repetitions, last_name, first_name
-> FROM person_tbl
-> GROUP BY last_name, first_name
-> HAVING repetitions > 1;
(3)、过滤重复数据
mysql> SELECT DISTINCT last_name, first_name
-> FROM person_tbl;
(4)、删除重复数据
mysql> CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl GROUP BY (last_name, first_name, sex);
mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;
或者
mysql> ALTER IGNORE TABLE person_tbl
-> ADD PRIMARY KEY (last_name, first_name);
二十六、MySQL函数
MySQL 字符串函数
函数 | 描述 | 实例 |
---|---|---|
ASCII(s) | 返回字符串 s 的第一个字符的 ASCII 码。 | 返回 CustomerName 字段第一个字母的 ASCII 码:SELECT ASCII(CustomerName) AS NumCodeOfFirstChar FROM Customers; |
CHAR_LENGTH(s) | 返回字符串 s 的字符数 | 返回字符串 RUNOOB 的字符数SELECT CHAR_LENGTH("RUNOOB") AS LengthOfString; |
CHARACTER_LENGTH(s) | 返回字符串 s 的字符数 | 返回字符串 RUNOOB 的字符数SELECT CHARACTER_LENGTH("RUNOOB") AS LengthOfString; |
CONCAT(s1,s2…sn) | 字符串 s1,s2 等多个字符串合并为一个字符串 | 合并多个字符串SELECT CONCAT("SQL ", "Runoob ", "Gooogle ", "Facebook") AS ConcatenatedString; |
CONCAT_WS(x, s1,s2…sn) | 同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符 | 合并多个字符串,并添加分隔符:SELECT CONCAT_WS("-", "SQL", "Tutorial", "is", "fun!")AS ConcatenatedString; |
FIELD(s,s1,s2…) | 返回第一个字符串 s 在字符串列表(s1,s2…)中的位置 | 返回字符串 c 在列表值中的位置:SELECT FIELD("c", "a", "b", "c", "d", "e"); |
FIND_IN_SET(s1,s2) | 返回在字符串s2中与s1匹配的字符串的位置 | 返回字符串 c 在指定字符串中的位置:SELECT FIND_IN_SET("c", "a,b,c,d,e"); |
FORMAT(x,n) | 函数可以将数字 x 进行格式化 “#,###.##”, 将 x 保留到小数点后 n 位,最后一位四舍五入。 | 格式化数字 “#,###.##” 形式:SELECT FORMAT(250500.5634, 2); -- 输出 250,500.56 |
INSERT(s1,x,len,s2) | 字符串 s2 替换 s1 的 x 位置开始长度为 len 的字符串 | 从字符串第一个位置开始的 6 个字符替换为 runoob:SELECT INSERT("google.com", 1, 6, "runnob"); -- 输出:runoob.com |
LOCATE(s1,s) | 从字符串 s 中获取 s1 的开始位置 | 获取 b 在字符串 abc 中的位置:SELECT LOCATE('st','myteststring'); -- 5 返回字符串 abc 中 b 的位置:SELECT LOCATE('b', 'abc') -- 2 |
LCASE(s) | 将字符串 s 的所有字母变成小写字母 | 字符串 RUNOOB 转换为小写:SELECT LCASE('RUNOOB') -- runoob |
LEFT(s,n) | 返回字符串 s 的前 n 个字符 | 返回字符串 runoob 中的前两个字符:SELECT LEFT('runoob',2) -- ru |
LOWER(s) | 将字符串 s 的所有字母变成小写字母 | 字符串 RUNOOB 转换为小写:SELECT LOWER('RUNOOB') -- runoob |
LPAD(s1,len,s2) | 在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len | 将字符串 xx 填充到 abc 字符串的开始处:SELECT LPAD('abc',5,'xx') -- xxabc |
LTRIM(s) | 去掉字符串 s 开始处的空格 | 去掉字符串 RUNOOB开始处的空格:SELECT LTRIM(" RUNOOB") AS LeftTrimmedString;-- RUNOOB |
MID(s,n,len) | 从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len) | 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT MID("RUNOOB", 2, 3) AS ExtractString; -- UNO |
POSITION(s1 IN s) | 从字符串 s 中获取 s1 的开始位置 | 返回字符串 abc 中 b 的位置:SELECT POSITION('b' in 'abc') -- 2 |
REPEAT(s,n) | 将字符串 s 重复 n 次 | 将字符串 runoob 重复三次:SELECT REPEAT('runoob',3) -- runoobrunoobrunoob |
REPLACE(s,s1,s2) | 将字符串 s2 替代字符串 s 中的字符串 s1 | 将字符串 abc 中的字符 a 替换为字符 x:SELECT REPLACE('abc','a','x') --xbc |
REVERSE(s) | 将字符串s的顺序反过来 | 将字符串 abc 的顺序反过来:SELECT REVERSE('abc') -- cba |
RIGHT(s,n) | 返回字符串 s 的后 n 个字符 | 返回字符串 runoob 的后两个字符:SELECT RIGHT('runoob',2) -- ob |
RPAD(s1,len,s2) | 在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len | 将字符串 xx 填充到 abc 字符串的结尾处:SELECT RPAD('abc',5,'xx') -- abcxx |
RTRIM(s) | 去掉字符串 s 结尾处的空格 | 去掉字符串 RUNOOB 的末尾空格:SELECT RTRIM("RUNOOB ") AS RightTrimmedString; -- RUNOOB |
SPACE(n) | 返回 n 个空格 | 返回 10 个空格:SELECT SPACE(10); |
STRCMP(s1,s2) | 比较字符串 s1 和 s2,如果 s1 与 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1 | 比较字符串:SELECT STRCMP("runoob", "runoob"); -- 0 |
SUBSTR(s, start, length) | 从字符串 s 的 start 位置截取长度为 length 的子字符串 | 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTR("RUNOOB", 2, 3) AS ExtractString; -- UNO |
SUBSTRING(s, start, length) | 从字符串 s 的 start 位置截取长度为 length 的子字符串 | 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTRING("RUNOOB", 2, 3) AS ExtractString; -- UNO |
SUBSTRING_INDEX(s, delimiter, number) | 返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。 如果 number 是正数,返回第 number 个字符左边的字符串。 如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。 | SELECT SUBSTRING_INDEX('a*b','*',1) -- a SELECT SUBSTRING_INDEX('a*b','*',-1) -- b SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a*b*c*d*e','*',3),'*',-1) -- c |
TRIM(s) | 去掉字符串 s 开始和结尾处的空格 | 去掉字符串 RUNOOB 的首尾空格:SELECT TRIM(' RUNOOB ') AS TrimmedString; |
UCASE(s) | 将字符串转换为大写 | 将字符串 runoob 转换为大写:SELECT UCASE("runoob"); -- RUNOOB |
UPPER(s) | 将字符串转换为大写 | 将字符串 runoob 转换为大写:SELECT UPPER("runoob"); -- RUNOOB |
MySQL 数字函数
函数名 | 描述 | 实例 |
---|---|---|
ABS(x) | 返回 x 的绝对值 | 返回 -1 的绝对值:SELECT ABS(-1) -- 返回1 |
ACOS(x) | 求 x 的反余弦值(参数是弧度) | SELECT ACOS(0.25); |
ASIN(x) | 求反正弦值(参数是弧度) | SELECT ASIN(0.25); |
ATAN(x) | 求反正切值(参数是弧度) | SELECT ATAN(2.5); |
ATAN2(n, m) | 求反正切值(参数是弧度) | SELECT ATAN2(-0.8, 2); |
AVG(expression) | 返回一个表达式的平均值,expression 是一个字段 | 返回 Products 表中Price 字段的平均值:SELECT AVG(Price) AS AveragePrice FROM Products; |
CEIL(x) | 返回大于或等于 x 的最小整数 | SELECT CEIL(1.5) -- 返回2 |
CEILING(x) | 返回大于或等于 x 的最小整数 | SELECT CEILING(1.5); -- 返回2 |
COS(x) | 求余弦值(参数是弧度) | SELECT COS(2); |
COT(x) | 求余切值(参数是弧度) | SELECT COT(6); |
COUNT(expression) | 返回查询的记录总数,expression 参数是一个字段或者 * 号 | 返回 Products 表中 products 字段总共有多少条记录:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products; |
DEGREES(x) | 将弧度转换为角度 | SELECT DEGREES(3.1415926535898) -- 180 |
n DIV m | 整除,n 为被除数,m 为除数 | 计算 10 除于 5:SELECT 10 DIV 5; -- 2 |
EXP(x) | 返回 e 的 x 次方 | 计算 e 的三次方:SELECT EXP(3) -- 20.085536923188 |
FLOOR(x) | 返回小于或等于 x 的最大整数 | 小于或等于 1.5 的整数:SELECT FLOOR(1.5) -- 返回1 |
GREATEST(expr1, expr2, expr3, …) | 返回列表中的最大值 | 返回以下数字列表中的最大值:SELECT GREATEST(3, 12, 34, 8, 25); -- 34 返回以下字符串列表中的最大值:SELECT GREATEST("Google", "Runoob", "Apple"); -- Runoob |
LEAST(expr1, expr2, expr3, …) | 返回列表中的最小值 | 返回以下数字列表中的最小值:SELECT LEAST(3, 12, 34, 8, 25); -- 3 返回以下字符串列表中的最小值:SELECT LEAST("Google", "Runoob", "Apple"); -- Apple |
LN | 返回数字的自然对数,以 e 为底。 | 返回 2 的自然对数:SELECT LN(2); -- 0.6931471805599453 |
LOG(x) 或 LOG(base, x) | 返回自然对数(以 e 为底的对数),如果带有 base 参数,则 base 为指定带底数。 | SELECT LOG(20.085536923188) -- 3 SELECT LOG(2, 4); -- 2 |
LOG10(x) | 返回以 10 为底的对数 | SELECT LOG10(100) -- 2 |
LOG2(x) | 返回以 2 为底的对数 | 返回以 2 为底 6 的对数:SELECT LOG2(6); -- 2.584962500721156 |
MAX(expression) | 返回字段 expression 中的最大值 | 返回数据表 Products 中字段 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products; |
MIN(expression) | 返回字段 expression 中的最小值 | 返回数据表 Products 中字段 Price 的最小值:SELECT MIN(Price) AS LargestPrice FROM Products; |
MOD(x,y) | 返回 x 除以 y 以后的余数 | 5 除于 2 的余数:SELECT MOD(5,2) -- 1 |
PI() | 返回圆周率(3.141593) | SELECT PI() --3.141593 |
POW(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POW(2,3) -- 8 |
POWER(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POWER(2,3) -- 8 |
RADIANS(x) | 将角度转换为弧度 | 180 度转换为弧度:SELECT RADIANS(180) -- 3.1415926535898 |
RAND() | 返回 0 到 1 的随机数 | SELECT RAND() --0.93099315644334 |
ROUND(x) | 返回离 x 最近的整数 | SELECT ROUND(1.23456) --1 |
SIGN(x) | 返回 x 的符号,x 是负数、0、正数分别返回 -1、0 和 1 | SELECT SIGN(-10) -- (-1) |
SIN(x) | 求正弦值(参数是弧度) | SELECT SIN(RADIANS(30)) -- 0.5 |
SQRT(x) | 返回x的平方根 | 25 的平方根:SELECT SQRT(25) -- 5 |
SUM(expression) | 返回指定字段的总和 | 计算 OrderDetails 表中字段 Quantity 的总和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails; |
TAN(x) | 求正切值(参数是弧度) | SELECT TAN(1.75); -- -5.52037992250933 |
TRUNCATE(x,y) | 返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入) | SELECT TRUNCATE(1.23456,3) -- 1.234 |
MySQL 日期函数
函数名 | 描述 | 实例 |
---|---|---|
ADDDATE(d,n) | 计算起始日期 d 加上 n 天的日期 | SELECT ADDDATE("2017-06-15", INTERVAL 10 DAY); ->2017-06-25 |
ADDTIME(t,n) | 时间 t 加上 n 秒的时间 | SELECT ADDTIME('2011-11-11 11:11:11', 5) ->2011-11-11 11:11:16 (秒) |
CURDATE() | 返回当前日期 | SELECT CURDATE(); -> 2018-09-19 |
CURRENT_DATE() | 返回当前日期 | SELECT CURRENT_DATE(); -> 2018-09-19 |
CURRENT_TIME | 返回当前时间 | SELECT CURRENT_TIME(); -> 19:59:02 |
CURRENT_TIMESTAMP() | 返回当前日期和时间 | SELECT CURRENT_TIMESTAMP() -> 2018-09-19 20:57:43 |
CURTIME() | 返回当前时间 | SELECT CURTIME(); -> 19:59:02 |
DATE() | 从日期或日期时间表达式中提取日期值 | SELECT DATE("2017-06-15"); -> 2017-06-15 |
DATEDIFF(d1,d2) | 计算日期 d1->d2 之间相隔的天数 | SELECT DATEDIFF('2001-01-01','2001-02-02') -> -32 |
DATE_ADD(d,INTERVAL expr type) | 计算起始日期 d 加上一个时间段后的日期 | SELECT ADDDATE('2011-11-11 11:11:11',1) -> 2011-11-12 11:11:11 (默认是天) SELECT ADDDATE('2011-11-11 11:11:11', INTERVAL 5 MINUTE) -> 2011-11-11 11:16:11 (TYPE的取值与上面那个列出来的函数类似) |
DATE_FORMAT(d,f) | 按表达式 f的要求显示日期 d | SELECT DATE_FORMAT('2011-11-11 11:11:11','%Y-%m-%d %r') -> 2011-11-11 11:11:11 AM |
DATE_SUB(date,INTERVAL expr type) | 函数从日期减去指定的时间间隔。 | Orders 表中 OrderDate 字段减去 2 天:SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 2 DAY) AS OrderPayDate FROM Orders |
DAY(d) | 返回日期值 d 的日期部分 | SELECT DAY("2017-06-15"); -> 15 |
DAYNAME(d) | 返回日期 d 是星期几,如 Monday,Tuesday | SELECT DAYNAME('2011-11-11 11:11:11') ->Friday |
DAYOFMONTH(d) | 计算日期 d 是本月的第几天 | SELECT DAYOFMONTH('2011-11-11 11:11:11') ->11 |
DAYOFWEEK(d) | 日期 d 今天是星期几,1 星期日,2 星期一,以此类推 | SELECT DAYOFWEEK('2011-11-11 11:11:11') ->6 |
DAYOFYEAR(d) | 计算日期 d 是本年的第几天 | SELECT DAYOFYEAR('2011-11-11 11:11:11') ->315 |
EXTRACT(type FROM d) | 从日期 d 中获取指定的值,type 指定返回的值。 type可取值为: MICROSECONDSECONDMINUTEHOURDAYWEEKMONTHQUARTERYEARSECOND_MICROSECONDMINUTE_MICROSECONDMINUTE_SECONDHOUR_MICROSECONDHOUR_SECONDHOUR_MINUTEDAY_MICROSECONDDAY_SECONDDAY_MINUTEDAY_HOURYEAR_MONTH | SELECT EXTRACT(MINUTE FROM '2011-11-11 11:11:11') -> 11 |
FROM_DAYS(n) | 计算从 0000 年 1 月 1 日开始 n 天后的日期 | SELECT FROM_DAYS(1111) -> 0003-01-16 |
HOUR(t) | 返回 t 中的小时值 | SELECT HOUR('1:2:3') -> 1 |
LAST_DAY(d) | 返回给给定日期的那一月份的最后一天 | SELECT LAST_DAY("2017-06-20"); -> 2017-06-30 |
LOCALTIME() | 返回当前日期和时间 | SELECT LOCALTIME() -> 2018-09-19 20:57:43 |
LOCALTIMESTAMP() | 返回当前日期和时间 | SELECT LOCALTIMESTAMP() -> 2018-09-19 20:57:43 |
MAKEDATE(year, day-of-year) | 基于给定参数年份 year 和所在年中的天数序号 day-of-year 返回一个日期 | SELECT MAKEDATE(2017, 3); -> 2017-01-03 |
MAKETIME(hour, minute, second) | 组合时间,参数分别为小时、分钟、秒 | SELECT MAKETIME(11, 35, 4); -> 11:35:04 |
MICROSECOND(date) | 返回日期参数所对应的微秒数 | SELECT MICROSECOND("2017-06-20 09:34:00.000023"); -> 23 |
MINUTE(t) | 返回 t 中的分钟值 | SELECT MINUTE('1:2:3') -> 2 |
MONTHNAME(d) | 返回日期当中的月份名称,如 November | SELECT MONTHNAME('2011-11-11 11:11:11') -> November |
MONTH(d) | 返回日期d中的月份值,1 到 12 | SELECT MONTH('2011-11-11 11:11:11') ->11 |
NOW() | 返回当前日期和时间 | SELECT NOW() -> 2018-09-19 20:57:43 |
PERIOD_ADD(period, number) | 为 年-月 组合日期添加一个时段 | SELECT PERIOD_ADD(201703, 5); -> 201708 |
PERIOD_DIFF(period1, period2) | 返回两个时段之间的月份差值 | SELECT PERIOD_DIFF(201710, 201703); -> 7 |
QUARTER(d) | 返回日期d是第几季节,返回 1 到 4 | SELECT QUARTER('2011-11-11 11:11:11') -> 4 |
SECOND(t) | 返回 t 中的秒钟值 | SELECT SECOND('1:2:3') -> 3 |
SEC_TO_TIME(s) | 将以秒为单位的时间 s 转换为时分秒的格式 | SELECT SEC_TO_TIME(4320) -> 01:12:00 |
STR_TO_DATE(string, format_mask) | 将字符串转变为日期 | SELECT STR_TO_DATE("August 10 2017", "%M %d %Y"); -> 2017-08-10 |
SUBDATE(d,n) | 日期 d 减去 n 天后的日期 | SELECT SUBDATE('2011-11-11 11:11:11', 1) ->2011-11-10 11:11:11 (默认是天) |
SUBTIME(t,n) | 时间 t 减去 n 秒的时间 | SELECT SUBTIME('2011-11-11 11:11:11', 5) ->2011-11-11 11:11:06 (秒) |
SYSDATE() | 返回当前日期和时间 | SELECT SYSDATE() -> 2018-09-19 20:57:43 |
TIME(expression) | 提取传入表达式的时间部分 | SELECT TIME("19:30:10"); -> 19:30:10 |
TIME_FORMAT(t,f) | 按表达式 f 的要求显示时间 t | SELECT TIME_FORMAT('11:11:11','%r') 11:11:11 AM |
TIME_TO_SEC(t) | 将时间 t 转换为秒 | SELECT TIME_TO_SEC('1:12:00') -> 4320 |
TIMEDIFF(time1, time2) | 计算时间差值 | SELECT TIMEDIFF("13:10:11", "13:10:10"); -> 00:00:01 |
TIMESTAMP(expression, interval) | 单个参数时,函数返回日期或日期时间表达式;有2个参数时,将参数加和 | SELECT TIMESTAMP("2017-07-23", "13:10:11"); -> 2017-07-23 13:10:11 |
TO_DAYS(d) | 计算日期 d 距离 0000 年 1 月 1 日的天数 | SELECT TO_DAYS('0001-01-01 01:01:01') -> 366 |
WEEK(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 | SELECT WEEK('2011-11-11 11:11:11') -> 45 |
WEEKDAY(d) | 日期 d 是星期几,0 表示星期一,1 表示星期二 | SELECT WEEKDAY("2017-06-15"); -> 3 |
WEEKOFYEAR(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 | SELECT WEEKOFYEAR('2011-11-11 11:11:11') -> 45 |
YEAR(d) | 返回年份 | SELECT YEAR("2017-06-15"); -> 2017 |
YEARWEEK(date, mode) | 返回年份及第几周(0到53),mode 中 0 表示周天,1表示周一,以此类推 | SELECT YEARWEEK("2017-06-15"); -> 201724 |
MySQL 高级函数
函数名 | 描述 | 实例 |
---|---|---|
BIN(x) | 返回 x 的二进制编码 | 15 的 2 进制编码:SELECT BIN(15); -- 1111 |
BINARY(s) | 将字符串 s 转换为二进制字符串 | SELECT BINARY "RUNOOB"; -> RUNOOB |
CASE expression WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... WHEN conditionN THEN resultN ELSE result END | CASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回 result,而当有一个成立之后,后面的就不执行了。 | SELECT CASE WHEN 1 > 0 THEN '1 > 0' WHEN 2 > 0 THEN '2 > 0' ELSE '3 > 0' END ->1 > 0 |
CAST(x AS type) | 转换数据类型 | 字符串日期转换为日期:SELECT CAST("2017-08-29" AS DATE); -> 2017-08-29 |
COALESCE(expr1, expr2, …, expr_n) | 返回参数中的第一个非空表达式(从左向右) | SELECT COALESCE(NULL, NULL, NULL, 'runoob.com', NULL, 'google.com'); -> runoob.com |
CONNECTION_ID() | 返回服务器的连接数 | SELECT CONNECTION_ID(); -> 4292835 |
CONV(x,f1,f2) | 返回 f1 进制数变成 f2 进制数 | SELECT CONV(15, 10, 2); -> 1111 |
CONVERT(s USING cs) | 函数将字符串 s 的字符集变成 cs | SELECT CHARSET('ABC') ->utf-8 SELECT CHARSET(CONVERT('ABC' USING gbk)) ->gbk |
CURRENT_USER() | 返回当前用户 | SELECT CURRENT_USER(); -> guest@% |
DATABASE() | 返回当前数据库名 | SELECT DATABASE(); -> runoob |
IF(expr,v1,v2) | 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。 | SELECT IF(1 > 0,'正确','错误') ->正确 |
IFNULL(v1,v2) | 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。 | SELECT IFNULL(null,'Hello Word') ->Hello Word |
ISNULL(expression) | 判断表达式是否为 NULL | SELECT ISNULL(NULL); ->1 |
LAST_INSERT_ID() | 返回最近生成的 AUTO_INCREMENT 值 | SELECT LAST_INSERT_ID(); ->6 |
NULLIF(expr1, expr2) | 比较两个字符串,如果字符串 expr1 与 expr2 相等 返回 NULL,否则返回 expr1 | SELECT NULLIF(25, 25); -> |
SESSION_USER() | 返回当前用户 | SELECT SESSION_USER(); -> guest@% |
SYSTEM_USER() | 返回当前用户 | SELECT SYSTEM_USER(); -> guest@% |
USER() | 返回当前用户 | SELECT USER(); -> guest@% |
VERSION() | 返回数据库的版本号 | SELECT VERSION() -> 5.6.34 |
二十七、MySQL运算符
算术运算符
MySQL 支持的算术运算符包括:
运算符 | 作用 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ 或 DIV | 除法 |
% 或 MOD | 取余 |
比较运算符
符号 | 描述 | 备注 |
---|---|---|
= | 等于 | |
<>, != | 不等于 | |
> | 大于 | |
< | 小于 | |
<= | 小于等于 | |
>= | 大于等于 | |
BETWEEN | 在两值之间 | >=min&&<=max |
NOT BETWEEN | 不在两值之间 | |
IN | 在集合中 | |
NOT IN | 不在集合中 | |
<=> | 严格比较两个NULL值是否相等 | 两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0 |
LIKE | 模糊匹配 | |
REGEXP 或 RLIKE | 正则式匹配 | |
IS NULL | 为空 | |
IS NOT NULL | 不为空 |
逻辑运算符
运算符号 | 作用 |
---|---|
NOT 或 ! | 逻辑非 |
AND | 逻辑与 |
OR | 逻辑或 |
XOR | 逻辑异或 |
位运算符
运算符号 | 作用 |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
! | 取反 |
<< | 左移 |
>> | 右移 |
二十八、MySQL视图
MySQL 视图(View)是一种虚拟存在的表,同真实表一样,视图也由列和行构成,但视图并不实际存在于数据库中。行和列的数据来自于定义视图的查询中所使用的表,并且还是在使用视图时动态生成的。
数据库中只存放了视图的定义,并没有存放视图中的数据,这些数据都存放在定义视图查询所引用的真实表中。使用视图查询数据时,数据库会从真实表中取出对应的数据。因此,视图中的数据是依赖于真实表中的数据的。一旦真实表中的数据发生改变,显示在视图中的数据也会发生改变。
语法
CREATE VIEW <视图名> AS <SELECT语句>
查询视图:可以用SELECT语句
DESCRIBE/DESC 视图名;
-- 查看视图的详细信息
SHOW CREATE VIEW 视图名;
修改视图
ALTER VIEW <视图名> AS <SELECT语句>
删除视图
DROP VIEW <视图名1> [ , <视图名2> …]
二十九、MySQL存储过程
存储过程是一组为了完成特定功能的 SQL 语句集合。使用存储过程的目的是将常用或复杂的工作预先用 SQL 语句写好并用一个指定名称存储起来,这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。当以后需要数据库提供与已定义好的存储过程的功能相同的服务时,只需调用“CALL存储过程名字”即可自动完成。
语法
CREATE PROCEDURE <过程名> ( [过程参数[,…] ] ) <过程体>
[过程参数[,…] ] 格式
[ IN | OUT | INOUT ] <参数名> <类型>
参数说明:
1) 过程名
存储过程的名称,默认在当前数据库中创建。若需要在特定数据库中创建存储过程,则要在名称前面加上数据库的名称,即 db_name.sp_name。
需要注意的是,名称应当尽量避免选取与 MySQL 内置函数相同的名称,否则会发生错误。
2) 过程参数
存储过程的参数列表。其中,<参数名>
为参数名,<类型>
为参数的类型(可以是任何有效的 MySQL 数据类型)。当有多个参数时,参数列表中彼此间用逗号分隔。存储过程可以没有参数(此时存储过程的名称后仍需加上一对括号),也可以有 1 个或多个参数。
MySQL 存储过程支持三种类型的参数,即输入参数、输出参数和输入/输出参数,分别用 IN、OUT 和 INOUT 三个关键字标识。其中,输入参数可以传递给一个存储过程,输出参数用于存储过程需要返回一个操作结果的情形,而输入/输出参数既可以充当输入参数也可以充当输出参数。
需要注意的是,参数的取名不要与数据表的列名相同,否则尽管不会返回出错信息,但是存储过程的 SQL 语句会将参数名看作列名,从而引发不可预知的结果。
3) 过程体
存储过程的主体部分,也称为存储过程体,包含在过程调用的时候必须执行的 SQL 语句。这个部分以关键字 BEGIN 开始,以关键字 END 结束。若存储过程体中只有一条 SQL 语句,则可以省略 BEGIN-END 标志。
在存储过程的创建中,经常会用到一个十分重要的 MySQL 命令,即 DELIMITER 命令,特别是对于通过命令行的方式来操作 MySQL 数据库的使用者,更是要学会使用该命令。
在 MySQL 中,服务器处理 SQL 语句默认是以分号作为语句结束标志的。然而,在创建存储过程时,存储过程体可能包含有多条 SQL 语句,这些 SQL 语句如果仍以分号作为语句结束符,那么 MySQL 服务器在处理时会以遇到的第一条 SQL 语句结尾处的分号作为整个程序的结束符,而不再去处理存储过程体中后面的 SQL 语句,这样显然不行。
查看存储过程状态:
SHOW PROCEDURE STATUS LIKE 存储过程名;
删除存储过程:
DROP PROCEDURE [ IF EXISTS ] <过程名>
三十、MySQL触发器
MySQL 的触发器和存储过程一样,都是嵌入到 MySQL 中的一段程序,是 MySQL 中管理数据的有力工具。不同的是执行存储过程要使用 CALL 语句来调用,而触发器的执行不需要使用 CALL 语句来调用,也不需要手工启动,而是通过对数据表的相关操作来触发、激活从而实现执行。比如当对 student 表进行操作(INSERT,DELETE 或 UPDATE)时就会激活它执行。
创建语法
CREATE <触发器名> < BEFORE | AFTER >
<INSERT | UPDATE | DELETE >
ON <表名> FOR EACH Row<触发器主体>
1) 触发器名
触发器的名称,触发器在当前数据库中必须具有唯一的名称。如果要在某个特定数据库中创建,名称前面应该加上数据库的名称。
2) INSERT | UPDATE | DELETE
触发事件,用于指定激活触发器的语句的种类。
注意:三种触发器的执行时间如下。
- INSERT:将新行插入表时激活触发器。例如,INSERT 的 BEFORE 触发器不仅能被 MySQL 的 INSERT 语句激活,也能被 LOAD DATA 语句激活。
- DELETE: 从表中删除某一行数据时激活触发器,例如 DELETE 和 REPLACE 语句。
- UPDATE:更改表中某一行数据时激活触发器,例如 UPDATE 语句。
3) BEFORE | AFTER
BEFORE 和 AFTER,触发器被触发的时刻,表示触发器是在激活它的语句之前或之后触发。若希望验证新数据是否满足条件,则使用 BEFORE 选项;若希望在激活触发器的语句执行之后完成几个或更多的改变,则通常使用 AFTER 选项。
4) 表名
与触发器相关联的表名,此表必须是永久性表,不能将触发器与临时表或视图关联起来。在该表上触发事件发生时才会激活触发器。同一个表不能拥有两个具有相同触发时刻和事件的触发器。例如,对于一张数据表,不能同时有两个 BEFORE UPDATE 触发器,但可以有一个 BEFORE UPDATE 触发器和一个 BEFORE INSERT 触发器,或一个 BEFORE UPDATE 触发器和一个 AFTER UPDATE 触发器。
5) 触发器主体
触发器动作主体,包含触发器激活时将要执行的 MySQL 语句。如果要执行多个语句,可使用 BEGIN…END 复合语句结构。
6) FOR EACH ROW
一般是指行级触发,对于受触发事件影响的每一行都要激活触发器的动作。例如,使用 INSERT 语句向某个表中插入多行数据时,触发器会对每一行数据的插入都执行相应的触发器动作。