"""
MySQL中的索引的存储类型有两种:BTREE、HASH

SHOW INDEX FROM 表名\G; 显示表里面所有的索引值
"""
"""
一 、 索引的优、缺点以及使用原则
    优点:
        1、查询某条数据的时候,不用在遍历整个表,提高效率。

        2、所有的MySql列类型(字段类型)都可以被索引,也就是可以给任意字段设置索引

        3、大大加快数据的查询速度

    缺点:

      1、创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加

      2、索引也需要占空间,我们知道数据表中的数据也会有最大上限设置的,如果我们有大量的索引,索引文件可能会比数据文件更快达到上限值

      3、当对表中的数据进行增加、删除、修改时,索引也需要动态的维护,降低了数据的维护速度。

    使用原则:

      通过上面说的优点和缺点,我们应该可以知道,并不是每个字段都设置索引就好,也不是索引越多越好,而是需要自己合理的使用。

         1、对经常更新的表就避免对其进行过多的索引,对经常用于查询的字段应该创建索引。

         2、数据量小的表最好不要使用索引,因为由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。

         3、在一同值少的列上(字段上)不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。相反的,在一个字段上不同值较多可是建立索引。
"""
"""
二、索引的分类  

       注意:索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引

            MyISAM和InnoDB存储引擎:只支持BTREE索引, 也就是说默认使用BTREE,不能够更换

            MEMORY/HEAP存储引擎:支持HASH和BTREE索引

       1、索引我们分为四类来讲  单列索引(普通索引,唯一索引,主键索引),组合索引,全文索引,空间索引

          1.1、单列索引:一个索引只包含单个列,但一个表中可以有多个单列索引。 这里不要搞混淆了。

             1.1.1、普通索引:

                  MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。

             1.1.2、唯一索引:

                  索引列中的值必须是唯一的,但是允许为空值

             1.1.3、主键索引:

                  是一种特殊的唯一索引,不允许有空值

          1.2、组合索引:

               在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合。
                           这个如果还不明白,等后面举例讲解时在细说。 

          1.3、全文索引  MyISAM引擎

               全文索引,只有在 MyISAM引擎 上才能使用,只能在 CHAR,VARCHAR,TEXT 类型字段上使用全文索引,介绍了要求,说说什么是全文索引,就是在一堆文字中,通过其中
                           的某个关键字等,就能找到该字段所属的记录行,比如有"你是个大煞笔,二货 ..." 通过大煞笔,可能就可以找到该条记录。这里说的是可能,因为全文索引的使用
                           涉及了很多细节,我们只需要知道这个大概意思,如果感兴趣进一步深入使用它,那么看下面测试该索引时,会给出一个博文,供大家参考.

          1.4、空间索引  MyISAM引擎

               空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。

               在创建空间索引时,使用SPATIAL关键字。

               要求,引擎为MyISAM,创建空间索引的列,必须将其声明为NOT NULL。具体细节看下面  
"""

