约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性
mysql 常见的额外约束条件有4 类6项
create table 表名(字段1 数值类型 约束条件, 字段2 数据类型 约束条件);
eg: create table class(id int not null , name char(20) not null ); #设置id 字段和 name 字段值 允许为null
alter table 表名 change 旧的表字段 新的表字段 数据类型 约束条件
eg: alter table class change id id int null; #修改id 字段值 允许为null
当新旧表字段,值类型相同时,就是对约束条件的操作。
旧字段没有约束条件,如果值类型后面加了约束条件,则是为该字段添加约束条件
旧字段有约束条件,如果值类型后面跟了新的约束条件,则是为该字段修改约束条件
旧字段有约束条件,如果值类型后面没有加约束条件,则是为该字段删除约束条件
alter table 表名 modify 表字段 数据类型 约束条件
eg alter table class modify name char(20) null; #修改name 字段值 允许为null
此项有两个值 null 和 not null ,默认是null 。但是当字段为空时,数据无法参与运算。
非空约束(not null ) 确保当前列的值不为空值。
所有类型的值都可以时null,包括int,float 等数据类型
当复制时,单引号'' 或双引号"" 里什么都没有时,此时表示是0个字符,而不是null,因为nul表示没有赋值
create table class(id int , student char(20) not null)
(注意,当存在表记录时,修改为not null 的字段的值不可以存在空值)
alter table class change id id int not null ;
#将 id 字段的not null 改回null alter table class change id id int ;
#向 class 表的 student 字段添加值 'zhangsan‘ ,id 字段不进行赋值,则默认为null insert into class(student) value('zhangsan'); select * from class;
#向class 表中添加表记录,但是只给id字段赋值,不给student字段赋值,则添加失败。 insert into class(id) value(1);
#向class 表中插入表记录,id字段赋值为2 #student字段值虽然单引号’‘里什么都没有,但是代表的是0字符,而不是null。因为null表示的是没有进行赋值 insert into class value( 2,'');
唯一约束是指定table的列或列组合不能重复,保证数据的唯一性。
唯一约束不允许出现重复的值,但是可以为多个null。
同一个表可以有多个唯一约束,多个列组合的约束。
在创建唯一约束时,如果不给唯一约束名称,就默认和列名相同。
唯一约束不仅可以在一个表内创建,而且可以同时多表创建组合唯一约束。
方法一:在设置字段名和数据属性时,就添加唯一索引
create table 表名(字段名1 数据类型1 约束条件,....)
;
#创建class 表,将id 字段和 id_card 字段 值设置为unique唯一性约束,不允许字段值重复 create table class1(id int unique,name char(20),id_card bigint unique);
方法二: 在设置完字段名和属性后,在最后在添加唯索引项
create table 表名(字段名1 数据类型1,字段名2 数据类型2,unique(字段名1,字段名2...));
create table class2(id int ,name char(20), unique(id)); #将id 字段设置为unqiue。 #如果想象设置多个,unique() 括号中填写过个字段名,以逗号分隔。如unique(id,name)
方法一
create unique index 索引名 on 表名(列名);
#为class 表的id 字段创建唯一键 create unique index class_id_UNI on class(id);
方法二
alter table 表名 add unique 索引名(列名)
#为class表name 字段创建唯一键 alter table class add unique class_name_UNI(name);
方法三
通过修改字段属性或者修改字段名。来添加或者修改约束类型
alter table class modify 字段 值类型 unique;
alter table 表名 change 字段 字段 值类型 unique
#为 class表的 score 字段 添加约束类型 alter table class modify score int unique; 或者 alter table class change score score int unique;
alter table 表名 drop index 唯一键名;
#查看表的详细信息。得到唯一键名为 id show create table class; #删除名为id的唯一键 alter table class drop index id
主键约束相当于 唯一约束 + 非空约束 的组合,主键约束列不允许重复,也不允许出现空值。
每个表最多只允许一个主键,建立主键约束可以在列级别创建,也可以在表级别创建。
当创建主键的约束时,系统默认会在所在的列和列组合上建立对应的唯一索引。
主键约束(主键索引)与创建唯一性约束的方法相同
create table class2(id int primary key,card_id bigint,name char(20)); create table class3(id int,card_id bigint,name char(20),primary key(id));
#为class 表的id 字段创建主键 alter table class add primary key(id); 或者 alter table class modify id int primary key; 或者 alter table class change id id int primary key;
alter table 表名 drop primary key;
(1) 当字段只有主键约束,没有其他约束时,可以直接删除主键
#当字段没有其他约束时,可以直接删除主键 alter table class1 drop primary key;
(2) 当字段有其他约束时,先删除其他约束,在删除主键
#先通过修改表字段属性,删除自增约束 alter table class modify id int ; #再删除id 字段的主键约束 alter table class drop primary key;
外键约束是用来加强两个表(主表和从表)的一列或多列数据之间的连接的,可以保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。
创建外键约束的顺序是先定义主表的主键,然后定义从表的外键。也就是说只有主表的主键才能被从表用来作为外键使用,被约束的从表中的列可以不是主键,主表限制了从表更新和插入的操作。
主表和从表关联的字段要具有相同的数据类型,字符长度,参数类型
只有当主表中主键字段存在某个数值,从表的才可以添加相应的表记录
主表删除时表记录时,如果该项数值在从表中被使用,则需要先将从表中的占用删除,才可以在主表中删除相应的表记录
create table 表名(字段名列表, foreign key(字段名) references 表名(字段名)on update cascade on delete cascade)engin=innodb;
foreign key(字段名):设置从表的外键字段
references 表名(字段名) :设置关联的主表的主键字段
on update cascade : 同步更新,主表字段跟新,从表也相应的更新
on delete cascade: 同步删除,当主表的记录删除,则从表引用该字段的表记录也自动删除
engin=innodb: 设置表的存储引擎为innodb,如果默认引擎时innodb,可以省略此项
#创建表project,并设置 id 字段为 主键 create table project(id int primary key,subject char(30)); #向project 表插入3条记录 insert into project(id,subject) -> values -> (1,'chinese'), -> (2,'math'), -> (3,'English');
#创建表class,设置id 字段为主键,设置fail 字段为外键,关联到project表的id 字段。并且,同步更新,同步删除 create table class -> (id int primary key, -> name char(20), -> fail int, -> foreign key(fail) references project(id) -> on update cascade -> on delete cascade );
#插入记录测试 insert into class values (1,'zhangsan',2); insert into class values (2,'lisi',2); insert into class values (3,'wangwu',3); insert into class values (4,'zhaoliu',4); #此条记录插入失败
#自动同步测试 #主表将id 字段,值为2的表记录更改,将id字段值变为4,查看从表的fail 字段值 update project set id=4 where id=2; select * from class; #自动删除测试 #主表将 id字段为 4 的表记录都删除,查看从表的表记录情况 delete from project where id=4; select * from class;
alter table 外键表名 add [constraint 外键名] foreign key(外键字段) references 主键表(主键表主键字段);
alter table 表名 drop foreign key 外键名
alter table 表名 drop index 索引名
在创建外键约束的同时,也会创建外键索引。想要完全删除外键,需要两个一起删除
(1) 先查看外键名
#查看建表的详细信息 show create table class1; #得到外键名为 class1_ibfk_1
(2)删除外键约束
#删除外键 class1_ibfk_1 alter table class1 drop foreign key class1_ibfk_1; #查看class1表的详细信息 show create table class1;
(3) 删除外键索引
#删除外键索引 id alter table class1 drop index id; #查看表class1 的详细信息 show create table class1;
若在表中定义了默认值约束,用户在插入新的数据行时,如果该行没有指定数据,那么系统将默认值赋给该列,如果我们不设置默认值,系统默认为NULL。
设置默认值的字段,默认值的类型必须和字段的值类型一样
create table 表名(字段名 值类型 default 默认值);
#创建表class,并设置字段 address的默认值为 'not known' create table class(id int ,name char(20) ,address char(40) default 'not known'); #插入表记录,并且不给address 字段赋值 insert into class(id,name) values(1,'zhangsan'); select * from class;
alter table 表名 modify 字段 值类型 default 默认值;
alter table 表名 change 字段 字段 值类型 default 默认值;
这两条命令同时也可以删除默认值。只要将default 后面的默认值设置为NULL即可
#将class 表的name 字段设置默认值为'not known' alter table class modify name char(40) default 'not known'; #将class 表的 id 字段设置默认值为0 alter table class change id id int default '0';
自增约束(AUTO_INCREMENT)可以约束任何一个字段,该字段不一定是PRIMARY KEY字段,也就是说自增的字段并不等于主键字段。
但是PRIMARY_KEY约束的主键字段,一定是自增字段,即PRIMARY_KEY 要与AUTO_INCREMENT一起作用于同一个字段。
当插入第一条记录时,自增字段没有给定一个具体值,可以写成DEFAULT/NULL,那么以后插入字段的时候,该自增字段就是从1开始,没插入一条记录,该自增字段的值增加1。当插入第一条记录时,给自增字段一个具体值,那么以后插入的记录在此自增字段上的值,就在第一条记录该自增字段的值的基础上每次增加1。
自增约束要设置在数值类型为整形的字段上,且字段时主键,外键,唯一键的一种
create table 表名(字段 数值类型 主键或外键或者唯一键 auto_increment);
#设置class 表id 字段为整型,主键,且自增长 create table class(id int primary key auto_increment , name char(20)); #插入记录测试 insert into class(name) values('zhangsan'); insert into class(name) values('lisi');
alter table 表名 modify 字段 int auto_increment;
alter table 表名 change 字段 字段 int auto_increment;
此命令也可以删除字段值自增长。当字段值存在自增长设置时,使用这两条命令时,不跟上auto_increment,即表示删除 字段的自增长设置
#设置 class表的id 字段自增长(id 字段必须已经设置了主键或者外键,或者唯一键,并且时整型) alter table class modify id int auto_increment; 或者 alter table class change id id int auto_incremnet;
索引随可以提升数据库查询的速度,但并不是任何情况下都适合创建索引。因为索引本身会消耗系统资源,在有索引的情况下,数据库会先进行索引查询,然后定位到具体的数据行,如果索引使用不当,反而会增加数据库的负担。
索引有普通索引,唯一索引,主键索引,外键索引,组合索引,全文索引。
唯一键约束就是唯一索引(unique key),
主键索引(primary key),外键索引(foreign key) ,在创建主键约束,外键约束时候,会自动创建
普通索引时最基本的索引类型,没有唯一性之类的限制
方法一: 直接创建索引
create index 索引名 on 表名(列名(length));
(列名(length)): length 是可选项。如果忽略length 值,则使用整个列的值作为索引。如果指定,使用列的前 length 个字符来创建索引,有利于减小索引文件的大小。在不损失精度的情况下,长度越短越好。
索引名:普通索引的索引名建议以 " _index" 为结尾
方法二: 修改表的方式创建
alter table 表名 add index 索引名(列名);
create table 表名(字段名 数据类型 ......, index 索引名(列名);
#创建表的时候,为score 字段设置索引 create table class(id int, name char(30),score int ,index class_score_index(score)); #修改表的方式,为name 字段创建索引 alter table class add index class_name_index(name); #直接为class表id 字段创建索引 create index class_id_index on class(id);
show index form 表名;
#查看表class 的索引 show index from class \G
组合索引(单列索引与多列索引):可以是单列上创建的索引,也可以在多列上创建的索引。需要满足最左原则。因为select 语句的where 条件是依次从左向右执行的,所以在使用select语句查询时,where 条件的使用字段顺序必须和组合索引中的排序一致,否则索引不会生效
create table 表名 (字段名 属主类型 ......, index 索引名(列名1,列名2...));
#创建class 表,并将 id,name,score 字段设置为组合索引 create table class(id int,name char(20),score int, index class_MUL_index(id,name,score));
全文索引(fulltext) 适合在模糊查询时候使用,可以用于一篇文章中检查文本信息。
在mysql 5.6 之前只能用于MyISAM 引擎,5.6 之后,可以用于InnoDB 引擎。
全文索引可以子啊char,varchar 后者text 类型的列上创建。
每个表只允许有一个全文索引
方法一:直接创建全文索引
create fulltext index 索引名 on 表名(列名);
方法二: 创建表时候指定索引
create table 表名(字段名 数据类型 ..... ,fulltext 索引名(字段名));
方法三: 修改表方式创建
alter table 表名 add fulltext 索引名 on 表名(字段名);
create table class(id int,name char(30), -> tel bigint , -> address varchar(50), -> info varchar(100), -> fulltext textindex(info));
select * from 表名 where match(字段名) against('匹配内容');
#插入三条表记录 insert into class values (1,'zhangsan',1010110,'china','this is vip'), -> (2,'lisi',1010110,'china','this is super vip'), -> (3,'wangwu',1010110,'china','this is vvip'); #在clss 表的info 字段,查询匹配 ‘vip’ 的表记录 select * from class where match(info) against('vip');
show index from 表名;
show key from 表名;
show index from class \G
字段 含义
Table :表的名称
Non_unique :如果索引不能包括重复词,则为 0;如果可以,则为 1
Key_name: 索引的名称
Seq_in_index: 索引中的列序号,从 1 开始
Column_name: 列名称
Collation :列以什么方式存储在索引中。在 MySQL 中,有值‘A’(升序)或 NULL(无分类)
Cardinality :索引中唯一值数目的估计值
Sub_part: 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,为 NULL
Packed: 指示关键字如何被压缩。如果没有被压缩,则为 NULL
Null :如果列含有 NULL,则含有 YES。如果没有,则该列含有 NO
Index_type: 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)
Comment: 备注
直接删除索引
drop index 索引名 on 表名;
alter table 表名 drop index 索引名;
删除主键索引
alter table 表名 drop primary key
#查看表的详细信息,获取索引名 show create table class \G #删除索引 drop index textindex on class;