MySQL 第四章索引与完整性约束

4.1 MySQL索引

    在MySQL中,为了更加高效的访问表中记录的内容,引入了索引。数据库的表按照索引排序,这样我们查找索引项描述的内容时先找到索引,然后按照索引即可定位数据库表的内容。

1.索引

    索引是根据表中一列或若干列按照一定顺序建立的列值与记录行之间的对应关系表。在列上创建了索引之后,查找数据时可以直接根据该列上的索引找到对应行的位置,从而快速的找到数据。

2.索引的分类

    索引是储存在文件中的,所以索引也是要占用物理空间的,MySQL将一个表的索引都保存在同一个索引文件中,如果更新表中的一个值或者向表中添加或删除一行,MySQL会自动的更新索引,因此索引树总是和表的内容保持一致。
    索引类型分成下列几个:

  • 普通索引(index):是最基本的索引,没有唯一性之类的限制,创建普通索引的关键字是index
  • 唯一性索引(unique):唯一性索引和普通索引基本相同,但是索引列的所有值都只能出现一次,即必须是唯一的
  • 主键(primary key):主键是唯一性索引。主键一般在创建表的时候指定,也可以通过修改表的方式加入主键,但是每个表只能有一个主键。
  • 全文索引(fulltext):全文索引只能在varchar或text类型的列上创建

3.说明

  • 只有当表类型为MyISAM、InnoDB或BDB时,才可以向有null、blob和text的列中添加索引
  • 一个表最多有16个索引。最大索引长度是256字节
  • 对于char和varchar列,可以索引列的前缀。这样索引的速度更快并且比索引整个列需要较少的磁盘空间。
  • MySQL能在多个列上创建索引。索引可以由最多15个列组成

4.2 MySQL索引创建

1.create index 语句创建

    create index 语句可以在一个已有表上创建索引,一个表可以创建多个索引,其语法如下:

create [unique | fulltext | spatial]
index 索引名 [索引类型] on 表名 (索引列名,....)
[索引选项]...

    索引列名:

列名 [(长度)] [ASC | DESC]

注意:

  • 索引名:索引在一个表中名称必须是唯一的
  • 索引类型:btree和hash。btree为采用二叉树方式,hash为哈希方式。
  • 索引列名:创建索引的列名后的长度表示为该列内容从头开始创建索引字符的个数(例如学号为080212,即可创建索引数目5,只索引到08021)。这可使索引文件大大减少,从而节省磁盘空间,另外还可以规定索引按照升序(ASC)或降序(DESC)排列,默认为ASC。

    如果一个索引列包含多个列,中间用逗号隔开,但他们属于同一个表,这样的索引叫做符合索引。
    create index 语句并不能创建主键

例如:根据xs表的学号列上的前5个字符创建一个升序索引xh_xs

 use xscjcreate index xh_xs on xs (学号(5));

例如:在xs_kc表的学号列和课程号列上建立一个符合索引xskc_in

create index xskc_in
on xs_kc(学号,课程号);

2.在建立表时创建索引

    索引也可以在创建表时一起创建,其语法格式如下:

  create table [if exists] 表名[ ([ 列定义 ],...| 索引定义) ][ 表选项 ] [select 语句]primary key (列名...)

索引定义如下:

primary key [索引类型] (索引列名,....)                        / *主键*/
| {index | key} [索引名] [索引类型]  (索引列名,...)                   / *索引*/
| unique  [索引名] [索引类型]  (索引列名,...)                        / *唯一性索引*/
| fulltext | spatial  [索引名] (索引列名,...)                               / *全文索引*/
| foreign key  [索引名] (索引列名,...)  [参照性定义]                  / *外键*/

注意:

  • key通常时index的同义词,在定义列的时候,可以将某列定义为primary key,但是当主键是由多个列组成的多列索引时,定义列时无法定义此主键,必须在语句最后加上一个primary key(列名,…)子句。
  • constraint[名称]:为主键、unique键、外键定义一个名字。

