热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql索引与约束_MySQL之索引与约束条件

字段约束作用顾名思义就是给字段加以限制其保证数据库的完整性与一致性通过约束条件防止数据库产生一些不必要的数据保证数据库的正确性相容性安全性null和notnullmysqlcre

字段约束

作用

顾名思义就是给字段加以限制

其保证数据库的完整性与一致性

通过约束条件防止数据库产生一些不必要的数据 保证数据库的正确性 相容性 安全性

null和not null

mysql> create database test1;

mysql> use test1;

mysql> create table test1(id int not null,name varchar(254) not null); # 设置约束条件不能为空

mysql> insert into test1 values (1,'SR');

mysql> insert into test1 values (1,''); # 如果以空字符可以正常插入数据

mysql> insert into test1 values (1,null); # 为null则报错

ERROR 1048 (23000): Column 'name' cannot be null

mysql> select * from test1 where name is not null; # 当查询条件为not null的时候即使数据为空也可以被查询出来

+----+------+

| id | name |

+----+------+

| 1 | SR |

| 1 | |

+----+------+

mysql> select * from test1 where name != ''; # 当查询条件不为空的时候 数据为空不能被查询出来

+----+------+

| id | name |

+----+------+

| 1 | SR |

+----+------+

PS:当约束条件为not null的时候可以设置为"" 但是不能插入null

上述现象扩展

""和null的区别

null在数据库中是占用空间的 为空值不占用空间

对于MyISAM表中null需要一个额外的为 四舍五入到最接近的字节

null和not null效率

not null效率高于null

对于null字段来说其本身占用空间在数据查询的时候会参与字段比较

null字段不会被索引 如果参与索引的时候效率会下降很多

内核优化

MySQL 难以优化引用可空列查询,它会使索引、索引统计和值更加复杂。

可空列需要更多的存储空间,还需要一个额外字节作为判断是否为 NULL 的标志位 “需要 MySQL内部进行特殊处理”

可空列被索引后,每条记录都需要一个额外的字节,还能导致 MyISAM 中固定大小的索引变成可变大小的索引

default

作用

为指定字段设置默认值

如果在插入数据的时候给默认值赋值则使用赋值的数据

mysql> create table test2(id int not null,name varchar(255) not null default 'SR');

mysql> insert into test2(id)values(1); # 不给name字段插入数据

mysql> insert into test2(id,name)values(2,'MZ'); # 手动给name字段添加数据

mysql> select * from test2;

+----+------+

| id | name |

+----+------+

| 1 | SR | # 使用默认值

| 2 | MZ | # 使用指定的值

+----+------+

PS:

1:如果时间字段,默认为当前时间 ,插入 0 时,默认为当前时间。

2:如果是 enum 类型,默认为第一个元素

auto_increment

作用

自动增长

其作用数据类型只能为整形

每次插入一条数据的时候都会在该字段的最大值+1

mysql> create table test3 (id int not null auto_increment primary key ,test int);

mysql> desc test3;

+-------+---------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+---------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| test | int(11) | YES | | NULL | |

+-------+---------+------+-----+---------+----------------+

mysql> insert into test3(test) values(1);

mysql> insert into test3(test) values(2);

# id字段自动从1开始插入数据并且自动递增

mysql> select * from test3;

+----+------+

| id | test |

+----+------+

| 1 | 1 |

| 2 | 2 |

+----+------+

mysql> insert into test3(id,test) values(4,9);

mysql> insert into test3(id,test) values(9,9);# 跳级插入

mysql> insert into test3(test) values(9);# 从最大值+1

mysql> select * from test3;

+----+------+

| id | test |

+----+------+

| 1 | 1 |

| 2 | 2 |

| 3 | 9 |

| 4 | 9 |

| 9 | 9 |

| 10 | 9 |

+----+------+

外键约束

作用

'''

foreign key 就是表与表之间的某种约定的关系,由于这种关系的存在,我们能够让表与表之间的数据,更加的完整, 关联性更强。

关于完整性, 关联性我们举个例子

例:

有二张表,一张是用户表,一张是订单表

1. 如果我删除了用户表里的用户,那么订单表里面与这个用户有关的数据,就成了无头数据了,不完整了。

2. 如果我在订单表里面,随便插入了一条数据,这个订单在用户表里面,没有与之对应的用户。这样数据也不完整了。

3. 如果有外键的话,就方便多了,可以不让用户删除数据,或者删除用户的话,通过外键同样删除订单表里面的数据,这样也能让数据完整。

'''

参数解释

foreign key 当前表的字段

references 外部表名

on update cascade 是级联更新的意思

on update cascade 是级联更新的意思

约束条件

确保参照的表和字段存在

组成外键的字段被索引。

必须使用 ENGINE 指定存储引擎为: innodb。

外键字段和关联字段,数据类型必须一致。

外键创建

