在MySQL中,索引类似于书籍的目录,如果想要快速访问数据表中的特定信息,可以建立索引加快数据查询效率。使用数据库时,不仅需要提高对数据的查询效率,也需要考虑数据的安全问题。在MySQL中可以创建一种叫作视图的虚拟表,让使用视图的用户只能访问被允许访问的结果集,从而提高数据的安全性。除了安全性,视图还具备简化查询语句和逻辑数据独立性等优点,下面将对数据库中的索引和视图分别进行讲解。
这篇文章只需要会一些简单的索引和视图简单的使用就行了,不需要过多的深入了解。
查询数据库中的数据时,默认会对全表的数据进行扫描,如果数据库中数据较大,会导致查询的效率比较低。如果能快速到达一个位置去搜寻数据,而不必查看所有数据的话,查询效率会明显提高,索引就是这样一种数据库性能调优的技术,使用索引可以快速找出数据表中的特定记录。接下来对索引进行详细讲解。
索引是数据库中为提高数据查询效率而常用的数据库对象,它好比新华字典的音序表,通过音序表可以快速地查找内容。索引在数据表中一列或多列的值与记录行之间按照一定的顺序建立关系,以提高对数据表中数据的查询速度。根据索引的实现语法不同.MySQL中常见的索引大致分为5种,具体描述如下。
普通索引是MySQL中的基本索引类型,使用KEY或INDEX定义,不需要添加任何限制条件。
创建唯一性索引的字段允许有NULL值,但需要保证索引对应字段中的值是唯一的。例如,在员工表emp的ename字段上建立唯一性索引,那么ename字段的值必须是唯一的。
主键索引是一种特殊的唯一性索引,用于根据主键自身的唯一性标识每一条记录。主键索引的字段不允许有NULL值。
全文索引主要用于提高在数据量较大的字段中的查询效率。全文索引和SQL中的LIKE模糊查询类似,不同的是LIKE模糊查询适合用于在内容较少的文本中进行模糊匹配,全文检索更擅长在大量的文本中进行数据检索。全文索引只能创建在CHAR、VARCHAR或TEXT类型的字段上。
空间索引只能创建在空间数据类型的字段上,其中空间数据类型存储的空间数据是指含有位置、大小、形状以及自身分布特征等多方面信息的数据。MySQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING和POLYGON。需要注意的是,对于创建空间索引的字段,必须将其声明为NOT NULL。
上述5种索引可以在一列或多列字段上进行创建。根据创建索引的字段个数,可以将索引分为单列索引和复合索引,具体介绍如下。
需要注意的是,虽然索引可以提高数据的查询速度,但它会占用一定的磁盘空间,并且在创建和维护索引时,其消耗的时间是随着数据量的增加而增加的。因此,使用索引时,应该综合考虑其优点和缺点。
要想使用索引提高数据表的访问速度,首先必须创建索引。MySOL提供了3确的建来习的方式,分别是创建教据表的同时创建索引、在已有的数据表上创建索引、能数据表的同时创建索引,接下来对这3种创建方式进行讲解。
创建数据表的同时创建索引的基本语法格式如下。
CREATE TABLE 表名(
字段名1 数据类型 [完整性约束条件],
字段名2 数据类型 [完整性约束条件],
......
{INDEX | KEY) [索引名] [索引类型] (字段列表)
| UNIQUE [INDEX | KEY] [索引名] [索引类型](字段列表)
| PRIMARY KEY [索引类型] (字段列表)
| {FULL TEXT | SPATIAL} [INDEX | KEY] [索引名] (字段列表)
......
);
上述语法格式中各选项的含义如下。
{INDEX | KEY]: INDEX和KEY为同义词,表示索引,二者选一即可。
索引名:可选项,表示为创建的索引定义的名称。不使用该选项时,默认使用建立索引的字段表示,复合索引则使用第一个字段的名称作为索引名称。
索引类型:可选项,某些存储引擎允许在创建索引时指定索引类型,使用的语法是USING (BTREE|HASH)。不同的存储引擎支持的索引类型也不同,例如存储引擎InnoDB和MyISAM支持BTREE,而MEMORY则同时支持BTREE和HASH。
UNIQUE:可选项,表示唯一性索引。
FULLTEXT:表示全文索引。
SPATIAL:表示空间索引。
创建索引时,如果字段列表中为单个字段,则设定的素引为单列索引:如果字段列表中为多个字段,则同时在多个字段上创建一个来习。即创建复合索引。下面根据CEAET.BLF语的的基本语法格式分别领示单列索习和复合案引的创建,具体下。
SQL语句及执行结果如下。
mysql> CREATE TABLE dept_index(
-> id INT,
-> deptno INT,
-> dname VARCHAR(20),
-> introduction VARCHAR(200),
-> address GEOMETRY NOT NULL SRID 4326,
-> PRIMARY KEY(id), 创建主键索引
-> UNIQUE INDEX(deptno), 创建唯一索引
-> INDEX(dname), 创建普通索引
-> FULLTEXT (introduction), 创建全文索引
-> SPATIAL INDEX(address) 创建空间索引
-> );
Query OK, 0 rows affected (0.10 sec)
下面通过SHOW CREATE TABLE语句查看刚创建的dept_index数据表,具体SQL语句及执行结果如下。
mysql> SHOW CREATE TABLE dept_index;
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| dept_index | CREATE TABLE `dept_index` (
`id` int NOT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
`introduction` varchar(200) DEFAULT NULL,
`address` geometry NOT NULL /*!80003 SRID 4326 */,
PRIMARY KEY (`id`),
UNIQUE KEY `deptno` (`deptno`),
KEY `dname` (`dname`),
SPATIAL KEY `address` (`address`),
FULLTEXT KEY `introduction` (`introduction`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
在上述执行结果中,第15行的id字段是主键索引;第16行的deptno字段是唯一性索引;第17行的dname字段是普通索引;第18行的address字段是空间索引;第19行的introduction字段是全文索引。
一般的我们在使用唯一约束,主键约束的时候索引都会自动建立,和我们手动添加的索引一样。
上述案例只是为了演示创建数据表时创建单列索引,真实开发中一般不会为字段都加索引。我们需要避免过度使用索引,因为索引不仅会占用一定的物理空间,而且当对数据表中的数据进行增加、删除和修改时,也需要动态维护索引,会导致数据库的写性能降低和减缓数据表的修改速度。
需要注意,如果想要创建空间索引,后面的数字就写4326就行,不然写其他的可能会报错
上面创建的索引都是对数据表中的单个字段设定的索引,下面对创建数据表时创建复合索引进行演示。
例如,创建数据表index_data,在数据表中的id和name字段上建立索引名为data的普通索引,具体SQL语句及执行结果如下。
mysql> CREATE TABLE index_data(
-> id INT NOT NULL,
-> name VARCHAR(20) NOT NULL,
-> score FLOAT,
-> INDEX data(id,name)
-> );
Query OK, 0 rows affected (0.02 sec)
从上述执行结果可以得出,语句创建成功。
下面通过SHOW CREATE TABLE语句查看数据表index_data的创建信息,以验证多列字段的普通索引data是否创建成功,具体SQL语句及执行结果如下。
mysql> SHOW CREATE TABLE index_data;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data | CREATE TABLE `index_data` (
`id` int NOT NULL,
`name` varchar(20) NOT NULL,
`score` float DEFAULT NULL,
KEY `data` (`id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
从上述结果中的第10行可以得出,id字段和name字段上共同创建了一个名称为data的普通索引。
需要注意的是,在复合索引中,多个字段的设置顺序要遵守“最左前缀原则”;也就是在创建索引时,把使用最频繁的字段放在索引字段列表的最左边,使用次频繁的字段放在索引字段列表的第二位,以此类推。
若想在一个已经存在的数据表上创建索引,可以使用CREATE INDEX语句。CREATE INDEX语句创建索引的具体语法格式如下。
CREATE [UNIQUE |FULLTEXT |SPATIAL] INDEX 索引名 [索引类型] ON 数据表名(字段列表);
在上述语法格式中,UNIQUE、FULLTEXT和SPATIAL都是可选参数,分别用于表示唯一性索引、全文索引和空间索引。
为了便于观察CREATE INDEX语句创建的索引语句,我们先创建一个新的没有索引的数据表。
mysql> CREATE TABLE index_data01(
-> id INT,
-> deptno INT,
-> dname VARCHAR(20)
-> );
Query OK, 0 rows affected (0.01 sec)
根据CREATE INDEX语句中字段列表的个数,可将创建的索引分为单列索引和复合索引,下面针对这两种情况分别进行讲解。
通过CREATE INDEX语句可以创建普通索引、唯一性索引、全文索引和空间索引。由于创建索引的格式都一样,此处以创建唯一性索引为例,演示单列索引的创建。例如,在数据表index_data01中的id字段上建立一个名称为unique_id的唯一性索引,具体SQL语句及执行结果如下。
mysql> CREATE UNIQUE INDEX unique_id ON index_data01(id);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
从上述执行结果可以得出,创建索引的语句成功执行。
下面通过SHOW CREATE TABLE语句查看数据表index_data01的创建信息,以验证id字段上是否成功创建索引,具体SQL语句及执行结果如下。
mysql> SHOW CREATE TABLE index_data01;
+--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data01 | CREATE TABLE `index_data01` (
`id` int DEFAULT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
UNIQUE KEY `unique_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从上述结果中的第10行可以得出,id字段上新增了一个名称为unique_id的唯一性索引。
下面使用CREATE INDEX语句创建复合索引。例如在index_data01表中的deptno和dname字段上创建一个名称为multi_index的复合索引,具体SQL语句和执行结果如下。
mysql> CREATE INDEX multi_index ON index_data01(deptno,dname);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
从结果中可以看到语句创建成功了。
下面通过SHOW CREATE语句查看是否成功的创建索引。
mysql> SHOW CREATE TABLE index_data01;
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data01 | CREATE TABLE `index_data01` (
`id` int DEFAULT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
UNIQUE KEY `unique_id` (`id`),
KEY `multi_index` (`deptno`,`dname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从上述结果中的第12行可以看到deptno和dname字段上新增了一个名称为multi_index的索引。
要想在已经创建好的数据表中创建索引除了使用CREATE INDEX语句之外,还可以使用修改语句ALTER TABLE。其具体语法及格式如下。
ALTER TABLE 数据表名
ADD {INDEX | KEY} [索引名] [索引类型] (字段列表)
| ADD UNIQUE [INDEX | KEY] [索引名] [索引类型] (字段列表)
| ADD PRIMARY KEY [索引类型] (字段列表)
| ADD {FULLTEXT | SPATIAL} [INDEX | KEY] [索引名] (字段列表)
在这里我统一说一遍,"|"是或的意思,也就是前后只能选一个语句,所以不要以为这个语句很长,“[]”里面的是可选项,就是可选可不选。
为了更好的观察,我再创建一个index_data02数据表。
mysql> CREATE TABLE index_data02(
-> id INT,
-> deptno INT,
-> dname VARCHAR(20)
-> );
Query OK, 0 rows affected (0.01 sec)
根据ALTER TABLE语句中索引作用的字段列表的个数,可将创建的索引分为单列索和复合索引,下面针对这两种情况分别进行讲解。
下面以创建唯一性索引为例,演示使用ALTER TABLE语句创建单列索引。例如,在数据表index_data02中的id字段上创建名称为index_id的唯一性索引,具体SQL语句及执行结果如下。
mysql> ALTER TABLE index_data02 ADD UNIQUE INDEX index_id(id);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
从上述执行结果可以得出,ALTER TABLE语句成功执行。
下面通过SHOW CREATE TABLE语句查看数据表index_data02的创建信息,以验证id字段上是否成功创建唯一性索引,具体SQL语句及执行结果如下。
mysql> SHOW CREATE TABLE index_data02;
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data02 | CREATE TABLE `index_data02` (
`id` int DEFAULT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
UNIQUE KEY `index_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从上述结果中的第10行可以得出,id字段上新增了一个名称为index_id的索引。需要注意的是,创建唯一性索引时,需要确保数据表中的数据不存在重复的值,否则会出错。
上面使用ALTERTABLE语句创建的普通索引、唯一性索引、全文索引和空间索引都是对数据表中的单列字段设定的索引。下面使用ALTER TABLE语句演示复合索引的创建。
例如,在index_data02表中的deptno字段和dname字段上创建一个名称为muti_index的复合唯一性索引,具体SQL语句和执行结果如下。
mysql> ALTER TABLE index_data02 ADD UNIQUE INDEX multi_index(deptno,dname);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
从上述执行结果可以得出,ALTER TABLE语句成功执行。
下面通过SHOW CREATE语句查看索引是否创建成功。
mysql> SHOW CREATE TABLE index_data02;
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data02 | CREATE TABLE `index_data02` (
`id` int DEFAULT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
UNIQUE KEY `index_id` (`id`),
UNIQUE KEY `multi_index` (`deptno`,`dname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从上述结果中的第9行可以得出,deptno和dname字段上新增了一个multi_index的索引。
如果需要查看数据表中已经创建的索引的信息,除使用SHOW CREATE TABLE语句在数据表的创建语句中查看外,还可以通过如下语法格式的语句进行查看。
SHOW {INDEXES | INDEX | KEYS} FROM 数据表名;
在上述语法格式中,使用INDEXES、INDEX、KEYS含义都一样,都可以查询出数据表中所有的索引信息。
下面查看数据表dept_index中的索引,具体SQL语句及执行结果如下
mysql> SHOW INDEX FROM index_data02 \G;
*************************** 1. row ***************************
Table: index_data02
Non_unique: 0
Key_name: index_id
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: index_data02
Non_unique: 0
Key_name: multi_index
Seq_in_index: 1
Column_name: deptno
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 3. row ***************************
Table: index_data02
Non_unique: 0
Key_name: multi_index
Seq_in_index: 2
Column_name: dname
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
3 rows in set (0.00 sec)
ERROR:
No query specified
由上述执行结果可以得出,查询出3条索引信息,说明数据表dept_index创建了3个索引,其中展示的索引信息字段描述的含义如表所示。
字段名 |
描述的含义 |
Table |
索引所在的数据表的名称 |
Non _unique |
索引是否可以重复,0表示不可以,1表示可以 |
Key_name |
索引的名称,如果索引是主键索引,则它的名称为PRIMARY |
Seq_in_index |
建立索引的字段序号值,默认从1开始 |
Column_name |
建立索引的字段 |
Collation |
索引字段是否有排序,A表示有排序,NULL表示没有排序 |
Cardinality |
MySQL连接时使用索引的可能性(精确度不高),值越大可能性越高Sub part 前缀索引的长度,如字段值都被索引,则Sub_part为NULL |
Packed |
关键词如何被压缩,如果没有被压缩,则为NULL |
Null |
索引字段是否含有NULL值,YES表示含有,NO表示不含有 |
Index_type |
索引方式,可选值有FULLTEXT、HASH、BTREE、RTREE |
Comment |
索引字段的注释信息 |
Index_comment |
创建索引时添加的注释信息 |
Visible |
索引对查询优化器是否可见,YES表示可见,NO表示不可见 |
Expression |
使用什么表达式作为建立索引的字段,NULL表示没有 |
在MySQL中除了可以查看数据表中的索引信息,还可以通过EXPLAIN关键字分析SOL语句的执行情况,例如分析SQL语句执行时是否使用了索引。EXPLAIN可以分析的语句有SELECT、UPDATE、DELETE、INSERT和REPLACE,下面以查询数表index_data中id为1的部门信息为例分析语句的执行情况,具体如下。
1.索引是为了提高对数据的查询效率,由于数据表index_data02中还不存在任何数据,此时对查询语句进行分析没有太大的意义,因此先往数据表index_data02中插入数据,具体SQL语句和执行结果如下。
mysql> INSERT INTO index_data02 VALUES
-> (1,10,"销售部"),
-> (2,20,"技术部"),
-> (3,30,"人事部");
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
2.使用EXPLAIN关键字查看查询语句的执行情况,具体SQL语句及执行结果如下。
mysql> EXPLAIN SELECT id FROM index_data WHERE id=1 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: index_data
partitions: NULL
type: ref
possible_keys: data
key: data
key_len: 4
ref: const
rows: 1
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
字段名 |
描述 |
id |
查询标识符,默认从1开始,如果使用了联合查询,则该值依次递增 |
select_type |
查询类型,它的值包含多种,如SIMPLE表示简单SELECT,不使用UNION或子查询 |
table |
输出行所引用的数据表的名称 |
partitions |
匹配的分区 |
type |
连接的类型,它的值有多种,如ref表示使用前缀索引或条件中含有运算符"=" 或“<=>”等 |
key_len |
索引字段的长度 |
ref |
表示哪些字段或常量与索引进行了比较 |
rows |
预计需要检索的记录数 |
filtered |
按条件过滤的百分比 |
Extra |
附件信息,如Using index表示使用了索引覆盖 |
在表中,字段 select_type和type的值还有很多,读者如有需要可以自行查看官方使用手册进行了解。
由于索引会占用一定的磁盘空间,因此为避免影响数据库性能,应该及时删除不再使用的索引。在MySQL中,可以使用ALTER TABLE语句或DROP INDEX语句删除索引。下面分别讲解这两种索引删除方式。
使用ALTER TABLE删除索引的基本语法格式如下所示。
ALTER TABLE 表名 {DROP {INDEX | KEY} index_name | DROP PRIMARY KEY};
上述语法格式中index_name是索引的名称,依据上述语法格式可以删除普通索引和主键索引,其中删除主键索引时不需要指定索引名称。
下面以删除普通索引为例演示索引的删除,例如删除表index_data02中名称为multi_index的复合索引。
mysql> ALTER TABLE index_data02 DROP INDEX multi_index;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
从上述执行结果可以得出,ALTER TABLE 语句执行成功。下面通过SHOW CREATE 语句查看是否成功删除索引。
mysql> SHOW CREATE TABLE index_data02;
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data02 | CREATE TABLE `index_data02` (
`id` int DEFAULT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
UNIQUE KEY `index_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从上述代码可以看出,multi_index索引已经成功删除。
使用DROP INDEX语句删除索引的基本语法格式如下。
DROP INDEX 索引名 ON 数据表名;
下面根据这个语法删除index_data02表中的index_id的索引。具体SQL语句及执行结果如下。
mysql> DROP INDEX index_id ON index_data02;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
从上述执行结果可以看出,DROP INDEX语句执行成功。下面通过SHOW CREATE 语句查看是否成功删除。
mysql> SHOW CREATE TABLE index_data02;
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_data02 | CREATE TABLE `index_data02` (
`id` int DEFAULT NULL,
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从上述代码可以看出,index_id索引已经成功删除。
需要注意的是,删除主键索引时,索引名固定为PRIMARY。因为PRIMARY是保留字,所以必须将其指定为带引号的标识符,示例如下。
DROP INDEX PRIMARY
ON 数据表名;
到这里就结束了,对于索引大家了解即可。
下篇文章是MySQL视图,点个关注不迷路。