文章目录
- 1. null 空属性
 - 2. default 默认值
 - 3. comment 列描述
 - 4. zerofill 格式化输出
 - 5. primary key 主键
 - 6. auto_increment 自增长
 - 7. 唯一键
 - 8. unique key 外键
 
前言: 表的约束主要是靠数据类型。有些情况,光靠数据类型约束是不够的,比如想要限制某个字段它的值是唯一的,不能重复,这就需要额外的约束。本章只介绍
null/not null,default, comment, zerofill,primary key,auto_increment,unique key 这些约束,都比较的常用。
 
1. null 空属性
null是空属性,意思就是它的值不存在。注意:是不存在 ,这样记忆不容易混。有C语言基础可能以为 null 就是空指针?在c/c++里,null,0,"" 它们的数值是一样的,它们是有值的。但是 MySQL中的null 它没值,不参与任何运算。
mysql> select null;
+------+
| NULL |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
mysql> select null+1;
+--------+
| null+1 |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)
 
默认情况下,如果不对字段进行限制,那么字段默认是可以为null的,但是 有的字段不能默认为空。比如你的信息表,有名字,有学号,有班级,这个班级不能默认为空,也就是说你插入一个学生信息,必须告诉人家所在班级:
mysql> create table student1(id int,name varchar(10),class int not null);
Query OK, 0 rows affected (0.03 sec)
mysql> desc student1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| class | int(11)     | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into student1 values(1,'bob',102);
Query OK, 1 row affected (0.01 sec)
mysql> insert into student1(id,name) values(2,'dd');
ERROR 1364 (HY000): Field 'class' doesn't have a default value
mysql> 
 
指定not null的字段,是不允许为null,所以插入一组值的时候,必须得插入这个字段的值,不过 它也可以有默认值,这就是下面讲的了。
2. default 默认值
默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。
简单说就是,你插入一组值,有的值你没主动插入,但是它可以用默认值。
mysql> create table student2(id int,name varchar(10),class int not null default 102);
Query OK, 0 rows affected (0.03 sec)
mysql> desc student2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| class | int(11)     | NO   |     | 102     |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into student2(id,name) values(1,'kk');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student2  values(2,'gg',103);
Query OK, 1 row affected (0.00 sec)
mysql> select * from student2;
+------+------+-------+
| id   | name | class |
+------+------+-------+
|    1 | kk   |   102 |
|    2 | gg   |   103 |
+------+------+-------+
2 rows in set (0.00 sec)
 
看上面例子,class 默认值是102,所以我插入值可以不插入class,尽管它是not null,结果没有报错,使用了它的默认值102。
3. comment 列描述
这个就是注释,对表中的列 进行 注释。
mysql> create table test1(id int comment '这是身份证号');
Query OK, 0 rows affected (0.03 sec)
mysql> show create table test1\G;
*************************** 1. row ***************************
       Table: test1