例如:在mytest数据库中创建成绩(cj)表,学号和课程号的联合主键,并在成绩列上创建索引

 use testcreate table xs_kc1(学号  char(6) not null,课程号 char(3) not null,成绩 tinyint(1),学分 tinyint(1),primary key (学号,课程号),index cj(成绩)
);

注意:使用show index from 表名 查看执行结果

3.alter table 语句创建

    用户使用alter table 语句修改表,其中也包括向表中添加索引,其语法格式如下

alter table 表名
...
add  {index | key} [索引名] [索引类型]  (索引列名,...)                   / *添加索引*/
| add primary key [索引类型] (索引列名,....)                        / *添加主键*/
| add unique  [索引名] [索引类型]  (索引列名,...)                        / *添加唯一性索引*/
| add foreign key  [索引名] (索引列名,...)  [参照性定义]                  / *添加外键*/

例如:在xs表的姓名列上创建一个非唯一的索引

create index xs_xm
on xs(姓名);
alter table xs
add index xs_xm using btree (姓名);

4.删除索引

    当一个索引不在被需要时,可以用drop index 语句或者alter table语句删除
(1)使用drop index 删除

  drop index 索引名 on 表名

(2)使用alter table 删除

  alter table 表名...| drop index 索引名                                       / *删除索引*/| drop primary key                               / *删除主键*/| drop foreign key fk_symbol                / *删除外键*/

例如:删除xs表上的mark索引。

  alter table xsdrop mark

4.3 MySQL数据完整性约束

    MySQL为防止不符合规范的数据进入数据库,MySQL系统自动按照一定的完整性约束条件对用户输入的数据进行检测,一旦定义了完整性约束,MySQL就会负责在每次更新时,测试新的数据内容是否符合相关的约束。

4.3.1 主键约束

    主键就是表中的一列或多个列的一组,其值能够唯一标识表中的每一行。

(1)通过定义primary key约束来创建主键,而且primary key约束中的列不能取空值。
(2)当为表定义primary key约束时,MySQL为主键列创建唯一性索引,实现数据的唯一性
(3)在查询中使用主键时,该索引可用来对数据进行快速访问
(4)如果primary key 约束是由多列组合定义的,则某一列的值可以重复使用,但primary key约束定义中所有列的组合值必须是唯一的。

可以用两种方式定义主键,作为列或表的完整性约束。

(1)作为列的完整性约束,只需在列定义的时候加上关键字primary key
(2)作为表的完整性约束,需要在语句最后加上一条primary key (列,…)子句

例如:创建表xs1,将姓名定义为主键

create table xs1
(
学号  varchar(6)   null,
姓名  varchar (8) not null primary key,
出生日期  datetime
);

    当表中的主键为复合主键时,只能定义为表的完整性

例如:创建course表来记录每门课程的学生学号、姓名、课程号、学分和毕业日期。其中学号、课程号和毕业日期构成复合主键。

 create table course(学号   varchar(6)   not null,姓名   varchar(8)  not null,课程号  varchar(3)  not null,毕业日期   date  not null,学分    tinyint,primary key (学号,课程号,毕业日期) );

    MySQL通常会自动为主键创建一个索引,索引名为primary。然而,可以重新给这个索引取名字,
例如:创建course 表,把主键创建的索引名命名为index_course

create table course
(
学号   varchar(6)   not null,
姓名   varchar(8)  not null,
课程号  varchar(3)  not null,
毕业日期   date  not null,
学分    tinyint,
primary key  index_course(学号,课程号,毕业日期)
);

4.3.2 替代键约束

    替代键像主键一样,是表的一列或者多列,他们的值在任何时候都是唯一的。替代键是没有被选作主键的候选键,定义替代键的关键字为unique
例如:在表xs1中将姓名列定义为一个替代键(列的完整性约束)

create table xs1
(
学号   varchar(6)   not null,
姓名   varchar(8)  not null  unique,
课程号  varchar(3)  not null,
毕业日期   date  not null,
学分    tinyint,
primary key  index_course(学号,课程号,毕业日期)
);

替代键还可以定义为表的完整性约束,

