MySQL 之高级命令(精简笔记)

2022-12-28 16:41:56 浏览数 (2)

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一,该笔记用于生产环境快速查阅.

♥ 文章声明 ♥ 该系列文章部分文字描述,参考于以下文献,化繁为简. 《MySQL5.7从入门到精通》 - 刘增杰

创建索引

索引用于快速找出在某个列中有一特定值的行,如果不使用索引MySQL必须从第l条记录开始读完整个表,直到找出相关的行.表越大,查询数据所花费的时间越多,如果表中查询的列有一个索引,MySQL能快速到达某个位置去搜寻数据文件,而不必查看所有数据.

使用CREATE TABLE创建表时,除了可以定义列的数据类型,还可以定义主键约束、外键约束或者唯一性约束,而不论创建那种约束,在定义约束的同时相当于在指定列上创建了一个索引。创建表时创建索引的基本语法格式如下:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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查看表结构:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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 keyskey的值都为year_public,说明查询时使用了索引.

◆创建唯一索引◆

创建唯一索引的主要原因是减少查询索引列操作的执行时间,尤其是对比较庞大的数据表.它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值.如果是组合索引,则列值的组合必须唯一.

创建一个表table_1,在表中的id字段上使用unique关键字创建唯一索引

代码语言:javascript复制
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字段上创建单列索引.

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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.创建完成之后,我们来查看一下结果吧.

代码语言:javascript复制
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语句查看索引的使用情况:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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的全文索引.

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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语句查看指定表中创建的索引

代码语言:javascript复制
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 tablebookname字段上添加索引,SQL语句如下:

代码语言:javascript复制
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语句查看表中索引:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
MariaDB [lyshark]> create table table_6
    -> (
    -> id int not null,
    -> info char(255)
    -> )engine=MyISAM;
Query OK, 0 rows affected (0.01 sec)

2.创建并查看全文索引:

代码语言:javascript复制
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.首先创建表结构.

代码语言:javascript复制
MariaDB [lyshark]> create table table_7
    -> (
    -> g geometry not null
    -> )engine=MyISAM;
Query OK, 0 rows affected (0.00 sec)

2.使用alter tabletable_7上创建空间索引.

代码语言:javascript复制
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语句:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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号,姓名,班级,此时我们就需要用一个视图来解决,取出指定的字段.

代码语言:javascript复制
create table student (s_id int,name varchar(40));
create table info (s_id int,glass varchar(40),addr varchar(90));

视图提供了一个很好的解决方法,创建视图的信息来自表的部分信息,只取出需要的信息,这样既能满足需求也不破坏原有的表结构.

视图的作用:

视图不仅可以简化用户对于数据的理解,也可以简化他们的操作,那些被经常使用的查询可以定义为视图,从而使得用户不必为以后的操作每次指定全部条件.

通过视图用户只能查询和修改他们所能见到的数据,数据库中的其他数据则既看不见也取不到,数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对象上,但不能授权到数据库特定行和特定的列上.通过视图,用户可以被限制在数据的不同子集上.

◆创建视图◆

在单表上创建视图:

1.首先创建一个基本表table1并插入测试数据.

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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.紧接着我们使用视图来查询创建的新表格.

代码语言:javascript复制
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.首先创建两个测试表并插入一些数据,这里我们就创建要给studentinfo两个表,SQL语句如下:

代码语言:javascript复制
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号相同的关联在一起.

代码语言:javascript复制
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查看视图表结构:

代码语言:javascript复制
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查看视图:

代码语言:javascript复制
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查看视图详细信息:

代码语言:javascript复制
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表中查看视图详细信息:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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更新视图:

代码语言:javascript复制
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)

删除视图中指定字段:注意,联合字段的视图无法删除.

代码语言:javascript复制
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_tab1view_tab2两个视图.

代码语言:javascript复制
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语句直接删除掉.

代码语言:javascript复制
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.再次查询,发现没有了,删除成功.

代码语言:javascript复制
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语句,它们主要用于满足复杂的业务规则或要求.

一般来说创建触发器的基本语法如下:

代码语言:javascript复制
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              #触发器执行语句

而创建多个执行语句的触发器的语法如下:

代码语言:javascript复制
create trigger trigger_name trigger_time trigger_event
ON table_name FOR EACH ROW
BEGIN
执行语句块...
END

◆创建触发器◆

创建只有一条执行语句的触发器:

1.首先创建一个account表,表中有两个字段,分别是acct_num字段(INT),amount字段(float).

代码语言:javascript复制
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字段值进行求和计算.

代码语言:javascript复制
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个测试表格,并写入以下测试字段.

代码语言:javascript复制
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有数据插入时,执行触发语句,代码如下:

代码语言:javascript复制
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插入数据前执行触发器的语句,具体执行代码如下:

代码语言:javascript复制
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表格插入数据后,其他表格也会出现相同的数据,这就是触发器所做的贡献.

代码语言:javascript复制
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.先来创建一个数据表.

代码语言:javascript复制
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插入一组数据,代码如下:

代码语言:javascript复制
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表,发现自动添加上了,说明触发器生效了.

代码语言:javascript复制
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 查看所有触发器:

代码语言:javascript复制
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表中查看触发器:

代码语言:javascript复制
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语句如下:

代码语言:javascript复制
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.一条命令删除.

代码语言:javascript复制
MariaDB [lyshark]> drop trigger lyshark.ins_sum;
Query OK, 0 rows affected (0.00 sec)

0 人点赞