1. not null约束

    not null 约束只能在列名后面声明,不能使用constraint语句声明,当然也就没无法声明约束名称了。更改字段为null或者not null只能使用alter table table_name modify col_name (not) null;无法使用constraint语句修改。也就是说not null虽然是约束,但是却和constraint语句扯不上关系。not null约束在information_schema里面的table_constraints表中也无法查到。

    (1)在创建表的时候申明not null 约束

    create table t1(id int primary key, name varchar(20) not null);

    (2)在表已经存在时为字段添加not null约束

    alter table t2 modify name varchar(20) not null;

    (3)删除not null 约束

    alter table t2 modify name varchar(20) null;

     

  2. 主键约束

    主键约束既可以在列名后面声明,也可以在声明完所有列之后声明。前者只需要在列明后面跟上primary key就行了,后者的声明方法是[CONSTRAINT [symbol]] PRIMARY KEY(COL1,...)这里声明约束名称是没有任何意义的(只针对MySQL),因为你假如使用CONSTRAINT [symbol]语句之后,MySQL会自动把约束名称改为PRIMARY,可以到information_schema里面的table_constriants表里面验证。所以我们在声明所有列再声明primary key一般都不会使用constraint关键字。主键即唯一索引加上not null约束,主键列上会创建唯一索引,索引的名称和约束名称相同(都为PRIMARY),默认为BTREE索引,索引信息可以在information_schema里面的statistics表里面查询。

    (1)在创建表的时候申明主键约束

    create table t1(id int primary key, name varchar(20);

    create table t1(id int, name varchar(20), primary key(id));=========>常用

    create table t1(id int, name varchar(20), constraint ti_t1_pk primary key(id));=======>约束名没有意义

    (2)在表已经存在的时候添加主键约束

    alter table t1 modify id int primary key;

    alter table t1 add primary key(id); =========>常用,不过建表不带主键是不明智的行为

    alter table t1 add constraint t1_id_pk primary key(id);=======>约束名没有意义

    (3)删除主键约束

    alter table table_name drop primary key;

     

  3. unique约束

    unique约束和unique索引(注意是unique索引,不是普通索引)有着微妙的关系,二者在MySQL里面是同时存在的,但是二者不能等价。unique约束可以在information_schema里面的table_constraints表中查到,索引信息可以在information_schema里面的statistics表里面查询。

    (1)创建表的时候可以使用如下几种方法创建unique约束:

    create table t1(id int primary key,name varchar(20) unique);=======>无法指定约束名称,系统默认约束名称和字段名相同。

    create table t1(id int primary key,name varchar(20),constraint t1_unq unique(name));========>指定了约束名(或者索引名)。如果省略constraint子句或者只省略约束名称,那么约束名称和字段名相同。

    create table t1(id int primary key,name varchar(20), unique index t1_name_unq(name));========>常用,相当于创建了索引。

    create table t1(id int primary key,name varchar(20), unique key t1_name_unq(name));========>同上,相当于创建了索引,只是用的关键字是key,index和key在MySQL里面是同义词

     (2)表已经存在时可以通过两种方式添加unique约束。

    alter table t1 modify name varchar(20) unique;======>无法指定约束名称,系统默认约束名称和字段名相同。

    alter table t1 add constraint t1_name_unq unique(name);======>constraint关键字指定约束名称,即索引名称。如果省略约束名或者constraint关键字和约束名,那么约束名和字段名相同。

    alter table t1 add unique index t1_name_unq(name);=======>常用,约束名和索引名都为t1_name_unq

    alter table t1 add unique key t1_name_unq(name);=======>同上,相当于创建了索引,只是用的关键字是key

    因为unique约束和unique索引同时存在,所以我们都会用第三种方式去添加unique索(t1_name_unq为索引名称),如果不带unique关键字则说明添加的是普通索引。unique约束(unique索引)的信息会同时在information_schema里面的statistics表和table_constraints表里面保持一致。

    (3)删除unique约束(索引)只能使用如下语句:

    alter table t1 drop index t1_unq;

  4. 外键约束

    (1)在建表时创建外键约束可以使用如下方法(注意被引用的表的那个列必须是主键或者有unique索引):

    create table t1(id int primary key,name varchar(20), constraint t1_fk_name foreign  key(name) references       t2(name));该方法可以声明约束名。========>常用,如果省略contraint子句或者只省略约束名称,系统会按照一定的规则指定一个约束名称

    (2)在表已经存在的时候添加外键约束可以使用如下语句:

    alter table t1 add constraint t1_fk_name foreign key(name) references t2(name));=======>如果不指定constraint子句或者只省略约束名称,系统会按照一定的规则指定一个约束名

    (3)删除外键使用如下语句:

    alter table t1 drop foreign key t1_fk_name;

      

    注意1:InnoDB和Myisam引擎为比较常用的引擎。近年来大家越来越偏好采用InnoDB,因为它支持事务和外键。Myisam引擎不支持事务也不支持外键,如果你在Myisam引擎中创建外键,语句不会报错,但是show create table的显示是看不到外键的。 另外,在InnoDB表中创建指向Myisam表的外键,语句会报错Cannot add foreign key constraint。

    注意2:创建外键的父表的字段必须是主键或者有索引(只是普通索引即可,不一定要非空,也不一定是唯一索引)。主表和子表的字段数据类型要相同,数据类型相同指的是数据类型,不包括长度。比如varchar(5)和varchar(10)数据类型相同,varchar(10)和char(5)数据类型相同,而init、smallint和bigint等数据类型则不相同(实验得出的结论)。如果不符合这个条件会报错Cannot add foreign key constraint。不过一般情况下我们还是设置父子表的字段类型和长度都一样。

      

  5. check约束

    MySQL不支持check约束。如果你在SQL语句中写check约束,MySQL不会报错,但是没有任何效果。你必须在程序里面去限制列的取值。

    试验如下:

    mysql> create table t4(id int, age int, constraint t1_age_check check(age>18)); ======>没有报错

    Query OK, 0 rows affected (0.11 sec)

     

    mysql> show create table t4\G======>没有check约束的信息

    *************************** 1. row ***************************

           Table: t4

    Create Table: CREATE TABLE `t4` (

      `id` int(11) DEFAULT NULL,

      `age` int(11) DEFAULT NULL

    ) ENGINE=InnoDB DEFAULT CHARSET=latin1

    1 row in set (0.00 sec)

    mysql> insert into t4 values(1,20);======>仍然可以插入数据

    Query OK, 1 row affected (0.01 sec)

     

    可以看到check约束是没有任何作用的。当然了,使用modify语句添加或修改check约束是没有用的,在information_schema库的table_constraints表中同样也是无法查到的。

总结:

        1.  not null是一朵奇葩。只能在列级指定。

        2.  primary key的约束名称是没有意义的。你指定了MySQL也会把你重置为PRIMARY。

        3.  除了not null约束,一般建表的时候所有的约束都放在表级声明(包括primary key),只是因为放在那里一目了然,便于查看和维护。

        4.  除了not null约束,添加约束的时候都最好使用alter table add ....语句,删除约束的时候都最好使用alter table drop ....语句,这样便于记忆。