create table xs1
(
学号   varchar(6)   not null,
姓名   varchar(8)  not null ,
课程号  varchar(3)  not null,
毕业日期   date  not null,
学分    tinyint,
primary key  index_course(学号,课程号,毕业日期),
unique (姓名)
);

注意:在MySQL中,替代键和主键的区别主要有以下几点

  1. 一个数据表只能创建一个主键,但一个表可以有若干个替代键,并且他们甚至可以重合,例如在C1和C2列上定义了一个替代键,并且在C2和C3列上定义了另一个替代键。这种情况是被允许的。
  2. 主键字段的值不允许为null,而替代键unique字段的值可以为null,但是必须使用null或not null 声明
    (在mysql中unique约束列可以含有多个null!,不违背唯一性定理,每一个null都视为不同值)
  3. 一般创建primary key约束时,系统会自动产生primary key索引,创建unique约束时,也会自动生成unique索引

4.3.3 参照完整性约束

    xs_kc表中所有学号必须同时储存于xs表的学号列。
    xs_kc表中所有课程号必须同时储存于kc表的课程号列。
这种类型的关系就是”参照完整性“。参照完整性约束是一种特殊的完整性约束,表现为一个外键。所以xs_kc表中的学号列和课程号列都可以定义为一个外键。可以在创建表或修改表时定义一个外键声明。其格式如下:

  create table 表名[([列定义],....| [索引定义] ) ]primary key [索引类型] (索引列名,...)                     / *定义主键*/...| foreign key [索引名] (索引列名,...) [参照性定义]             / *定义外键*/
references 表名 [ ( 索引列名.. ) ]
[on delete {restrict | cascade | set null | no action }]
[on update {restrict | cascade | set null | no action }]
  • foreign key:称为外键,被定义为表的完整性约束
  • references:称为参照性,定义中包含了外键所参照的表和列。这里表名叫做被参照表,而外键所在的表叫做参照表
  • on delete | on update:可以为每个外键定义参照动作

    参照动作包括两个部分:
    第一部分:指定参照动作应用那一条语句,即update和delete
    第二部分:指定采取那个动作,可能采取的动作是 restrict | cascade | set null | no action

    接下来说明这些动作的含义:

  • restrict:当要删除或更新父表中被参照列上在外键中出现的值时,拒绝对父表的删除或更新操作
  • cascade:如果字表引用父表的某个字段的值,那么不允许直接删除父表的该值,如果你要同时删除父表和依赖表中的行,则要先删除依赖表中的行。
  • set null:当从父表删除或更新行时,设置子表中与之对应的外键列为null。前提是子表中外键列没有指定not null
  • no action:意味着不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新父表中主要键值的企图不被允许和restrict一样(基本上和restrict区别不大)

例如:创建xs1表,所有的xs表中学生学号都必须出现在xs1表中,假设已经使用学号列作为主键创建了xs表

 create table xs1(学号   varchar(6)   not null,姓名   varchar(8)  not null ,课程号  varchar(3)  not null,毕业日期   date  not null,学分    tinyint,primary key  (学号), foreign key (学号),references xs(学号)on delete restricton update restrict);

即MySQL将会保证xs1表中的学号列内容总是xs表中学号列的内容的一个子集。

当指定一个外键时需要注意:

  • 被参照表必须已经用一条create table 语句创建了,或者必须时当前正在创建的表(参照表是本身即自参照)
  • 必须为被参照表定义主键
  • 必须在被参照表的表名后面指定列名(可以多个),这个列(多个列)必须是这个表的主键或替代键。(外键必须是被参照表的主键或替代键)
  • 尽管主键是不能包含空值的,但允许外键中出现一个空值。这意味着,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的
  • 外键中的列的数目必须和被参照表的主键(替代键)中的列的数目相同
  • 外键中的列的数据类型必须和被参照表的主键(替代键)中列的数据类型对应相等

自参照完整性例如:

create table xs2
(
学号 varchar(6) not null,
姓名 varchar(8) not null,
出生日期 datetime null,
primary key (学号),
foreign key (学号)
references xs1(学号)
);

