您现在的位置是:首页 >其他 >MySQL 约束网站首页其他
MySQL 约束
简介MySQL 约束
目录
表的约束
真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的 保证数据的合法性 ,从业务逻辑角度保证数据的正确性。比如有一个字段是 email ,要求是唯一的。表的约束很多,这里主要介绍如下几个: null/not null,default, comment, zerofill , primarykey , auto_increment , unique key 。空属性 null
两个值: null (默认的)和 not null( 不为空 )数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。mysql> select null ;+------+| NULL |+------+| NULL |+------+1 row in set ( 0.00 sec)mysql> select 1 + null ;+--------+| 1 + null |+--------+| NULL |+--------+1 row in set ( 0.00 sec)所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这就是“ 约束 ” 。默认值 default
默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。mysql> create table tt10 (-> name varchar ( 20 ) not null ,-> age tinyint unsigned default 0 ,-> sex char ( 2 ) default ' 男 '-> );Query OK, 0 rows affected ( 0.00 sec)默认值的生效:数据在插入的时候不给该字段赋值,就使用默认值(default)。-- 注意:只有设置了 default 的列,才可以在插入值的时候,对列进行省略列描述 comment
列描述: comment ,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或 DBA来进行了解。mysql> create table tt12 (-> name varchar ( 20 ) not null comment ' 姓名 ' ,-> age tinyint unsigned default 0 comment ' 年龄 ' ,-> sex char ( 2 ) default ' 男 ' comment ' 性别 '-> );-- 注意: not null 和 defalut 一般不需要同时出现,因为 default 本身有默认值,不会为空通过 desc 查看不到注释信息:mysql> desc tt12;+-------+---------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+---------------------+------+-----+---------+-------+| name | varchar ( 20 ) | NO | | NULL | || age | tinyint ( 3 ) unsigned | YES | | 0 | || sex | char ( 2 ) | YES | | 男 | |+-------+---------------------+------+-----+---------+-------+通过 show 可以看到mysql> show create table tt12G*************************** 1 . row ***************************Table : tt12Create Table : CREATE TABLE `tt12` (`name` varchar ( 20 ) NOT NULL COMMENT ' 姓名 ' ,`age` tinyint ( 3 ) unsigned DEFAULT '0' COMMENT ' 年龄 ' ,`sex` char ( 2 ) DEFAULT ' 男 ' COMMENT ' 性别 ') ENGINE=MyISAM DEFAULT CHARSET=gbk1 row in set ( 0.00 sec)zerofill
刚开始学习数据库时,很多人对 数字类型 后面的长度很迷茫。通过 show 看看 tt3 表的建表语句:mysql> show create table tt3G***************** 1 . row *****************Table : tt3Create Table : CREATE TABLE `tt3` (`a` int ( 10 ) unsigned DEFAULT NULL ,`b` int ( 10 ) unsigned DEFAULT NULL) ENGINE=MyISAM DEFAULT CHARSET=gbk1 row in set ( 0.00 sec)可以看到 int(10), 这个代表什么意思呢?整型不是 4 字节码?这个 10 又代表什么呢?其实没有 zerofill 这个属性,括号内的数字是毫无意义的。a 和 b 列就是前面插入的数据,如下:mysql> insert into tt3 values ( 1 , 2 );Query OK, 1 row affected ( 0.00 sec)mysql> select * from tt3;+------+------+| a | b |+------+------+| 1 | 2 |+------+------+但是对列添加了 zerofill 属性后,显示的结果就有所不同了。修改 tt3 表的属性:mysql> alter table tt3 change a a int ( 5 ) unsigned zerofill;mysql> show create table tt3G*************************** 1 . row ***************************Table : tt3Create Table : CREATE TABLE `tt3` (`a` int ( 5 ) unsigned zerofill DEFAULT NULL , -- 具有了 zerofill`b` int ( 10 ) unsigned DEFAULT NULL) ENGINE=MyISAM DEFAULT CHARSET=gbk1 row in set ( 0.00 sec)对 a 列添加了 zerofill 属性,再进行查找,返回如下结果:mysql> select * from tt3;+-------+------+| a | b |+-------+------+| 00001 | 2 |+-------+------+这次可以看到 a 的值由原来的 1 变成 00001 ,这就是 zerofill 属性的作用,如果宽度小于设定的宽度(这里设置的是5 ),自动填充 0 。要注意的是,这只是最后显示的结果,在 MySQL 中实际存储的还是 1 。为什么是这样呢?我们可以用hex 函数来证明。mysql> select a, hex(a) from tt3;+-------+--------+| a | hex(a) |+-------+--------+| 00001 | 1 |+-------+--------+可以看出数据库内部存储的还是 1,00001 只是设置了 zerofill 属性后的一种格式化输出而已。
主键 primary key
主键: primary key 用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的列通常是整数类型。创建表的时候直接在字段上指定主键mysql> create table tt13 (-> id int unsigned primary key comment ' 学号不能为空 ' ,-> name varchar ( 20 ) not null );Query OK, 0 rows affected ( 0.00 sec)mysql> desc tt13;+-------+------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+------------------+------+-----+---------+-------+| id | int ( 10 ) unsigned | NO | PRI | NULL | | <= key 中 pri 表示该字段是主键| name | varchar ( 20 ) | NO | | NULL | |+-------+------------------+------+-----+---------+-------+主键约束:主键对应的字段中不能重复,一旦重复,操作失败。mysql> insert into tt13 values ( 1 , 'aaa' );Query OK, 1 row affected ( 0.00 sec)mysql> insert into tt13 values ( 1 , 'aaa' );ERROR 1062 ( 23000 ): Duplicate entry '1' for key 'PRIMARY'当表创建好以后但是没有主键的时候,可以再次追加主键alter table 表名 add primary key( 字段列表 )删除主键alter table 表名 drop primary key;复合主键在创建表的时候,在所有字段之后,使用 primary key( 主键字段列表 ) 来创建主键,如果有多个字段作为主键,可以使用复合主键。mysql> create table tt14(-> id int unsigned,-> course char(10) comment ' 课程代码 ',-> score tinyint unsigned default 60 comment ' 成绩 ',-> primary key(id, course) -- id 和course为复合主键-> );Query OK, 0 rows affected (0.01 sec)mysql> desc tt14;+--------+---------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+---------------------+------+-----+---------+-------+| id | int(10) unsigned | NO | PRI | 0 | | <= 这两列合成主键| course | char(10) | NO | PRI | | || score | tinyint(3) unsigned | YES | | 60 | |+--------+---------------------+------+-----+---------+-------+mysql> insert into tt14 (id,course)values(1, '123');Query OK, 1 row affected (0.02 sec)mysql> insert into tt14 (id,course)values(1, '123');ERROR 1062 (23000): Duplicate entry '1-123' for key 'PRIMARY' -- 主键冲突自增长 auto_increment
auto_increment :当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。自增长的特点 :
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)。
- 自增长字段必须是整数。
- 一张表最多只能有一个自增长。
mysql> create table tt21(-> id int unsigned primary key auto_increment,-> name varchar ( 10 ) not null default ''-> );mysql> insert into tt21(name) values ( 'a' );mysql> insert into tt21(name) values ( 'b' );mysql> select * from tt21;+----+------+| id | name |+----+------+| 1 | a || 2 | b |+----+------+在插入后获取上次插入的 AUTO_INCREMENT 的值(批量插入获取的是第一个值)自己增加到更的的值之后,下次自增会比最大值大一。索引
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的 SQL 语句执行得更快,可快速访问数据库表中的特定信息。唯一键 unique
一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键就可以解决表中有多个字段需要唯一性约束的问题。唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。关于唯一键和主键的区别:我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。案例:mysql> create table student (-> id char ( 10 ) unique comment ' 学号,不能重复,但可以为空 ' ,-> name varchar ( 10 )-> );Query OK, 0 rows affected ( 0.01 sec)mysql> insert into student(id, name) values ( '01' , 'aaa' );Query OK, 1 row affected ( 0.00 sec)mysql> insert into student(id, name) values ( '01' , 'bbb' ); -- 唯一约束不能重复ERROR 1062 ( 23000 ): Duplicate entry '01' for key 'id'mysql> insert into student(id, name) values ( null , 'bbb' ); -- 但可以为空Query OK, 1 row affected ( 0.00 sec)mysql> select * from student;+------+------+| id | name |+------+------+| 01 | aaa || NULL | bbb |+------+------+外键 foreign key
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或 unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null 。foreign key ( 字段名 ) references 主表 ( 列 )对上面的示意图进行设计:
先创建主键表
create table myclass (id int primary key,name varchar ( 30 ) not null comment ' 班级名 ');再创建从表create table stu (id int primary key,name varchar ( 30 ) not null comment ' 学生名 ' ,class_id int ,foreign key (class_id) references myclass(id));正常插入数据mysql> insert into myclass values ( 10 , 'C++ 大牛班 ' ),( 20 , 'java 大神班 ' );Query OK, 2 rows affected ( 0.03 sec)Records: 2 Duplicates: 0 Warnings: 0mysql> insert into stu values ( 100 , ' 张三 ' , 10 ),( 101 , ' 李四 ' , 20 );Query OK, 2 rows affected ( 0.01 sec)Records: 2 Duplicates: 0 Warnings: 0插入一个班级号为 30 的学生,因为没有这个班级,所以插入不成功mysql> insert into stu values ( 102 , 'wangwu' , 30 );ERROR 1452 ( 23000 ): Cannot add or update a child row:a foreign key constraint fails (mytest .stu , CONSTRAINT stu_ibfk_1FOREIGN KEY (class_id) REFERENCES myclass (id))插入班级id为null,比如来了一个学生,目前还没有分配班级
mysql> insert into stu values(102, 'wangwu', null);
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。