索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并而后读完整个表直到它找出相关的行。php
表越大,花费时间越多。若是表对于查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要考虑全部数据。mysql
若是一个表有1000行,这比顺序读取至少快100倍。注意你须要存取几乎全部1000行,它较快的顺序读取,由于此时咱们避免磁盘寻道。
全部的MySQL索引(PRIMARY、UNIQUE和INDEX)在B树中存储。字符串是自动地压缩前缀和结尾空间。
索引用于:
快速找出匹配一个WHERE子句的行;
当执行联结时,从其余表检索行;
对特定的索引列找出MAX()或MIN()值;
若是排序或分组在一个可用键的最左面前缀上进行(例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。sql
若是全部键值部分跟随DESC,键以倒序被读取。
在一些状况中,一个查询能被优化来检索值,不用咨询数据文件。数据库
若是对某些表的全部使用的列是数字型的而且构成某些键的最左面前缀,为了更快,值能够从索引树被检索出来。 oracle
—————————————————————————————————————————————————————————————————————————————app
下面是建表的语句:
dom
- CREATE TABLE `phpcolor_ad` (
- `id` mediumint(8) NOT NULL AUTO_INCREMENT,
- `name` varchar(30) NOT NULL,
- `type` mediumint(1) NOT NULL,
- `code` text,
- PRIMARY KEY (`id`),
- KEY `type` (`type`)
- );
CREATE TABLE `phpcolor_ad` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`type` mediumint(1) NOT NULL,
`code` text,
PRIMARY KEY (`id`),
KEY `type` (`type`)
);
最后一句的KEY `type` (`type`)是什么意思?oop
若是只是key的话,就是普通索引。post
mysql的key和index多少有点使人迷惑,单独的key和其它关键词结合的key(primary key)实际表示的意义是不一样,这实际上考察对数据库体系结构的了解的。
1 :优化
key 是数据库的物理结构,它包含两层意义和做用,
一是约束(偏重于约束和规范数据库的结构完整性),
二是索引(辅助查询用的)。
包括primary key, unique key, foreign key 等。
primary key 有两个做用,一是约束做用(constraint),用来规范一个存储主键和惟一性,但同时也在此key上创建了一个主键索引;
PRIMARY KEY 约束:惟一标识数据库表中的每条记录;
主键必须包含惟一的值;
主键列不能包含 NULL 值;
每一个表都应该有一个主键,而且每一个表只能有一个主键。(PRIMARY KEY 拥有自动定义的 UNIQUE 约束)
unique key 也有两个做用,一是约束做用(constraint),规范数据的惟一性,但同时也在这个key上创建了一个惟一索引;
UNIQUE 约束:惟一标识数据库表中的每条记录。
UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了惟一性的保证。
(每一个表能够有多个 UNIQUE 约束,可是每一个表只能有一个 PRIMARY KEY 约束)
foreign key也有两个做用,一是约束做用(constraint),规范数据的引用完整性,但同时也在这个key上创建了一个index;
可见,mysql的key是同时具备constraint和index的意义,这点和其余数据库表现的可能有区别。
(至少在oracle上创建外键,不会自动创建index),所以建立key也有以下几种方式:
(1)在字段级以key方式创建, 如 create table t (id int not null primary key);
(2)在表级以constraint方式创建,如create table t(id int, CONSTRAINT pk_t_id PRIMARY key (id));
(3)在表级以key方式创建,如create table t(id int, primary key (id));
其它key建立相似,但无论那种方式,既创建了constraint,又创建了index,只不过index使用的就是这个constraint或key。
2: index是数据库的物理结构,它只是辅助查询的,它建立时会在另外的表空间(mysql中的innodb表空间)以一个相似目录的结构存储。索引要分类的话,分为前缀索引、全文本索引等;
所以,索引只是索引,它不会去约束索引的字段的行为(那是key要作的事情)。如,create table t(id int,index inx_tx_id (id));
3 总结,最后的释疑:
(1)咱们说索引分类,分为
主键索引(必须指定为“PRIMARY KEY”,没有PRIMARY Index)、
惟一索引(unique index,通常写成unique key)、
普通索引(index,只有这一种才是纯粹的index)等,也是基因而不是把index看做了key。
好比 create table t(id int, unique indexinx_tx_id (id));--index看成了key使用
(2)最重要的也就是,无论如何描述,须要理解index是纯粹的index(普通的key,或者普通索引index),仍是被看成key(如:unique index、unique key和primary key),若看成key时则会有两种意义或起两种做用。
—————————————————————————————————————————————————————————————————————————————
MySQL Key值(PRI, UNI, MUL)的含义:
PRI主键约束;
UNI惟一约束;
MUL能够重复。
注:如果普通的key或者普通的index(实际上,普通的key与普通的index同义)。
当咱们在desc 表名; 的时候,有一个Key值,表示该列是否含有索引
假设表结构以下所示
mysql> desc aa;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
| xx | int(11) | YES | PRI | NULL | |
+-------+---------+------+-----+---------+-------+
| yy | int(11) | YES | UNI | NULL | |
+-------+---------+------+-----+---------+-------+
| zz | int(11) | YES | MUL | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
咱们看到Key那一栏,可能会有4种值,即'啥也没有','PRI','UNI','MUL'
1. 若是Key是空的, 那么该列值的能够重复,表示该列没有索引, 或者是一个非惟一的复合索引的非前导列
2. 若是Key是PRI, 那么该列是主键的组成部分
3. 若是Key是UNI, 那么该列是一个惟一值索引的第一列(前导列),且不能含有空值(NULL)
4. 若是Key是MUL, 那么该列的值能够重复, 该列是一个非惟一索引的前导列(第一列)或者是一个惟一性索引的组成部分可是能够含有空值NULL
注:
一、若是对于一个列的定义,同时知足上述4种状况的多种,好比一个列既是PRI,又是UNI(若是是PRI,则必定是UNI)
那么"desc 表名"; 的时候,显示的Key值按照优先级来显示 PRI->UNI->MUL
那么此时,显示PRI。
二、若是某列不能含有空值,同时该表没有主键,则一个惟一性索引列能够显示为PRI,
三、若是多列构成了一个惟一性复合索引,那么一个惟一性索引列能够显示为MUL。(由于虽然索引的多列组合是惟一的,好比ID+NAME是惟一的,可是每个单独的列依然能够有重复的值,由于只要ID+NAME是惟一的便可)
1、key与primary key区别
- CREATE TABLE wh_logrecord (
- logrecord_id int(11) NOT NULL auto_increment,
- user_name varchar(100) default NULL,
- operation_time datetime default NULL,
- logrecord_operation varchar(100) default NULL,
- PRIMARY KEY (logrecord_id),
- KEY wh_logrecord_user_name (user_name)
- )
CREATE TABLE wh_logrecord (
logrecord_id int(11) NOT NULL auto_increment,
user_name varchar(100) default NULL,
operation_time datetime default NULL,
logrecord_operation varchar(100) default NULL,
PRIMARY KEY (logrecord_id),
KEY wh_logrecord_user_name (user_name)
)
解析:
KEY wh_logrecord_user_name (user_name)
本表的user_name字段与wh_logrecord_user_name表user_name字段创建外键
括号外是创建外键的对应表,括号内是对应字段
相似还有 KEY user(userid)
固然,key未必都是外键
总结:
Key是索引约束,对表中字段进行约束索引的,都是经过primary foreign unique等建立的。常见有foreign key,外键关联用的。
KEY forum (status,type,displayorder) # 是多列索引(键)
KEY tid (tid) # 是单列索引(键)。
如建表时: KEY forum (status,type,displayorder)
select * from table group by status,type,displayorder 是否就自动用上了此索引,
而当 select * from table group by status 此索引有用吗?
key的用途:主要是用来加快查询速度的。
- CREATE TABLE `admin_role` (
- `adminSet_id` varchar(32) NOT NULL,
- `roleSet_id` varchar(32) NOT NULL,
- PRIMARY KEY (`adminSet_id`,`roleSet_id`),
- KEY `FK9FC63FA6DAED032` (`adminSet_id`),
- KEY `FK9FC63FA6C7B24C48` (`roleSet_id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `admin_role` (
`adminSet_id` varchar(32) NOT NULL,
`roleSet_id` varchar(32) NOT NULL,
PRIMARY KEY (`adminSet_id`,`roleSet_id`),
KEY `FK9FC63FA6DAED032` (`adminSet_id`),
KEY `FK9FC63FA6C7B24C48` (`roleSet_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
主键,两个列组合在一块儿,是惟一的,内建惟一性索引,而且不能为NULL
另外,两个Key定义,至关于分别对这两列创建索引。
innodb
primary key 主键汇集索引
key 普通索引
2、KEY与INDEX区别
KEY一般是INDEX同义词。若是关键字属性PRIMARY KEY在列定义中已给定,则PRIMARY KEY也能够只指定为KEY。
这么作的目的是与其它数据库系统兼容。
PRIMARY KEY是一个惟一KEY,此时,全部的关键字列必须定义为NOT NULL。
若是这些列没有被明确地定义为NOT NULL,MySQL应隐含地定义这些列。一个表只有一个PRIMARY KEY。
MySQL 中Index 与Key 的区别
Key即键值,是关系模型理论中的一部份,好比有主键(Primary Key),外键(Foreign Key)等,用于数据完整性检否与惟一性约束等。
而Index则处于实现层面,好比能够对表的任意列创建索引,那么当创建索引的列处于SQL语句中的Where条件中时,就能够获得快速的数据定位,从而快速检索。
至于Unique Index,则只是属于Index中的一种而已,创建了Unique Index表示此列数据不可重复,猜测MySQL对Unique Index类型的索引能够作进一步特殊优化吧。
因而乎,在设计表的时候,Key只是要处于模型层面的,而当须要进行查询优化,则对相关列创建索引便可。
另外,在MySQL中,对于一个Primary Key的列,MySQL已经自动对其创建了Unique Index,无需重复再在上面创建索引了。
搜索到的一段解释:
Note that “primary” is called PRIMARY KEY not INDEX.
KEY is something on the logical level, describes your table and database design (i.e. enforces referential integrity …)
INDEX is something on the physical level, helps improve access time for table operations.
Behind every PK there is (usually) unique index created (automatically).
3、mysql中UNIQUE KEY和PRIMARY KEY有什么区别
1,Primary key的1个或多个列必须为NOT NULL,若是列为NULL,在增长PRIMARY KEY时,列自动更改成NOT NULL。
而UNIQUE KEY 对列没有此要求
2,一个表只能有一个PRIMARY KEY,但能够有多个UNIQUE KEY
3,主键和惟一键约束是经过参考索引实施的,若是插入的值均为NULL,
则根据索引的原理,全NULL值不被记录在索引上,因此插入全NULL值时,能够有重复的,而其余的则不能插入重复值。
alter table t add constraint uk_t_1 unique (a,b);
insert into t (a ,b ) values (null,1); # 不能重复
insert into t (a ,b ) values (null,null);#能够重复
4、使用UNIQUE KEY
- CREATE TABLE `secure_vulnerability_warning` (
- `id` int(10) NOT NULL auto_increment,
- `date` date NOT NULL,
- `type` varchar(100) NOT NULL,
- `sub_type` varchar(100) NOT NULL,
- `domain_name` varchar(128) NOT NULL,
- `url` text NOT NULL,
- `parameters` text NOT NULL,
- `hash` varchar(100) NOT NULL,
- `deal` int(1) NOT NULL,
- `deal_date` date default NULL,
- `remark` text,
- `last_push_time` datetime default NULL,
- `push_times` int(11) default '1',
- `first_set_ok_time` datetime default NULL,
- `last_set_ok_time` datetime default NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `date` (`date`,`hash`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `secure_vulnerability_warning` (
`id` int(10) NOT NULL auto_increment,
`date` date NOT NULL,
`type` varchar(100) NOT NULL,
`sub_type` varchar(100) NOT NULL,
`domain_name` varchar(128) NOT NULL,
`url` text NOT NULL,
`parameters` text NOT NULL,
`hash` varchar(100) NOT NULL,
`deal` int(1) NOT NULL,
`deal_date` date default NULL,
`remark` text,
`last_push_time` datetime default NULL,
`push_times` int(11) default '1',
`first_set_ok_time` datetime default NULL,
`last_set_ok_time` datetime default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `date` (`date`,`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
UNIQUE KEY的用途:主要是用来防止数据插入的时候重复的。
1,建立表时
- CREATE TABLE Persons
- (
- Id_P int NOT NULL,
- LastName varchar(255) NOT NULL,
- FirstName varchar(255),
- Address varchar(255),
- City varchar(255),
- UNIQUE (Id_P)
- )
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (Id_P)
)
若是须要命名 UNIQUE 约束,以及为多个列定义 UNIQUE 约束,请使用下面的 SQL 语法:
- CREATE TABLE Persons
- (
- Id_P int NOT NULL,
- LastName varchar(255) NOT NULL,
- FirstName varchar(255),
- Address varchar(255),
- City varchar(255),
- CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
- )
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
)
2,当表已被建立时,如需在 "Id_P" 列建立 UNIQUE 约束,请使用下列 SQL:
- ALTER TABLE Persons
- ADD UNIQUE (Id_P)
ALTER TABLE Persons
ADD UNIQUE (Id_P)
如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 SQL 语法:
- ALTER TABLE Persons
- ADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
3,撤销 UNIQUE 约束
如需撤销 UNIQUE 约束,请使用下面的 SQL:
- ALTER TABLE Persons
- DROP INDEX uc_PersonID
ALTER TABLE Persons
DROP INDEX uc_PersonID