Create Table: CREATE TABLE `test1` (
  `id` int(11) DEFAULT NULL COMMENT '这是身份证号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.01 sec)
ERROR: 
No query specified
mysql> 
 
这个就是注释作用。
4. zerofill 格式化输出
这个比较有意思了,能解决我们之前学习的一个困惑:

 有没有人好奇过,这个int(11),这个11是个啥?有人可能会想 这是 字节大小?字符长度? 都不是 。它的意思是默认对齐,不过要显示默认对齐前,必须要有zerofill属性。
mysql> alter table test1 change id id int(6) unsigned zerofill;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table test1\G;
*************************** 1. row ***************************
       Table: test1
Create Table: CREATE TABLE `test1` (
  `id` int(6) unsigned zerofill DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.00 sec)
ERROR: 
No query specified
mysql> 
 
现在我插入一个数据,我们看看现象:
mysql> insert into test1 values(4);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test1;
+--------+
| id     |
+--------+
| 000004 |
+--------+
1 row in set (0.00 sec)
mysql> 
 
这就是种格式化输出,看上去没啥卵用,我也没咋用过,哈哈。
5. primary key 主键
主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的列通常是整数类型。
- 指定主键:
 
mysql> create table student3(id int primary key not null  comment '学号不可以重复',name varchar(10));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into student3 values(1,'bob');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student3 values(1,'yy');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into student3 values(2,'bob');
Query OK, 1 row affected (0.02 sec)
mysql> select * from student3;
+----+------+
| id | name |
+----+------+
|  1 | bob  |
|  2 | bob  |
+----+------+
2 rows in set (0.00 sec)
mysql> desc student3;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> 
 
- 一个表只能有一个主键,不可以重复:
 
mysql> create table student4(id int primary key not null  comment '学号不可以重复',name varchar(10) primary key);
ERROR 1068 (42000): Multiple primary key defined
 
- 如果一个表中没有主键,要追加主键:
 
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> alter table test2 add primary key(name);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | NO   | PRI |         |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
 
desc 显示 mysql表结构,其中那个key,看到了吧,就是索引,字段的属性。
- 也可以删除一个表中的主键:
 
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | NO   | PRI |         |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> alter table test2 drop primary key;
Query OK, 4 rows affected (0.06 sec)
Records: 4  Duplicates: 0  Warnings: 0
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| name  | varchar(2) | NO   |     |         |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
 
- 复合主建:
 
有种情况,它允许单一的字段出现重复,但是 不允许多个字段出现重复。这个情况就得用复合主键,这样做,表里面还是只有一个主键,只不过这个主键是复合主键。
mysql> create table student4(id int,name varchar(10),gander varchar(2) not null,primary key(id,name));
Query OK, 0 rows affected (0.02 sec)
mysql> desc student4;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | 0       |       |
| name   | varchar(10) | NO   | PRI |         |       |
| gander | varchar(2)  | NO   |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into student4 values (1,'bob','男');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student4 values (1,'zz','男');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student4 values (2,'bob','男');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student4 values (1,'bob','女');
ERROR 1062 (23000): Duplicate entry '1-bob' for key 'PRIMARY'
mysql> 
 
6. auto_increment 自增长
auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
自增长的特点:
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
 - 自增长字段必须是整数
 - 一张表最多只能有一个自增长
 
mysql> create table people(id tinyint primary key auto_increment,name varchar(10) not null default '');
Query OK, 0 rows affected (0.02 sec)
mysql> insert into people values(1,'张飞');
Query OK, 1 row affected (0.00 sec)
mysql> insert into people(name) values('李四');
Query OK, 1 row affected (0.00 sec)
mysql> select * from people;
+----+--------+
| id | name   |
+----+--------+
|  1 | 张飞   |
|  2 | 李四   |
+----+--------+
2 rows in set (0.00 sec)
mysql> insert into people values(100,'吕布');
Query OK, 1 row affected (0.01 sec)
mysql> insert into people(name) values('关羽');
Query OK, 1 row affected (0.00 sec)
mysql> select * from people;
+-----+--------+
| id  | name   |
+-----+--------+
|   1 | 张飞   |
|   2 | 李四   |
| 100 | 吕布   |
| 101 | 关羽   |
+-----+--------+
4 rows in set (0.00 sec)
 
7. 唯一键
一个表中只能有一个主键,这个主键不能为null,并且不能重复;有的数据 也要保持唯一性,但是表中已有主键,只能使用唯一键。
注意:唯一键,是允许为null的,null并不参与任何计算,多个null也没关系,相当于多个不存在。
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 |
+------+------+
 
8. unique key 外键
这个约束是,表和表之间的约束,或者说是一种 映射关系:

在上述外键关系中:主表是班级表,从表是学生表。因为 学生表的班级id只能是175,或者176,为什么?因为班级表中只有175和176两个班。
也就是说:班级表约束了学生表中class_id的范围,这就是外键约束。
那么现在来做一下 实验,构建学生表 和 班级表的 外键关系:
mysql> create table class(id int primary key,
class_name varchar(10) not null);
Query OK, 0 rows affected (0.02 sec)
mysql> create table student(id int primary key,
name varchar(10) not null,
class_id int,
foreign key(class_id) references class(id));
Query OK, 0 rows affected (0.04 sec)
mysql> desc class;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| id         | int(11)     | NO   | PRI | NULL    |       |
| class_name | varchar(10) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> desc student;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int(11)     | NO   | PRI | NULL    |       |
| name     | varchar(10) | NO   |     | NULL    |       |
| class_id | int(11)     | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into class values(175,'加强班');
Query OK, 1 row affected (0.01 sec)
mysql> insert into class values(176,'普通班');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student values(1,'张三',175);
Query OK, 1 row affected (0.01 sec)
mysql> insert into student values(2,'李四',176);
Query OK, 1 row affected (0.00 sec)
mysql> insert into student values(3,'王五',178);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`hh1`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
mysql> 
 
这就是它的实验,大家可以下去自己敲的玩玩。

