"""
创建普通索引:               唯一     全文     空间
    语法: create table tablename [UNIQUE|FULLTEXT|SPATIAL|...]([字段1,字段类型1,字段2,字段类型2 .....] index | key (字段名称)[ASC|DESC] )
          如果你选取的字段是普通字段,那么即则是普通索引

        CREATE TABLE c(
                id INT(11) NOT NULL auto_increment,
                name VARCHAR(10) NULL,
                age TINYINT(3) NULL,
                KEY id3 (id)
        )
        -- 注意 : 可以给索引起别名,比如说这里面的 id3 就是别名
        -- 				如果不起别名,那么字段名就是索引名。
        CREATE TABLE `a` (
           `id` int(11) NOT NULL AUTO_INCREMENT,
           `name` varchar(10) DEFAULT NULL,
           `age` tinyint(3) DEFAULT NULL,
          INDEX `id` (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        -- INSERT INTO a (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ;

        SELECT * from a ;

        EXPLAIN SELECT * from a WHERE id=2;   # 这个就是 id 索引,这里面查询根据索引值进行查询,速度会很快

        EXPLAIN SELECT * from a WHERE age=6;  # age 不是索引,获取数据的时候要遍历整个表里面的数据

        INSERT INTO b (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ;

        EXPLAIN SELECT * from b WHERE id=2;

        EXPLAIN SELECT * from b WHERE age=6;

        INSERT INTO c (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ;

        EXPLAIN SELECT * from c WHERE id=2;

        EXPLAIN SELECT * from c WHERE age=6;
"""
"""
创建唯一索引:

    -- 创建唯一索引  UNIQUE INDEX|KEY  索引别名 (字段名称)

        CREATE TABLE t(
            id INT(11) NOT NULL,
            name CHAR(30),
            UNIQUE INDEX unique_id(id)
        );

        CREATE TABLE `t` (
          `id` int(11) NOT NULL,
          `name` char(30) DEFAULT NULL,
          UNIQUE KEY `unique_id` (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        -- 插入数据:
        -- INSERT INTO t (id,NAME) VALUES (1,"aa"),(2,"bb"),(3,"cc");
        -- INSERT INTO t (id,NAME) VALUES (4,"aa")

        -- INSERT INTO t (id,NAME) VALUES (4,"ee")
         # 这句话会报错,因为我们已经创建了 id 唯一索引,id值不能重复,其他值可以重复
        EXPLAIN SELECT * FROM t WHERE id=1;

"""
"""
创建主键索引:
    -- 创建主键索引

        CREATE TABLE t3(
         	 id INT(11) NOT NULL ,
         	 name CHAR(30) NOT NULL,
         	 PRIMARY KEY (id)
        )

        CREATE TABLE t2(
            id INT(11) NOT NULL,
            name CHAR(30) NULL,
            PRIMARY KEY(id)
        );

    -- 主键索引 id 作为索引,主键索引是特殊的唯一索引,索引值

        CREATE TABLE `t2` (
          `id` int(11) NOT NULL,
          `name` char(30) DEFAULT NULL,
          PRIMARY KEY (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        INSERT INTO t2 VALUES(1,'aaa'),(2,"bbb");

        SELECT * FROM t2;

        EXPLAIN SELECT * FROM t2 WHERE id = 1;
"""
"""
创建 组合索引:
    -- 创建组合索引

    -- 组合索引就是在多个字段上创建一个索引

    -- 比如说:创建一个表t3,在表中的id、name和age字段上建立组合索引
        # drop TABLE IF NOT EXISTS `haha`
        格式 :  drop table if  exists  表名

        DROP TABLE if EXISTS t3;

        CREATE TABLE t3(
            id INT(11) NOT NULL,
            NAME CHAR(30) NOT NULL,
            age INT(3) NULL,
            info VARCHAR(255),
            INDEX (id,name,age)
        )

    -- DDL语句 :
        CREATE TABLE `t4` (
          `id` int(11) NOT NULL,
          `NAME` char(30) NOT NULL,
          `age` int(3) DEFAULT NULL,
          `info` varchar(255) DEFAULT NULL,
          KEY `id` (`id`,`NAME`,`age`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    -- 表 t3 没有给组合索引命名,默认为第一个值 id 就是索引的别名

        DROP TABLE if EXISTS t4;
        CREATE TABLE t4(
            id INT(11) NOT NULL,
            NAME CHAR(30) NOT NULL,
            age INT(3) NULL,
            info VARCHAR(255),
            INDEX MultiIdx (id,name,age)
        )

    -- 表 t4 组合索引的别名为 MultiIdx

    数据库查询的时候按照最左索引的方法来查询。
        比如说: 这里面是(id,name,age)按照索引查必须字段 必须是(id),(id,name),(id,name,age),否则的话不按照索引 来查,还是会遍历表,不根据索引查询.

        INSERT INTO t4 (id,NAME,age,info) VALUES(1,"a",10,"aa"),(2,"b",20,"bb");
        SELECT * from t4;
        EXPLAIN SELECT * FROM t4 WHERE id=1;              	   # 按照索引进行查询
        EXPLAIN SELECT * FROM t4 WHERE id=1 AND name="a";       # 按照索引进行查询
        EXPLAIN SELECT * FROM t4 WHERE name="a" AND age=10;     # 遍历表t4

        组合索引就是多个字段的索引值。
"""

"""
添加索引:

    第一种方式: 修改表结构来添加索引

    alter table a add index index_name(字段名称)
        egg: ALTER TABLE book ADD INDEX BkNameIdx(bookname(30));

    第二种方式: 使用CREATE INDEX创建索引
    格式:CREATE [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] 索引名称 ON 表名(创建索引的字段名[length])[ASC|DESC]
    CREATE INDEX BkBookNameIdx ON book(bookname);
        egg : create index index_name on t4(字段名称)

    create index cc on field_name  # 创建索引

    alter table table_name add index cc (field_name)  # 添加索引 alter 语句

"""

"""
删除索引:
   删除book表中名为BkNameIdx的索引

    格式一:ALTER TABLE 表名 DROP INDEX 索引名。
        ALTER TABLE book DROP INDEX BkBookNameIdx;
            egg: alter table t4 drop index (索引名称)

    alter table t4 drop index (索引名称)

    格式二:DROP INDEX 索引名 ON 表名;
        DROP INDEX BkNameIdx ON book;
            egg: drop index (索引名称) on t4;

    drop index (索引名称) on  表名  
"""


"""

 十二、全文检索——MATCH和AGAINST

  1、SELECT MATCH(note_text)AGAINST('PICASO') FROM tb_name;

  2、InnoDB引擎不支持全文检索,MyISAM可以;

"""

# 单列索引(普通索引,唯一索引,主键索引)、 组合索引、 全文索引、 空间索引。  后两个用到的时候在说,前两个一定要记住

"""
注意 : 一个表只有一个主键,不存在删除某一列的主键,主键是唯一的
"""