mysql> create table orderinfo(o_id int(11) auto_increment, u_id int(11) default '0', username varchar(50), money int(11), primary key(o_id), index(u_id), foreign key order_f_key(u_id) references userinfo(id) on delete cascade on update cascade) ENGINE=innodb;

mysql> create table userinfo(id int(11) not null auto_increment, name varchar(50) not null default '', sex int(1) not null default '0', primary key(id))ENGINE=innodb;

mysql> insert into userinfo(name,sex)values('HA',1),('LB',2),('HPC',1);

Query OK, 3 rows affected (0.00 sec)

mysql> insert into orderinfo (u_id,username,money)values(1,'HA',234),(2,'LB',146),(3,'HPC',256);

Query OK, 3 rows affected (0.00 sec)

数据测试

mysql> select * from orderinfo;

+------+------+----------+-------+

| o_id | u_id | username | money |

+------+------+----------+-------+

| 1 | 1 | HA | 234 |

| 2 | 2 | LB | 146 |

| 3 | 3 | HPC | 256 |

+------+------+----------+-------+

mysql> select id,name,sex,money,o_id from userinfo,orderinfo where id=u_id;

+----+------+-----+-------+------+

| id | name | sex | money | o_id |

+----+------+-----+-------+------+

| 1 | HA | 1 | 234 | 1 |

| 2 | LB | 2 | 146 | 2 |

| 3 | HPC | 1 | 256 | 3 |

+----+------+-----+-------+------+

# 级联删除

mysql> delete from userinfo where id=1; #删除数据

Query OK, 1 row affected (0.00 sec)

mysql> select * from orderinfo; # 查看级联表

+------+------+----------+-------+

| o_id | u_id | username | money |

+------+------+----------+-------+

| 2 | 2 | LB | 146 |

| 3 | 3 | HPC | 256 |

+------+------+----------+-------+

# 级联更新

mysql> update userinfo set id=6 where id=2;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from userinfo;

+----+------+-----+

| id | name | sex |

+----+------+-----+

| 3 | HPC | 1 |

| 6 | LB | 2 |

+----+------+-----+

# 测试数据完整性

insert into orderinfo (u_id,username,money)values(5,'Find',346); # 报错此时无u_id=5的用户

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test1`.`orderinfo`, CONSTRAINT `orderinfo_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `userinfo` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

mysql> insert into userinfo values(5,'Find',1);

Query OK, 1 row affected (0.04 sec)

mysql> insert into orderinfo (u_id,username,money)values(5,'Find',346);

Query OK, 1 row affected (0.00 sec)

mysql> select * from orderinfo;

+------+------+----------+-------+

| o_id | u_id | username | money |

+------+------+----------+-------+

| 2 | 6 | LB | 146 |

| 3 | 3 | HPC | 256 |

| 7 | 5 | Find | 346 |

+------+------+----------+-------+

索引

作用

索引是一种特殊的文件( InnoDB 数据表上的索引是表空间的一个组成部分)

它们包含着对数据表里所有记录的引用指针

优缺点

优点

加快查询速度 增加查询效率

缺点

索引需要单独的文件来存放索引 如果索引量比较大占用存储空间

索引与数据库中的数据相互对应 如果数据量较大 当有数据增加的时候 索引需要同步更新 降低效率

普通索引

作用

最基础的索引 只是用来加快查询速度

其不具备唯一性

普通索引创建

# 使用index或者key指定索引字段

# 索引名称可以添加也可以省略 如果省略默认以字段名字作为索引名称

mysql> create table test4(id int,name varchar(254),index(id));

mysql> desc test4;

+-------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+-------+

| id | int(11) | YES | MUL | NULL | |

| name | varchar(254) | YES | | NULL | |

+-------+--------------+------+-----+---------+-------+

mysql> show create table test4;

+-------+--------------------------------------------------------------------------------------------------------------------------------------------------+

| Table | Create Table |

+-------+--------------------------------------------------------------------------------------------------------------------------------------------------+

| test4 | CREATE TABLE `test4` (

`id` int(11) DEFAULT NULL,

`name` varchar(254) DEFAULT NULL,

KEY `id` (`id`) # 索引名称

) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

+-------+--------------------------------------------------------------------------------------------------------------------------------------------------+

mysql> create table test4(id int,name varchar(254),index name_index(name)); # 指定索引名称index_name

mysql> show create table test5;

+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------+

| Table | Create Table |

+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------+

| test5 | CREATE TABLE `test5` (

`id` int(11) DEFAULT NULL,

`name` varchar(254) DEFAULT NULL,

KEY `name_index` (`name`) # 指定索引名称

) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------+

key为MUL表示普通索引 该列值可以重复

该列是一个非唯一索引的前导列(第一列)或者是一个唯一性索引的组成部分但是可以含有空值 NULL

索引删除与添加

mysql> alter table test5 drop key name_index;

mysql> desc test5;

+-------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+-------+

| id | int(11) | YES | | NULL | |

| name | varchar(254) | YES | | NULL | | # 无索引字段

+-------+--------------+------+-----+---------+-------+

