zoukankan      html  css  js  c++  java
  • 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 后的选择数据的列上,另外,我们要尽量选择在唯一值多的大表上的列建立索引,例如:男女性别列唯一值,不适合建立索引

  • 相关阅读:
    Python3之random模块常用方法
    Go语言学习笔记(九)之数组
    Go语言学习笔记之简单的几个排序
    Go语言学习笔记(八)
    Python3之logging模块
    Go语言学习笔记(六)
    123. Best Time to Buy and Sell Stock III(js)
    122. Best Time to Buy and Sell Stock II(js)
    121. Best Time to Buy and Sell Stock(js)
    120. Triangle(js)
  • 原文地址:https://www.cnblogs.com/hackerlin/p/12539630.html
Copyright © 2011-2022 走看看