字段约束
not null: 非空约束,指定某列不为空
null: 空约束,指定某列为空,默认会取第一字符
unique: 唯一约束,指定某列和几列组合的数据不能重复
primary key: 主键约束,指定某列的数据不能重复、唯一
foreign key: 外键,指定该列记录属于主表中的一条记录,参照另一条数据(其实就是表太大的拆表)
check: 检查,指定一个表达式,用于检验指定数据
default_value: 为列指定默认值。如果没有为列指定默认值,mysql> 自动地分配一个。如果列可以取NULL作为值,缺省值是NULL。
如果列被声明为NOT NULL,缺省值取决于列类型的value值
auto_increment: 自增模式,设置自增后在插入数据的时候就不需要给该列插入值了。
不支持check约束,但可以使用check约束,而没有任何效果;
单列约束:每个约束只约束一列
多列约束:每个约束约束多列数据
1. 对一个数据列建立的约束,称为列级约束《实际开发中多用》
2. 对多个数据列建立的约束,称为表级约束
3. 列级约束既可以在列定义时声明,也可以在列定义后声明
4. 表级约束只能在列定义后声明。
非空约束用于确保当前列的值不为空值,非空约束只能出现在表对象的列上。
Null类型特征:
所有的类型的值都可以是null,包括int、float等数据类型
空字符串是不等于null,0也不等于null
语法:
字段 数据类型 not null
举例:
create table temp(
id int not null,
name varchar(2) not null default 'abc',
sex char null
);
ERROR 1067 (42000): Invalid default value for 'name'
报错,default值取错了,只能为2个字符
注意:default value值取决于字段类型的value,这里varchar定为2,所以default数只能输入2个字符,同时也限定了name字段的字符个数
在操作一次
create table t(
id int not null,
name varchar(2) not null default 'ab',
sex char null
);
| id | int(11) | NO | | NULL | |
| name| varchar(3)| NO | | abc | |
3 rows in set (0.00 sec)
mysql> insert into t values(1234,'df,'f')
1 row in set (0.00 sec)
查看记录只录入了df
上面的table加上了非空约束,也可以用alter来修改或增加非空约束
增加非空约束
mysql> alter table temp modify sex varchar(2) not null;
| id | int(11) | NO | | NULL | |
| name | varchar(255) | NO | | abc | |
取消非空约束
mysql> alter table temp modify sex varchar(2) null;
| id | int(11) | NO | | NULL | |
| name | varchar(255) | NO | | abc | |
3 rows in set (0.00 sec)
取消非空约束,增加默认值
mysql> alter table temp modify sex varchar(2) default ab null;
唯一约束是指定table的列或列组合不能重复,保证数据的唯一性。虽然唯一约束不允许出现重复的值,但是可以为多个null
同一个表可以有多个唯一约束,多个列组合的约束。在创建唯一约束的时候,如果不给唯一约束名称,就默认和列名相同。
语法:
constraint 约束名 unique(列1,列2,...)
举例:
create table t200(id int,name varchar(25),password varchar(16),constraint np_cu unique(name,password));
语法:
1. 列(长度) 数据类型 unique
2. unique(列1,列2,...)
举例:
create table temp(id int,name varchar(25),password varchar(16) unique);
create table t1(id int,name varchar(25),password varchar(16),unique(password));
语法:
alter table 表名 add unique(列1,列2,...);
alter table 表名 modify 列 数据类型 unique;
举例:
alter table temp add unique(name, password);
alter table temp modify name varchar(25) unique;
语法:
alter table 语法 drop index 列;
举例:
alter table temp drop index name;
会给唯一约束的列上默认创建一个唯一索引;
create table temp (
id int not null,
name varchar(25),
password varchar(16),
--使用表级约束语法,
constraint uk_name_pwd unique(name, password)
);
表示用户名和密码组合不能重复
constraint是约束把name与password设置成主键约束,并且约束名为uk_name_pwd
用户名与密码都只能是唯一,在添加记录会提示不能添加
create table baidu(id int not null,
name varchar(5) unique,
password varchar(16) unique);
| id | int(11) | NO | | NULL | |
| name | varchar(5) | YES | UNI | NULL | |
3 rows in set (0.00 sec)
mysql> insert into baidu values(1,'wang','wang');
1 row in set (0.00 sec)
加添加一次同样名就不让了
mysql> insert into baidu values(2,'wang','wang');
ERROR 1062 (23000): Duplicate entry 'wang' for key 'name'
mysql> insert into sina values(2,'aaa','ttt');
| 1 | wang | wang |
2 rows in set (0.00 sec)
unique(会添加到key里)表示记录不能重复,比如下面添加一个mike帐号,再添加一个相同的记录就会报错。就跟申请邮箱时一样,名字不能重复。
mysql> insert into t9 values('mike','[email protected]');
mysql> insert into t9 values('mike','[email protected]');
ERROR 1062 (23000): Duplicate entry '[email protected]' for key 'email'
mysql> alter table t9 drop index email; 删除索引unique(删除key里的unique)
主键约束相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值;如果的多列组合的主键约束,
那么这些列都不允许为空值,并且组合的值不允许重复。
每个表最多只允许一个主键,建立主键约束可以在列级别创建,也可以在表级别上创建。mysql的主键名总是PRIMARY,
当创建主键约束时,系统默认会在所在的列和列组合上建立对应的唯一索引。
语法:
1. 列 数据类型 primary key
2. primary key (列1,列2,...);
列模式:
mysql> create table jing(id int primary key,name varchar(25));
| id | int(11) | NO | PRI | NULL | |
2 rows in set (0.00 sec)
mysql> insert into jing values(1,'wang');
在添加一条id记录,就提示了设置了PRIMARY,不能重复
mysql> insert into jing values(1,'wang');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
这一次添加id记录为2,就可以了
mysql> insert into jing values(2,'wang');
| 1 | wang |
2 rows in set (0.00 sec)
create table temp(
/*主键约束*/
id int primary key,
name varchar(25)
);
create table temp2(
id int not null,
name varchar(25),
pwd varchar(15),
constraint pk_temp_id primary key(id)
);
constraint是约束把id设置成主键约束,并且约束名为pk_temp_id
组合模式:
create table temp2(
id int not null,
name varchar(25),
pwd varchar(15),
constraint pk_temp_id primary key(name, pwd)
);
alter删除主键约束
语法:
alter table 表 drop primary key;
举例:
alter table temp drop primary key;
alter添加主键
语法:
alter table 表 add primary key(列1,列2,...);
举例:
alter table temp add primary key(name, pwd);
alter修改列为主键
语法:
alter table 表 modify 列 数据类型 primary key;
举例:
alter table temp modify id int primary key;
语法:
列 数据类型 auto_increment
create table bei(
id int auto_increment primary key,
name varchar(20),
pwd varchar(16)
);
auto_increment自增模式,设置自增后在插入数据的时候就不需要给该列插入值了。
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| pwd | varchar(16) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
添加id记录为空值
mysql> insert into bei values('','wang','ping');
Query OK, 1 row affected, 1 warning (0.00 sec)
1 row in set (0.00 sec)
在添加id记录为空值,这次就为2了,就是因为设置了auto_increment自增模式
mysql> insert into bei values('','wang','ping');
Query OK, 1 row affected, 1 warning (0.00 sec)
| 1 | wang | ping |
2 rows in set (0.00 sec)
1. 外键简单讲就是拆表,把大表拆成小表,在通过相同列值来保持两张的唯一性
你肯定会问为什么会拆表?
答:就是一张表不能过多字段,分两张表来存储,那么两张还都需要相同的列值来约束每条记录的唯一性
你又会问为什么不能有过多字段?
答:一张表字段过多会造成查询速度缓慢。
2. 外键其实就是一张表参照另一张表的相同的列,通过主表的列值来保持从表的记录唯一性,所以(从表关联列值)与(主表关联列值)必须相同,如果(父表)没有相关的记录,(子表)不能插入
1. 用于约束(两张表)或(多张表)记录的对应关系
2. 增加(子表)记录时,是否与(父表)记录相对应
注意:外键约束的参照列,在主表中引用的只能是主键或唯一键约束的列,假定引用的主表列不是唯一的记录,那么从表引用的数据就不确定记录的位置。同一个表可以有多个外键约束。
MySQL有两种常用的引擎类型:MyISAM和InnoDB。目前只有InnoDB引擎类型支持外键约束。
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION
1. 两张表必须都是InnoDB表,并且它们没有临时表。
2. 建立外键关系的对应列必须具有相似的InnoDB内部数据类型。
3. 建立外键关系的对应列必须建立了索引。
4. 假如显式的给出了CONSTRAINT symbol,那symbol在数据库中必须是唯一的。假如没有显式的给出,InnoDB会自动的创建。
如果子表试图创建一个在父表中不存在的外键值,InnoDB会拒绝任何INSERT或UPDATE操作。
如果父表试图UPDATE或者DELETE任何子表中存在或匹配外键值,最终动作取决于外键约束定
义中的ON UPDATE和ON DELETE选项。InnoDB支持5种不同的动作,如果没有指定ON DELETE或
者ON UPDATE,默认的动作为RESTRICT:
1. CASCADE: 从父表中删除或更新对应的行,同时自动的删除或更新自表中匹配的行。
ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。
2. SET NULL: 从父表中删除或更新对应的行,同时将子表中的外键列设为空。
注意,这些在外键列没有被设为NOT NULL时才有效。ON DELETE SET NULL和ON UPDATE SET SET NULL都被InnoDB所支持。
3. NO ACTION: InnoDB拒绝删除或者更新父表。
4. RESTRICT: 拒绝删除或者更新父表。指定RESTRICT(或者NO ACTION)和忽略ON DELETE或者ON UPDATE选项的效果是一样的。
5. SET DEFAULT: InnoDB目前不支持。
1)父表更新时子表也更新,父表删除时如果子表有匹配的项,删除失败;
2)父表更新时子表也更新,父表删除时子表匹配的项也删除。
前一种情况,在外键定义中,我们使用ON UPDATE CASCADE ON DELETE RESTRICT;
后一种情况,可以使用ON UPDATE CASCADE ON DELETE CASCADE。
ALTER TABLE tbl_name
ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;
表级别创建外键约束:
语法:
foreign key(外键名) references 主表(主表上的列)
举例:
create table tb1(
id int auto_increment primary key,
name varchar(20)
);
create table student(
id int auto_increment primary key,
name varchar(25),
zd int,
foreign key(zd) references tb1(id)
);
create table tb2(
id int auto_increment,
name varchar(22),
constraint pk_id primary key(id),
zd int references tb1(id)
);
references 意思是参照,通常先建主表,然后再建从表,这样从表的参照引用的表才存在
上面的创建外键的方法没有指定约束名称,系统会默认给外键约束分配外键约束名称,命名为student_ibfk_n,
其中student是表名,n是当前约束从1开始的整数。
指定约束名称:
create table student(
id int auto_increment primary key,
name varchar(25),
classes_id int,
/*指定约束名称*/
constraint fk_classes_id foreign key(classes_id) references classes(id)
);
多列外键组合,必须用表级别约束:
语法:
foreign key(外键名1,外键名2,...) references 主表(主表列1,主表列2,...)
举例:
create table classes(
id int,
name varchar(20),
number int,
primary key(name, number)
);
create table student(
id int auto_increment primary key,
name varchar(20),
classes_name varchar(20),
classes_number int,
/*表级别联合外键*/
foreign key(classes_name, classes_number) references classes(name, number)
);
删除外键约束:
语法:
alter table 表名 drop foreign key 外键名;
举例:
alter table student drop foreign key student_ibfk_1;
alter table student drop foreign key fk_student_id;
增加外键约束
语法:
alter table 表 add foreign key(外键名1,外键名2,...) references 主表(主表列1,主表列2,...);
举例:
alter table student add foreign key(classes_name, classes_number) references classes(name, number);
自引用、自关联(递归表、树状表)
create table tree(
id int auto_increment primary key,
name varchar(50),
parent_id int,
foreign key(parent_id) references tree(id)
);
级联删除:删除主表的数据时,关联的从表数据也删除,则需要在建立外键约束的后面增加on delete cascade
或on delete set null,前者是级联删除,后者是将从表的关联列的值设置为null。
create table student(
id int auto_increment primary key,
name varchar(20),
classes_name varchar(20),
classes_number int,
/*表级别联合外键*/
foreign key(classes_name, classes_number) references classes(name, number) on delete cascade
);
可以使用check约束,但check约束对数据验证没有任何作用。
create table temp(
id int auto_increment,
name varchar(20),
age int,
primary key(id),
/*check约束*/
check(age 20)
);
上面check约束要求age必须大于20,但没有任何作用。但是创建table的时候没有任何错误或警告。
default_value:为列指定默认值。如果没有为列指定默认值,mysql> 自动地分配一个。如果列可以取NULL作为值,缺省值是NULL。
如果列被声明为NOT NULL,缺省值取决于列类型的value值
语法:
列 数据类型 default 默认值;
举例:
mysql> create table t2 (id int,dep char(10) default 'mis');
| id | int(11) | YES | | NULL | |
mysql> insert into t2 values(1,'hr');
mysql> insert into t2(id) values(2);
mysql> alter table t2 modify id int not null;
mysql> insert into t2 values();
| 1 | hr |
| 2 | mis |
3 rows in set (0.00 sec)