MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一,该笔记用于生产环境快速查阅.
♥ 文章声明 ♥ 该系列文章部分文字描述,参考于以下文献,化繁为简. 《MySQL5.7从入门到精通》 - 刘增杰
索引用于快速找出在某个列中有一特定值的行,如果不使用索引MySQL必须从第l条
记录开始读完整个表,直到找出相关的行.表越大,查询数据所花费的时间越多,如果表中查询的列有一个索引,MySQL能快速到达某个位置去搜寻数据文件,而不必查看所有数据.
使用CREATE TABLE
创建表时,除了可以定义列的数据类型,还可以定义主键约束、外键约束或者唯一性约束,而不论创建那种约束,在定义约束的同时相当于在指定列上创建了一个索引。创建表时创建索引的基本语法格式如下:
MariaDB [lyshark]> create table table_name [col_name data_type]
[unique | fulltext | spatial]
[index | key][index_name] (col_name [length])
[ASC | DESC]
#----------------------------------------------------------------------------------------
#[参数解释]
unique | fulltext | spatial #可选参数,分别表示唯一索引,全文索引,空间索引
index | key #两者作用相同,用来指定创建索引
col_name #需要创建索引的字段列,此列必须从数据表中定义的列中选择
length #可选参数,表示索引长度,只用字符串类型才能指定索引长度
ASC | DESC #指定升序或者降序的索引值存储
创建最基本的索引类型,没有唯一性之类的限制,其作用只是加对快数据的访问速度.
1.创建book
表的同时,在year_public
字段上建立普通索引,SQL语句如下:
MariaDB [lyshark]> create table book
-> (
-> bookid int not null,
-> bookname varchar(255) not null,
-> authors varchar(255) not null,
-> info varchar(255) null,
-> comment varchar(255) null,
-> year_public year not null,
-> index(year_public)
-> );
Query OK, 0 rows affected (0.03 sec)
MariaDB [lyshark]> desc book;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| bookid | int(11) | NO | | NULL | |
| bookname | varchar(255) | NO | | NULL | |
| authors | varchar(255) | NO | | NULL | |
| info | varchar(255) | YES | | NULL | |
| comment | varchar(255) | YES | | NULL | |
| year_public | year(4) | NO | MUL | NULL | |
+-------------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
2.执行完语句后,我们可以使用show create table
查看表结构:
MariaDB [lyshark]> show create table book \G;
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_public` year(4) NOT NULL, #成功建立了索引
KEY `year_public` (`year_public`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
3.使用explain
语句查看索引是否正在使用,SQL语句如下:
MariaDB [lyshark]> explain select * from book where year_public=990 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: book
type: ref
possible_keys: year_public
key: year_public
key_len: 1
ref: const
rows: 1
Extra: Using index condition
1 row in set (0.00 sec)
对以上EXPLAIN语句输出结果的解释: ●
select type
:指定所使用的SELECT查询类型,这里值为SIMPLE ●table
:指定数据库读取的数据表的名字 ●type
:指定了本数据表与其他数据表之间的关联关系 ●possible keys
:给出了MySQL在搜索数据记录时可选用的各个索引 ●key
行是MySQL实际选用的索引 ●key len
:行给出索引按字节计算的长度,key len数值越小,表示越快 ●ref
:行给出了关联关系中另一个数据表里的数据列的名字 ●rows
:行是MySQL在执行这个查询时预计会从这个数据表里读出的数据行的个数 ●extra
:行提供了与关联操作有关的信息
可以看到,possible keys
和key
的值都为year_public,说明查询时使用了索引.
创建唯一索引的主要原因是减少查询索引列操作的执行时间
,尤其是对比较庞大的数据表.它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值.如果是组合索引,则列值的组合必须唯一.
创建一个表table_1
,在表中的id
字段上使用unique
关键字创建唯一索引
MariaDB [lyshark]> create table table_1
-> (
-> id int not null,
-> name char(30) not null,
-> unique index UniqIdx(id)
-> );
Query OK, 0 rows affected (0.02 sec)
MariaDB [lyshark]> show create table table_1 \G;
*************************** 1. row ***************************
Table: table_1
Create Table: CREATE TABLE `table_1` (
`id` int(11) NOT NULL,
`name` char(30) NOT NULL,
UNIQUE KEY `UniqIdx` (`id`) #id字段已经成功建立了一个名为UniqIdx的唯一索引
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
单列索引是在数据表中的某一个字段上创建的索引
,一个表中可以创建多个单列索引.前面两个例子中创建的索引都为单列索引.
创建一个表table_2
,在表中的name字段
上创建单列索引.
MariaDB [lyshark]> create table table_2
-> (
-> id int not null,
-> name char(50) null,
-> index SingleIdx(name(20))
-> );
Query OK, 0 rows affected (0.03 sec)
MariaDB [lyshark]> show create table table_2 \G;
*************************** 1. row ***************************
Table: table_2
Create Table: CREATE TABLE `table_2` (
`id` int(11) NOT NULL,
`name` char(50) DEFAULT NULL,
KEY `SingleIdx` (`name`(20)) #name字段上已经成功建立了一个单列索引,名称为SingleIdx
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
组合索引就是在多个字段上创建一个索引.
1.首先创建table_3
表,在表中的id,name,age
字段上建立组合索引,SQL语句如下:
MariaDB [lyshark]> create table table_3
-> (
-> id int not null,
-> name char(30) not null,
-> age int not null,
-> info varchar(255),
-> INDEX MultiIdx(id,name,age)
-> );
Query OK, 0 rows affected (0.01 sec)
2.创建完成之后,我们来查看一下结果吧.
MariaDB [lyshark]> show create table table_3 \G
*************************** 1. row ***************************
Table: table_3
Create Table: CREATE TABLE `table_3` (
`id` int(11) NOT NULL,
`name` char(30) NOT NULL,
`age` int(11) NOT NULL,
`info` varchar(255) DEFAULT NULL,
KEY `MultiIdx` (`id`,`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
3.测试,在table_3
表中,差查询id和name
字段,使用explain
语句查看索引的使用情况:
MariaDB [lyshark]> explain select * from table_3 where id=1 and name='lyshark' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: table_3
type: ref
possible_keys: MultiIdx
key: MultiIdx
key_len: 34
ref: const,const
rows: 1
Extra: Using index condition
1 row in set (0.07 sec)
FULLTEXT(全文索引)可以用于全文搜索,全文索引适合用于大型数据集
.只有MyISAM存储引擎支持
FULLTEXT索引,并且只为CHAR、VARCHAR和TEXT列
创建索引.索引总是对整个列进行,不支持局部(前缀)索引.
1.创建表table_4
在表中info字段
上建立一个全文索引,SQL语句如下:
MariaDB [lyshark]> create table table_4(
-> id int not null,
-> name char(40) not null,
-> age int not null,
-> info varchar(255),
-> fulltext index FullTxtIdx(info)
-> )engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)
#注意:MySQL5.7默认存储引擎室是InnoDB,在这里我们要改成MyISAM,不然索引会报错
2.结果如下,这样我们就创建了一个名为FullTxtIdx
的全文索引.
MariaDB [lyshark]> show create table table_4 \G
*************************** 1. row ***************************
Table: table_4
Create Table: CREATE TABLE `table_4` (
`id` int(11) NOT NULL,
`name` char(40) NOT NULL,
`age` int(11) NOT NULL,
`info` varchar(255) DEFAULT NULL,
FULLTEXT KEY `FullTxtIdx` (`info`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
空间索引必须在MyISAM
类型的表中创建,且空间类型的字段必须为空.
1.创建一个表table_5
,在空间类型Geometry的字段
上创建空间索引,SQL语句如下:
MariaDB [lyshark]> create table table_5
-> (
-> g geometry not null,
-> spatial index spatIdx(g)
-> )engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> show create table table_5 \G;
*************************** 1. row ***************************
Table: table_5
Create Table: CREATE TABLE `table_5` (
`g` geometry NOT NULL,
SPATIAL KEY `spatIdx` (`g`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
可以看到,table_5表
的g字段
上创建了名称为spatIdex
的空间索引,注意:创建时间指定空间类型字段值的非空约束,并且表的存储引擎必须为MyISAM.
在已经存在的表中创建索引,可以使用alter table
语句或者create index
语句,本节将介绍如何在一个已经存在的表上创建一个索引,首先先来看一下索引的添加语法,SQL语句如下:
alter table table_name add [unique | fulltext | spatial ]
[ index | key ] [ index_name ](col_name[length],.....)
[ asc |esc ]
#----------------------------------------------------------------------------------------
#[参数解释]
unique | fulltext | spatial #可选参数,分别表示唯一索引,全文索引,空间索引
index | key #两者作用相同,用来指定创建索引
col_name #需要创建索引的字段列,此列必须从数据表中定义的列中选择
length #可选参数,表示索引长度,只用字符串类型才能指定索引长度
ASC | DESC #指定升序或者降序的索引值存储
在book表中bookname字段
上,将建立名为BKNameIdx的普通索引
.
1.首先添加索引前,使用show index语句
查看指定表中创建的索引
MariaDB [lyshark]> show index from book \G;
*************************** 1. row ***************************
Table: book
Non_unique: 1
Key_name: year_public
Seq_in_index: 1
Column_name: year_public
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
1 row in set (0.00 sec)
对以上语句输出结果的解释: ●
Table
:表示创建索引的表 ●Non unique
:表示索引非唯一,1代表是非唯一索引,0代表唯一索引 ●Key name
:表示索引的名称 ●Seq in index
:表示该字段在索引中的位置,单列索引该值为1,组合索引为每个字段在索引定义中的顺序 ●Column name
:表示定义索引的列字段 ●Sub part
:表示索引的长度 ●Null
:表示该字段是否能为空值 ●Index type
:表示索弓引类型
可以看到,book表中已经存在了一个索引,即前面已经定义的名称为year publication索引
,该索引为非唯一索引.
2.使用alter table
在bookname字段
上添加索引,SQL语句如下:
MariaDB [lyshark]> alter table book add index BKNameIdx(bookname(30));
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
3.使用show index
语句查看表中索引:
MariaDB [lyshark]> show index from book \G;
*************************** 1. row ***************************
Table: book
Non_unique: 1
Key_name: year_public
Seq_in_index: 1
Column_name: year_public
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: book
Non_unique: 1
Key_name: BKNameIdx
Seq_in_index: 1
Column_name: bookname
Collation: A
Cardinality: 0
Sub_part: 30
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
2 rows in set (0.00 sec)
可以看到表中有两个索引,一个通过alter table 语句
添加的名称为BKNameIdx的索引
,该索引为非唯一索引,长度为30
.
在book表
的bookId字段
上建立名称为UniqidIdx的唯一索引
,SQL语句如下:
MariaDB [lyshark]> alter table book add unique index UniqidIdx(bookId);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> show index from book \G
*************************** 1. row ***************************
Table: book
Non_unique: 0
Key_name: UniqidIdx #此处为创建的唯一索引。
Seq_in_index: 1
Column_name: bookid
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
可以看到,Non_unique属性为0
,表示名称为UniqidIdx的索引为唯一性索引
,创建唯一索引成功.
在book表
的comment字段
建立单列索引,SQL语句如下:
MariaDB [lyshark]> alter table book add index BkcmtIdx(comment(50));
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> show index from book \G;
*************************** 4. row ***************************
Table: book
Non_unique: 1
Key_name: BkcmtIdx
Seq_in_index: 1
Column_name: comment
Collation: A
Cardinality: 0
Sub_part: 50
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
4 rows in set (0.00 sec)
语句执行后,book表的comment字段
上建立了名称为BkcmtIdx的索引
,长度为50
,查询时只需要检索前50个
字符.
在book表
的authors和info字段
上建立组合索引,SQL语句如下:
MariaDB [lyshark]> alter table book add index BkAuAndInfoIdx(authors(30),info(50));
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> show index from book \G;
*************************** 5. row ***************************
Table: book
Non_unique: 1
Key_name: BkAuAndInfoIdx
Seq_in_index: 1
Column_name: authors
Collation: A
Cardinality: 0
Sub_part: 30
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 6. row ***************************
Table: book
Non_unique: 1
Key_name: BkAuAndInfoIdx
Seq_in_index: 2
Column_name: info
Collation: A
Cardinality: 0
Sub_part: 50
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
6 rows in set (0.00 sec)
可以看到,名称为BkAuAndInfoIdx索引
,有两个字段组成authors字段长度为30
,在组合索引中序列为1
该字段不许为空NULL,info字段长度为50
,在组合索引中的序号为2,该字段可以为空值NULL.
创建表table_6
在table_6表上使用alter table
创建全文索引.
1.首先创建表table_6
并指定存储引擎为MyISAM
,SQL语句如下:
MariaDB [lyshark]> create table table_6
-> (
-> id int not null,
-> info char(255)
-> )engine=MyISAM;
Query OK, 0 rows affected (0.01 sec)
2.创建并查看全文索引:
MariaDB [lyshark]> alter table table_6 add fulltext index infoFTIdx(info);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> show index from table_6 \G;
*************************** 1. row ***************************
Table: table_6
Non_unique: 1
Key_name: infoFTIdx
Seq_in_index: 1
Column_name: info
Collation: NULL
Cardinality: NULL
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: FULLTEXT
Comment:
Index_comment:
1 row in set (0.01 sec)
以上可知,table_6表
中已经创建了名称为infoFTIdx的索引
,该索引在info字段
上创建,类型为fulltext
,允许为空.
创建表table_7
,在table_7的空间数据类型字段g
上创建名称为spatIdx的空间索引
,SQL语句如下:
1.首先创建表结构.
MariaDB [lyshark]> create table table_7
-> (
-> g geometry not null
-> )engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)
2.使用alter table
在table_7
上创建空间索引.
MariaDB [lyshark]> alter table table_7 add spatial index spatIdx(g);
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> show index from table_7 \G;
*************************** 1. row ***************************
Table: table_7
Non_unique: 1
Key_name: spatIdx #此处是空间索引的名称
Seq_in_index: 1
Column_name: g
Collation: A
Cardinality: NULL
Sub_part: 32
Packed: NULL
Null:
Index_type: SPATIAL
Comment:
Index_comment:
1 row in set (0.00 sec)
删除索引可以使用alter table
语句,下面我们介绍它的删除方法,例如:删除book表
中名称为UniqidIdx的唯一索引
,SQL语句如下:
1.首先查看一下名称为UniqidIdx
的索引,输入Show语句:
MariaDB [lyshark]> show create table book \G;
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_public` year(4) NOT NULL,
UNIQUE KEY `UniqidIdx` (`bookid`), #下一步我们删除它
KEY `year_public` (`year_public`),
KEY `BKNameIdx` (`bookname`(30)),
KEY `BkcmtIdx` (`comment`(50)),
KEY `BkAuAndInfoIdx` (`authors`(30),`info`(50))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
2.删除UniqidIdx
唯一索引,SQL语句如下:
MariaDB [lyshark]> alter table book drop index UniqidIdx; #删除语句
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> show create table book \G; #删除成功了
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_public` year(4) NOT NULL,
KEY `year_public` (`year_public`),
KEY `BKNameIdx` (`bookname`(30)),
KEY `BkcmtIdx` (`comment`(50)),
KEY `BkAuAndInfoIdx` (`authors`(30),`info`(50))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
视图是一张虚拟表,是从数据库中一个或多个表中导出来的表,视图还可以从已经存在的视图基础上定义,视图一经定义便存储在数据库中,与其相对应的数据并没有像表那样在数据库中再存储一份,通过视图看到的数据只是存放在基本表中的数据.对视图的操作与对表的操作一样,可以对其进行查询、修改和删除.当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化.同时,若基本表的数据发生变化,则这种变化也可以自动地反映到视图中.
如下小例子:下面有个student表
和 info表
,现在我分别只想去除其中的ID号,姓名,班级
,此时我们就需要用一个视图来解决,取出指定的字段.
create table student (s_id int,name varchar(40));
create table info (s_id int,glass varchar(40),addr varchar(90));
视图提供了一个很好的解决方法,创建视图的信息来自表的部分信息,只取出需要的信息,这样既能满足需求也不破坏原有的表结构.
视图的作用:
视图不仅可以简化用户对于数据的理解,也可以简化他们的操作,那些被经常使用的查询可以定义为视图,从而使得用户不必为以后的操作每次指定全部条件.
通过视图用户只能查询和修改他们所能见到的数据,数据库中的其他数据则既看不见也取不到,数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对象上,但不能授权到数据库特定行和特定的列上.通过视图,用户可以被限制在数据的不同子集上.
在单表上创建视图:
1.首先创建一个基本表table1
并插入测试数据.
MariaDB [lyshark]> create table table1(quantity INT,price INT);
Query OK, 0 rows affected (0.02 sec)
MariaDB [lyshark]> insert into table1 values(1,10);
Query OK, 1 row affected (0.00 sec)
MariaDB [lyshark]> insert into table1 values(2,30);
Query OK, 1 row affected (0.00 sec)
MariaDB [lyshark]> insert into table1 values(3,50);
Query OK, 1 row affected (0.00 sec)
2.创建视图,在table1
表上创建一个view_tab1
视图,其中代码有三个字段x,y,totle
,SQL语句如下:
MariaDB [lyshark]> create view view_tab1(x,y,totle)
-> AS SELECT quantity,price,quantity * price
-> FROM table1;
Query OK, 0 rows affected (0.00 sec)
3.紧接着我们使用视图来查询创建的新表格.
MariaDB [lyshark]> select * from view_tab1;
+------+------+-------+
| x | y | totle |
+------+------+-------+
| 1 | 10 | 10 |
| 2 | 30 | 60 |
| 3 | 50 | 150 |
+------+------+-------+
3 rows in set (0.00 sec)
在多张表上创建视图:
1.首先创建两个测试表并插入一些数据,这里我们就创建要给student
和info
两个表,SQL语句如下:
MariaDB [lyshark]> create table student
-> (
-> s_id INT,
-> name VARCHAR(40)
-> );
Query OK, 0 rows affected (0.01 sec)
MariaDB [lyshark]> create table info
-> (
-> s_id INT,
-> glass VARCHAR(40),
-> addr VARCHAR(90)
-> );
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> insert into student values(1,'wang'),(2,'rui');
Query OK, 2 rows affected (0.33 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> insert into info values(1,'wuban','henan'),(2,'sanban','hebei'),(3,'yiban','s
handong');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
2.接下来我们创建一个视图stu_glass
,其中有三个参数(id,name,glass),分别对应两个表的不同字段,并且通过where条件
限定ID号相同的关联在一起.
MariaDB [lyshark]> create view stu_glass(id,name,glass)
-> AS select student.s_id,student.name,info.glass
-> FROM student,info where student.s_id = info.s_id;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> select * from stu_glass;
+------+------+--------+
| id | name | glass |
+------+------+--------+
| 1 | wang | wuban |
| 2 | rui | sanban |
+------+------+--------+
2 rows in set (0.01 sec)
以上例子就解决了刚开始那个问题,通过这个视图可以很好地保护基本表中的数据.
使用desc查看视图表结构:
MariaDB [lyshark]> desc stu_glass;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(40) | YES | | NULL | |
| glass | varchar(40) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
使用show table status查看视图:
MariaDB [lyshark]> show table status like 'stu_glass' \G
*************************** 1. row ***************************
Name: stu_glass
Engine: NULL
Version: NULL
Row_format: NULL
Rows: NULL
Avg_row_length: NULL
Data_length: NULL
Max_data_length: NULL
Index_length: NULL
Data_free: NULL
Auto_increment: NULL
Create_time: NULL
Update_time: NULL
Check_time: NULL
Collation: NULL
Checksum: NULL
Create_options: NULL
Comment: VIEW
1 row in set (0.00 sec)
使用show create view查看视图详细信息:
MariaDB [lyshark]> show create view stu_glass \G
*************************** 1. row ***************************
View: stu_glass
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `stu_glass` AS select `student`.`s_id` AS `id`,`student`.`name` AS `name`,`info`.`glass` AS `glass` from (`student` join `info`) where (`student`.`s_id` = `info`.`s_id`)
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
MariaDB [lyshark]>
在views表中查看视图详细信息:
MariaDB [lyshark]> select * from information_schema.views; #查视图
MariaDB [lyshark]> select * from information_schema.tables; #查表
+---------------+--------------+------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME |
+---------------+--------------+------------+
| def | lyshark | stu_glass |
| def | lyshark | view_tab1 |
| def | lyshark | view_tab2 |
+---------------+--------------+------------+
3 rows in set (0.01 sec)
alter语句修改视图:
使用alter语句,修改视图view_tab1
,SQL语句如下:
MariaDB [lyshark]> desc view_tab1;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| x | int(11) | YES | | NULL | |
| y | int(11) | YES | | NULL | |
| totle | bigint(21) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
MariaDB [lyshark]> alter view view_tab1
-> AS select quantity from table1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> desc view_tab1;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| quantity | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
update更新视图:
MariaDB [lyshark]> select * from stu_glass;
+------+------+--------+
| id | name | glass |
+------+------+--------+
| 1 | wang | wuban |
| 2 | rui | sanban |
+------+------+--------+
2 rows in set (0.00 sec)
MariaDB [lyshark]> update stu_glass SET id=3 where name="rui";
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
MariaDB [lyshark]> select * from stu_glass;
+------+------+-------+
| id | name | glass |
+------+------+-------+
| 1 | wang | wuban |
| 3 | rui | yiban |
+------+------+-------+
2 rows in set (0.00 sec)
删除视图中指定字段:注意,联合字段的视图无法删除.
MariaDB [lyshark]> select * from view_tab1;
+------+------+-------+
| x | y | totle |
+------+------+-------+
| 1 | 10 | 10 |
| 2 | 30 | 60 |
| 3 | 50 | 150 |
+------+------+-------+
3 rows in set (0.00 sec)
MariaDB [lyshark]> delete from view_tab1 where x=1;
Query OK, 1 row affected (0.00 sec)
MariaDB [lyshark]> select * from view_tab1;
+------+------+-------+
| x | y | totle |
+------+------+-------+
| 2 | 30 | 60 |
| 3 | 50 | 150 |
+------+------+-------+
2 rows in set (0.00 sec)
删除一个视图:
1.查询一下,我们比如要删除view_tab1
和view_tab2
两个视图.
MariaDB [lyshark]> select * from information_schema.views; #查视图
+---------------+--------------+------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME |
+---------------+--------------+------------+
| def | lyshark | stu_glass |
| def | lyshark | view_tab1 |
| def | lyshark | view_tab2 |
+---------------+--------------+------------+
3 rows in set (0.01 sec)
2.通过drop view
语句直接删除掉.
MariaDB [lyshark]> drop view if exists view_tab1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> drop view if exists view_tab2;
Query OK, 0 rows affected (0.00 sec)
3.再次查询,发现没有了,删除成功.
MariaDB [lyshark]> select * from information_schema.views;
+---------------+--------------+------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME |
+---------------+--------------+------------+
| def | lyshark | stu_glass |
+---------------+--------------+------------+
1 row in set (0.00 sec)
触发器(Trigger)是个特殊的存储过程,不同的是,执行存储过程要使用CALL语句来调用,而触发器的执行不需要使用CALL语句来调用,也不需要手工启动,只要当一个预定义的事件发生的时候,就会被MySQL自动调用,触发器可以查询其他表,而且可以包含复杂的SQL语句,它们主要用于满足复杂的业务规则或要求.
一般来说创建触发器的基本语法如下:
create trigger trigger_name trigger_time trigger_event
ON table_name FOR EACH ROW trigger_stmt
#----------------------------------------------------------------
#[参数解释]
trigger_name #触发器名称
trigger_time #标识触发时机(befor/after)
trigger_event #标识触发事件
table_name #建立触发器表名,即在那张表上建立触发器
trigger_stmt #触发器执行语句
而创建多个执行语句的触发器的语法如下:
create trigger trigger_name trigger_time trigger_event
ON table_name FOR EACH ROW
BEGIN
执行语句块...
END
创建只有一条执行语句的触发器:
1.首先创建一个account表
,表中有两个字段,分别是acct_num字段(INT)
,amount字段(float)
.
MariaDB [lyshark]> create table account(acct_num INT,amount DECIMAL(10,2));
Query OK, 0 rows affected (0.01 sec)
MariaDB [lyshark]> desc account;
+----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+-------+
| acct_num | int(11) | YES | | NULL | |
| amount | decimal(10,2) | YES | | NULL | |
+----------+---------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
2.创建一个名为ins_sum
的触发器,触发条件是向数据表account
插入数据之前,对新插入的amount
字段值进行求和计算.
MariaDB [lyshark]> create trigger ins_sum BEFORE INSERT ON account
-> FOR EACH ROW SET @sum=@sum+NEW.amount;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> set @sum=0;
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> insert into account values(1,1.00),(2,2.00);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> select @sum;
+------+
| @sum |
+------+
| 3.00 |
+------+
1 row in set (0.00 sec)
以上例子,首先创建一个account
表,再向表account
插入数据之前,计算所有新插入的account
表的amount
值之和,触发器的名称为ins_sum
,条件是在向表中插入数据之前触发.
创建具有多条执行语句的触发器:
1.首相创建4个测试表格,并写入以下测试字段.
MariaDB [lyshark]> create table test1(a1 INT);
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> create table test2(a2 INT);
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> create table test3(a3 INT NOT NULL AUTO_INCREMENT primary key);
Query OK, 0 rows affected (0.00 sec)
MariaDB [lyshark]> create table test4(
-> a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> b4 INT DEFAULT 0
-> );
Query OK, 0 rows affected (0.07 sec)
2.创建一个包含多个执行语句的触发器,当test1
有数据插入时,执行触发语句,代码如下:
MariaDB [lyshark]> DELIMITER //
MariaDB [lyshark]> create trigger testref BEFORE INSERT ON test1
-> FOR EACH ROW
-> BEGIN
-> insert into test2 set a2=NEW.a1;
-> delete from test3 where a3=NEW.a1;
-> update test4 set b4=b4+1 where a4=NEW.a1;
-> END
-> //
MariaDB [lyshark]> DELIMITER ;;
以上代码创建了一个名为testref
的触发器,这个触发器的触发条件是在向表test1
插入数据前执行触发器的语句,具体执行代码如下:
MariaDB [lyshark]> insert into test1 values (1),(3),(1),(7),(1),(4);
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
当test1表格插入数据后,其他表格也会出现相同的数据,这就是触发器所做的贡献.
MariaDB [lyshark]> select * from test1;
+------+
| a1 |
+------+
| 1 |
| 3 |
| 1 |
| 7 |
| 1 |
| 4 |
+------+
6 rows in set (0.00 sec)
MariaDB [lyshark]> select * from test2;
+------+
| a2 |
+------+
| 1 |
| 3 |
| 1 |
| 7 |
| 1 |
| 4 |
+------+
6 rows in set (0.00 sec)
关于触发器的另一个小实验:
1.先来创建一个数据表.
MariaDB [lyshark]> create table myevent(id int,name char(20));
Query OK, 0 rows affected (0.01 sec)
MariaDB [lyshark]> desc myevent;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(20) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
2.创建一个trig_insert
的触发器,在向表account
插入数据之后会向表myevent
插入一组数据,代码如下:
MariaDB [lyshark]> create trigger trig_insert AFTER INSERT ON account
-> FOR EACH ROW INSERT INTO myevent values(2,'after insert');
Query OK, 0 rows affected (0.00 sec)
3.此时我们执行插入语句,向account
表插入数据,查询myevent
表,发现自动添加上了,说明触发器生效了.
MariaDB [lyshark]> insert into account values(1,1.00),(2,2.00);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [lyshark]> select * from myevent;
+------+--------------+
| id | name |
+------+--------------+
| 2 | after insert |
| 2 | after insert |
+------+--------------+
2 rows in set (0.00 sec)
show triggers 查看所有触发器:
MariaDB [lyshark]> show triggers \G;
*************************** 1. row ***************************
Trigger: ins_sum
Event: INSERT
Table: account
Statement: SET @sum=@sum+NEW.amount
Timing: BEFORE
Created: NULL
sql_mode:
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
*************************** 2. row ***************************
Trigger: trig_insert
Event: INSERT
Table: account
Statement: INSERT INTO myevent values(2,'after insert')
Timing: AFTER
Created: NULL
sql_mode:
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
在triggers表中查看触发器:
MariaDB [lyshark]> select * from information_schema.triggers \G;
*************************** 1. row ***************************
TRIGGER_CATALOG: def
TRIGGER_SCHEMA: lyshark
TRIGGER_NAME: ins_sum
EVENT_MANIPULATION: INSERT
EVENT_OBJECT_CATALOG: def
EVENT_OBJECT_SCHEMA: lyshark
EVENT_OBJECT_TABLE: account
ACTION_ORDER: 0
ACTION_CONDITION: NULL
ACTION_STATEMENT: SET @sum=@sum+NEW.amount
ACTION_ORIENTATION: ROW
ACTION_TIMING: BEFORE
ACTION_REFERENCE_OLD_TABLE: NULL
ACTION_REFERENCE_NEW_TABLE: NULL
ACTION_REFERENCE_OLD_ROW: OLD
ACTION_REFERENCE_NEW_ROW: NEW
CREATED: NULL
SQL_MODE:
DEFINER: root@localhost
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: latin1_swedish_ci
删除触发器: 删除lyshark
数据库中的,ins
触发器,SQL如下:
1.先查询一下触发器的名称,SQL语句如下:
MariaDB [lyshark]> select TRIGGER_SCHEMA,TRIGGER_NAME from information_schema.triggers;
+----------------+--------------+
| TRIGGER_SCHEMA | TRIGGER_NAME |
+----------------+--------------+
| lyshark | ins_sum |
| lyshark | trig_insert |
| lyshark | testref |
+----------------+--------------+
3 rows in set (0.00 sec)
2.一条命令删除.
MariaDB [lyshark]> drop trigger lyshark.ins_sum;
Query OK, 0 rows affected (0.00 sec)