• 12.为表的字段创建索引


    数据库索引就象书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时 可以加快查询数据的速度 查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有多个普通索 引列,主键列要求列的所有内容必须唯一,而普通索引列不要求内容必须唯一 主键就类似我们在学校学习时的学号一样,班级里是唯一的,整个表的每一条记录的 键值在表内都是唯一的,用来唯一标识一条记录。

    12.1 为表创建主键索引的方法

    mysql> use oldboy
    Database changed
    mysql> create table student(
     -> id int(4) not null AUTO_INCREMENT,
     -> name char(20) not null,
     -> age tinyint(2) not null default '0',
    -> dept varchar(16) default null,
    ->primary key(id),
    ->KEY index_name(name)
    ->);​

    提示:
    primary key(id) <-主键
    KEY index_name(name) <-name 字段普通索引
    只有 int 类型且为 primary key 才可以使用 auto_increment

    12.2 查看 student 表的结构

    mysql> show create table studentG;
    *************************** 1. row ***************************
     Table: student
    Create Table: CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
     `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    ERROR:
    No query specified
    mysql> describe student;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+----------------+
    | id | int(4) | NO | PRI | NULL | auto_increment |
    | name | char(20) | NO | MUL | NULL | |
    | age | tinyint(2) | NO | | 0 | |
    | dept | varchar(16) | YES | | NULL | |
    +-------+-------------+------+-----+---------+----------------+
    4 rows in set (0.00 sec)​

    12.3 怎么删除一个表的主键

    mysql> alter table student drop primary key;​

    提示:如果一个表中的 primary key 设置了 AUTO_INCREMENT(自动增加)的话,就删不掉

    12.4 利用 alter 命令修改 id 列为自增主键列

    mysql> alter table student change id id int primary key auto_increment;

    12.5 建表后利用 alter 增加普通索引

    删除建表时创建的 index_name 索引
    mysql> select database();
    +------------+
    | database()
    +------------+
    | oldboy |
    +------------+
    1 row in set (0.00 sec)
    mysql> show create table student;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------+
    | student | CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
     `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------+
    1 row in set (0.00 sec)
    删除普通索引
    mysql> alter table student drop index index_name;
    Query OK, 0 rows affected (0.08 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    mysql> show create table student;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ---+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ---+
    | student | CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
     `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ---+
    1 row in set (0.00 sec)
    创建普通索引
    mysql> use oldboy
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    Database changed
    mysql> alter table student add index index_name (name);
    Query OK, 0 rows affected (0.47 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    mysql> show create table student;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------+
    | student | CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
     `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_name` (`name`) 提示:访问数据量很大的时候,不适合建立普通索引,会影响
    用户访问,尽量选择业务低估时建立索引
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------+
    1 row in set (0.00 sec)​

     12.6 对表字段的前 n 个字符创建普通索引

    当遇到表中比较大的列时,列内容的前 n 个字符在所有内容中已接近唯一时,这时可以对列的前 n 个字符建立索引,而无需对整个列建立本索引,这样可以节省创建索引占用的系统空间,以及降低读取和更新维护索引消耗的系统资源。
    对字段前 n 个字符创建普通索引的语法:
    create index index_name on student(name(8));条件列前 N 个字符创建索引
    下面来实战演示:

    mysql> select database();
    +------------+
    | database() |
    +------------+
    | oldboy |
    +------------+
    1 row in set (0.00 sec)
    为 dept 列前八个字符创建普通索引
    mysql> describe student;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+----------------+
    | id | int(4) | NO | PRI | NULL | auto_increment |
    | name | char(20) | NO | MUL | NULL | |
    | age | tinyint(2) | NO | | 0 | |
    | dept | varchar(16) | YES | | NULL | |
    +-------+-------------+------+-----+---------+----------------+
    4 rows in set (0.00 sec)
    mysql> create index index_name_dept on student (dept(8));
    Query OK, 0 rows affected (0.21 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    mysql> describe student;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+----------------+
    | id | int(4) | NO | PRI | NULL | auto_increment |
    | name | char(20) | NO | MUL | NULL | |
    | age | tinyint(2) | NO | | 0 | |
    | dept | varchar(16) | YES | MUL | NULL | |
    +-------+-------------+------+-----+---------+----------------+
    4 rows in set (0.00 sec)
    mysql> show create table student;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ---------------------------------------------------------------------+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ---------------------------------------------------------------------+
    | student | CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
    `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_name` (`name`),
     KEY `index_name_dept` (`dept`(8))
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ---------------------------------------------------------------------+
    1 row in set (0.00 sec)​

    另外一种建立表后创建普通索引的方法:

    mysql> alter table student add index index_name_dept (dept(8));​

    12.7 为表的多个字段创建联合索引

    如何查询数据的条件时多列时,我们可以为多个查询的列创建联合索引,甚至,可以为多列的前 n 个字符列创建联合索引,实战演示如下:

    mysql> create index index_name_and_dept on student (name,dept);
    Query OK, 0 rows affected (0.11 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    mysql> show create table student;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------------------------------------+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------------------------------------+
    | student | CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
     `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_name` (`name`),
     KEY `index_name_dept` (`dept`(8)),
     KEY `index_name_and_dept` (`name`,`dept`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)​

    12.8 为表的多个字段的前 n 个字符创建联合索引

    mysql> create index index_name_and_dept on student (name(10),dept(10));
    Query OK, 0 rows affected (0.03 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    mysql> show create table student;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----+
    | student | CREATE TABLE `student` (
     `id` int(4) NOT NULL AUTO_INCREMENT,
     `name` char(20) NOT NULL,
     `age` tinyint(2) NOT NULL DEFAULT '0',
     `dept` varchar(16) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `index_name` (`name`),
     KEY `index_name_dept` (`dept`(8)),
     KEY `index_name_and_dept` (`name`(10),`dept`(10))
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----+
    1 row in set (0.00 sec)​

    提示:按条件列查询数据时,联合索引是有前缀生效特性的
    index(a,b,c)仅 a,ab,abc 三个查询条件列可以走索引,b,bc,ac,c 等无法使用索引了

    尽量把最常用作为查询条件的列,放在第一位置

    12.9 主键也可以联合多列做索引

    *************************** 1. row ***************************
     Table: user
    Create Table: CREATE TABLE `user` (
     `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
     `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
     `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
     `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
     `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT
    '',
     `ssl_cipher` blob NOT NULL,
     `x509_issuer` blob NOT NULL,
     `x509_subject` blob NOT NULL,
     `max_questions` int(11) unsigned NOT NULL DEFAULT '0',
     `max_updates` int(11) unsigned NOT NULL DEFAULT '0',
     `max_connections` int(11) unsigned NOT NULL DEFAULT '0',
     `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
     `plugin` char(64) COLLATE utf8_bin DEFAULT '',
     `authentication_string` text COLLATE utf8_bin,
     PRIMARY KEY (`Host`,`User`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and
    global privileges'
    1 row in set (0.00 sec)
    ERROR:
    No query specified​ 

    12.10  统计一个字段列的唯一值个数

    1. mysql> select user from mysql.user;
      +-----------+
      | user |
      +-----------+
      | root |
      | blog |
      | oldgirl |
      | wordpress |
      | oldgirl |
      | oldboy |
      | oldgirl |
      | root |
      +-----------+
      8 rows in set (0.00 sec)
      mysql> select count(distinct user) from mysql.user;
      +----------------------+
      | count(distinct user) |
      +----------------------+
      | 5 |
      +----------------------+
      1 row in set (0.06 sec)
      提示:尽量在唯一值多的大表上建立索引​

    12.11  创建唯一索引(非主键)

    mysql> show create table student ;
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------------+
    | Table | Create Table
    |
    +---------+----------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------------------------
    --------------------------------------+
    | student | CREATE TABLE `student` (
    `id` int(4) NOT NULL AUTO_INCREMENT,
    `name` char(20) NOT NULL,
    `age` tinyint(2) NOT NULL DEFAULT '0',
    `dept` varchar(16) DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `index_age` (`age`),
    KEY `index_name` (`name`),
    KEY `index_name_dept` (`dept`(8)),
    KEY `index_name_and_dept` (`name`(10),`dept`(10))
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +---------+----------------------------------------------------------------------------------------------------------
    1 row in set (0.00 sec)​

    12.12  索引列的创建及生效条件

    问题一:既然索引可以加快查询速度,那么就给所有的列建索引吧?
    解答:因为索引不但占用系统空间,而且更新数据时还需要维护索引数据的,因此,索引是一把双刃剑,并不是越多越好,例如:数十到几百行的小表上无需建立索引,更新频繁,读取比较少的表要少建立索引
    问题二:需要在哪些列上创建索引了?
    解答:select user,host from mysql.user where password=...,索引一定要创建在 where 后的条件列上,而不是 select 后的选择数据的列上,另外,我们要尽量选择在唯一值多的大表上的列建立索引,例如:男女性别列唯一值,不适合建立索引

  • 相关阅读:
    谎言,
    happy,
    架构,
    休闲游戏随想,
    IOS响应者链
    application 几个方法
    ios block 循环引用
    洛谷 P 1133 教主的花园
    Codevs 1148 == 洛谷 P1057 传球游戏
    Codevs 1169 == 洛谷 P1006 传纸条
  • 原文地址:https://www.cnblogs.com/hackerlin/p/12539630.html
Copyright © 2020-2023  润新知