例如创建带有参照动作CASCADE的xs1表

 create table xs1(学号   varchar(6)   not null,姓名   varchar(8)  not null ,毕业日期   date  not null,primary key  (学号), foreign key (学号),references xs(学号)on delete cascadeon update cascade);

4.3.4 check完整性约束

    主键、替代键、外键都是常见的完整性约束的例子,但是每个数据库还有一些专用的完整性约束。例如,kc表中星期数要在1-7之间,xs表中出生日期必须晚于1990年1月1日。这样的规则可以用check完整性约束来指定。

    check完整性约束在创建表的时候定义,可以定义为列完整性约束,也可以定义为表完整性约束,其语法格式如下

check(expr)

    注:expr是一个表达式,需要指定检查的条件,在更新表数据时,MySQL会检查更新后的数据行是否满足check的条件。
例如:创建表student,只包括学号和性别两列,性别只能是男或女

create table student
(
学号  varchar(6)  not null,
性别  char(1) not null,
check (性别 in ('男','女'))
);

    这里的check为列完整性约束

会报错!

ERROR 1054 (42S22): Unknown column '鎬у埆' in 'check constraint student_chk_1 expression'

目前还不知道如何更改,所以把check的列名换成英文名吧。

例如:创建表student1,只包括学号和出生日期两列,出生日期必须晚于1990年1月1日

create table student1
(
学号  varchar(6)  not null,
brith   date not null
check (brith>'1990-01-01')
);

例如:可以在条件中加入子查询
创建表student2,只包括学号和性别两列,并且确认性别列中的所有值必须都来源于student表的性别列

create table student2
(
学号 char(6)  not null,
sex  char(1) not null
check (sex in select sex from student)
);

如果指定完整性约束中,要相互比较一个表中的两个或多个列,那么必须定义表完整性约束
例如:创建表student3,有学号、最好成绩和平均成绩3列,要求最好成绩必须大于平均成绩。

create table student3
(
学号 char(6) not null,
最好成绩 int(1) not null,
平均成绩 int(1) not null,
check (最好成绩>平均成绩)
);

问题1:int char等后面的()里面的数字到底是什么意思
问题2:解决check中文列名乱码问题

4.3.5 check完整性约束

    如果一条insert、update或delete语句违反了完整性约束,则MySQL返回一条出错消息并且拒绝更新,一个更新可能会导致多个完整性约束的违反,在这种情况下,应用程序获取几条出错消息为了确切表示出是违背了那一条完整性约束,可以为每个完整性约束分配一个名字,随后,出错消息包含这个名字,从而使得消息对应用程序有意义。

constraint [完整性约束的名字]

完整性约束的名字在完整性约束的前面被定义,在这个数据库内这个名字必须是唯一的。如果它没有被给出,则MySQL会自动创建这个名字。只能给表完整性约束指定名字,无法给列完整性约束指定名字。
例如:创建与例4.8相同的xs1表,并为主键命名

create table xs1
(
学号  varchar(6)   null,
姓名  varchar (8) not null ,
出生日期  datetime
constraint primary_key_xs1 primary key(学号)
);

4.3.6 删除完整性约束

    如果使用drop table语句删除一个表则所有完整性约束都被删除了,被参照表的所有外键也删除了,使用alter table语句,完整性可以被单独的删除
例如:删除xs1表的主键

  alter table xs1drop primary key;