mysql> alter table test5 add key name_index(name);

mysql> desc test5;

+-------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+-------+

| id | int(11) | YES | | NULL | |

| name | varchar(254) | YES | MUL | NULL | | # 添加成功

+-------+--------------+------+-----+---------+-------+

唯一索引

作用

其与普通索引类似

但是在索引列所在的字段中插入的数据值必须唯一

唯一性索引允许有空值允许为null

唯一索引创建

mysql> create table test6(id int auto_increment primary key,name varchar(254), unique index(name));

mysql> desc test6;

+-------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| name | varchar(254) | YES | UNI | NULL | |

+-------+--------------+------+-----+---------+----------------+

mysql> insert into test6 values(1,'SR');

mysql> insert into test6 values(2,null);

mysql> insert into test6 values(3,'SR'); # 报错含有重复值

ERROR 1062 (23000): Duplicate entry 'SR' for key 'name'

唯一索引添加与删除

mysql> alter table test6 drop index name;

Query OK, 0 rows affected (0.05 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> desc test6;

+-------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| name | varchar(254) | YES | | NULL | |

+-------+--------------+------+-----+---------+----------------+

2 rows in set (0.00 sec)

mysql> alter table test6 add unique index(name);

Query OK, 0 rows affected (0.06 sec)

Records: 0 Duplicates: 0 Warnings: 0

主键索引

作用

使用主键索引查询速度最快

主键索引所在的字段数据必须唯一

主键索引不许为空

主键索引创建

mysql> create table test7(id int auto_increment not null, name varchar(254),primary key (id));

Query OK, 0 rows affected (0.06 sec)

mysql> desc test7;

+-------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| name | varchar(254) | YES | | NULL | |

+-------+--------------+------+-----+---------+----------------+

2 rows in set (0.00 sec)

mysql> insert into test7 values('','SR'); # 数据不能为空

ERROR 1366 (HY000): Incorrect integer value: '' for column 'id' at row 1

mysql>

mysql> insert into test7 values(1,'SR');

Query OK, 1 row affected (0.00 sec)

mysql> insert into test7 values(1,'SR');

ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

主键索引删除与添加

# 不建议当有生产数据的时候在来创建主键索引 因为此时有数据 无法保证数据唯一 如果不唯一则无法创建主键索引

alter table test7 drop primary key ; # 此时报错的原因因为自增长

ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

mysql> alter table test7 change id id int not null; # 去掉auto_increment

mysql> alter table test7 drop primary key ; # 删除主键

mysql> alter table test7 change id id int not null primary key auto_increment;

复合索引

作用

索引可以包含一个、两个或更多个列

两个或更多个列上的索引被称作复合索引

复合索引创建

mysql> create table test8( host varchar(15) not null ,port smallint(4) not null ,access enum('deny','allow') not null, primary key (host,port));

mysql> desc test8;

+--------+----------------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+--------+----------------------+------+-----+---------+-------+

| host | varchar(15) | NO | PRI | NULL | |

| port | smallint(4) | NO | PRI | NULL | |

| access | enum('deny','allow') | NO | | NULL | |

+--------+----------------------+------+-----+---------+-------+

mysql> insert into test8 values('10.96.52.46',22,'deny');

Query OK, 1 row affected (0.00 sec)

mysql> insert into test8 values('10.96.52.46',21,'allow');

Query OK, 1 row affected (0.05 sec)

mysql> insert into test8 values('10.96.52.46',21,'allow'); # 数据重复

ERROR 1062 (23000): Duplicate entry '10.96.52.46-21' for key 'PRIMARY'

全文索引

作用

全文索引( 也称全文检索) 是目前搜索引擎使用的一种关键技术。它能够利用「分词技术「等多种算法智能分析出文本文字中关键字词的频率及重要性,然后按照一定的算法规则智能地筛选出我们索结果。

MySQL 在数据量较大的情况下,高并发连接的情况下。select 语句 where bName like '%网%'使用% _ 通配符,不通过索引,直接全表扫描。ABSUWU LIKE ‘%U_U’数据库压力大。

MySQL 的解决方案:全文索引: 3.2 开始支持全文索引。 无法正确支持中文。从 MySQL 5.7.6 开始 MySQL 内置了 ngram 全文检索插件,用来支持中文分词

创建

# 全文索引字段必须是varchar text

# 存储引擎必须是myisam

# mysql自带的全文搜索引擎只能作用于myisam存储引擎

mysql> create table test10 (id int,article text, fulltext key(article)) engine=myisam;

Query OK, 0 rows affected (0.01 sec)

mysql> show index from test10\G;

*************************** 1. row ***************************

Table: test10

Non_unique: 1

Key_name: article

Seq_in_index: 1

Column_name: article

Collation: NULL

Cardinality: NULL

Sub_part: NULL

Packed: NULL

Null: YES

Index_type: FULLTEXT # 全文引擎

Comment:

Index_comment:

1 row in set (0.00 sec)



推荐阅读
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
果丽珍
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有