MySQL 第四章索引与完整性约束相关推荐

  1. mysql的四种索引类型

    ​一.索引的类型​ mysql索引的四种类型:​​主键索引​​​.​​唯一索引​​​.​​普通索引​​​和​​全文索引​​​.通过给字段​​添加索引​​​可以​​提高数据的读取速度​​​,提高项目的并 ...

  2. mysql第四章分页显示查询出租房屋信息_MYSQL必知必会读书笔记第四章之检索数据...

    MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理. 使用Select语句返回的数据,可能会发现显 ...

  3. mysql第四章思考与练习答案_Mysql课后思考题

    1.请简述数据库.表和数据库服务器之间的关系? 知识点数据库存储结构 一个数据库服务器可以管理多个数据库,通常情况下开发人员会针对每个应用创建一个数据库,为保存应用中实体的数据,会在数据库中创建多个表 ...

  4. mysql 第10章 索引

    2015-10-24 目录 参考资料 [1] 唐汉明.深入浅出MySQL 数据库开发.优化与管理维护(第2版)[M].北京:人民邮电出版社,2014 [2] Schwartz.高性能MySQL(第3版 ...

  5. MYSQL数据库四种索引类型的简单使用

    MYSQL数据库索引类型包括普通索引,唯一索引,主键索引与组合索引,这里对这些索引的做一些简单描述: (1)普通索引 这是最基本的MySQL数据库索引,它没有任何限制.它有以下几种创建方式: 创建索引 ...

  6. mysql第四章_MySQL必知必会--第二章~第四章--MySQL简介

    1.DBMS可分为两类:一类为基于共享文件系统的DBMS,另一类为基于客户机-服务器的DBMS.服务器部分是 负责所有数据访问和处理的一个软件.这个软件运行在称为数据库服务 器的计算机上. 2.MyS ...

  7. mysql第四章表单查询样题_查询mysql表单中前10条,然后在li中循环输出。

    $mysql_servername = "localhost"; $mysql_username = "root"; $mysql_password =&quo ...

  8. mysql索引和数据完整性答案_第5章MySQL索引与完整性约束.ppt

    第5章MySQL索引与完整性约束 5.3.4 CHECK完整性约束 CHECK完整性约束在创建表的时候定义.可以定义为列完整性约束,也可定义为表完整性约束. 语法格式: CHECK(expr) [例5 ...

  9. 【实施工程师之家】——mysql四种索引PRIMARY(主键索引)、INDEX(一般索引)、UNIQUE(非空索引)、FULLTEXT(全文索引)应用

    mysql四种索引PRIMARY(主键索引).INDEX(一般索引).UNIQUE(非空索引).FULLTEXT(全文索引)应用 目录 1)PRIMARY: 2)NORMAL: 3)UNIQUE: 4 ...

最新文章

  1. php中的装饰,详解PHP装饰模式的示例代码
  2. 利用FluidMoveBehavior制作出手机通讯录平滑的效果
  3. displaytag 相关
  4. 人人都是 DBA(XI)I/O 信息收集脚本汇编(转)
  5. Ubuntu 16.04 安装Go 1.9.2
  6. 机器学习Scikit-Learn安装
  7. JAVA总结实录01 : 异常处理 try-catch-finally
  8. WinForm sender初级应用
  9. 17.词法分析和语法分析
  10. Red Hat 4.4.7 安装 Mysql 5.7
  11. 基于PaddlePaddle的OCR识别,识别车牌号
  12. 350网店模板一键安装模版与淘宝传统装修的对比
  13. 使用eclipse打包app以及AndroidStudio和Eclipse中app签名修改等问题(SH1和MD5)
  14. windows 下安装securecrt 绿色版
  15. (精)广东工业大学 2018实时大数据分析——A-Priori算法实验报告
  16. 第十六周项目3函数指针调用函数 吃饭睡觉打豆豆
  17. 蓝牙BQB 认证流程
  18. 基于ASP.NET的电商系统的设计与实现
  19. 英特尔发布Xeon D-1600处理器:10nm工艺 性能提升40%
  20. 浙大与北大计算机考研分数线,2017浙大考研复试分数线及相关问题

热门文章

  1. 围棋口诀两百句(转)
  2. 一个资深程序员成功的背后
  3. 手机屏幕投到Windows系统
  4. 光纤收发器的原理及应用_光纤收发器的工作原理 光纤收发器的作用介绍
  5. DockerK8s---跟我一步步部署K8s(二进制安装部署)
  6. 【3dsmax新手入门】-实体立方八面晶体绘制
  7. java玫瑰花代码_js html5渲染的3D玫瑰花(程序员的情人节礼物)
  8. 基于Python Django Mysql 开发的宠物用品商城
  9. stm32(声音传感器控制LED)
  10. Docker 1 - 概述