真正约束数据,仅仅靠数据类型是不够的,我们还需要一些其他的约束,这就是 列属性 !
空属性(NULL/NOT NULL)
NULL 默认为空,NOT NULL 不为空,我们一般都约束数据不可以为空,为空,数据没有意义 ;
列描述(Comment)
没有实际含义,是专门用来描述字段,用来告诉程序员该字段是干嘛用的 ;
被保存在建表语句中,可以使用 show create table xxx ;
来查看该描述,以便了解字段的具体含义 ;
默认值(Default)
为某个字段赋予一个默认值,如果该字段,没有被显示的赋值,则使用默认值;
在插入的时候,如果想要使用默认值,可以为该字段插入 dafault
,这样也会得到默认值; (多此一举,不显示赋值,就可以获得默认值,非要显示的 default
)
主键(Primary key)
一张表中只能有一个主键,可以是一个字段被标识为主键,也可以是几个字段被标识为复合主键 ;
主键用来约束数据的唯一性,被标识为主键的字段列表的数据是不可以重复的;
-
增加主键
sql 操作中常见的有三种方法添加主键:
-
在创建表的时候,直接在字段后面添加
primary key
# 创建 mysql> create table my_pri1( -> name varchar(10) not null, -> number char(10) primary key comment '使用主键约束' -> ) charset utf8 ; Query OK, 0 rows affected # 查看主键 mysql> desc my_pri1 ; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | NO | | | | | number | char(10) | NO | PRI | | | +--------+-------------+------+-----+---------+-------+ 2 rows in set
优点:方便 ;
缺点:只能使用一个字段作为主键 ;
-
在创建表的时候,在最后使用
primary key(主键字段列表)
mysql> create table my_pri2( -> name varchar(10) not null, -> number char(10) comment '该字段没有被约束为非空,但是下面的主键会自动的约束为非空', -> primary key(name,number) comment '使用复合主键' -> )charset utf8 ; Query OK, 0 rows affected mysql> desc my_pri2 ; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | NO | PRI | | | | number | char(10) | NO | PRI | | | +--------+-------------+------+-----+---------+-------+ 2 rows in set
-
当表已经创建好以后,额外追加主键
可以直接修改表字段属性,也可以直接追加 ;
直接追加语法:alter table 表名 add primary key(字段列表)
;mysql> create table my_pri3( -> name varchar(10), -> number char(10) -> )charset utf8 ; Query OK, 0 rows affected -- 追加主键 mysql> alter table my_pri3 modify number char(10) primary key ; Query OK, 0 rows affected Records: 0 Duplicates: 0 Warnings: 0 -- 查看主键 mysql> desc my_pri3 ; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | YES | | NULL | | | number | char(10) | NO | PRI | | | +--------+-------------+------+-----+---------+-------+ 2 rows in set
追加主键的时候,要注意,表中对应字段的数据不可以有
null
或者重复
;
-
-
查看主键
使用
desc 表名
;-- 查看主键 mysql> desc my_pri3 ; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | YES | | NULL | | | number | char(10) | NO | PRI | | | -- 主键 +--------+-------------+------+-----+---------+-------+ 2 rows in set
-
更新主键 && 删除主键
更新与删除是一体的,因为主键只有一个,必须先删除主键,才能添加新的主键 ;
ヾ(◍°∇°◍)ノ゙
删除主键语法:
alter table 表名 drop primary key
;mysql> desc my_pri3 ; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | YES | | NULL | | | number | char(10) | NO | PRI | | | +--------+-------------+------+-----+---------+-------+ 2 rows in set mysql> -- 删除主键 -> alter table my_pri3 drop primary key ; Query OK, 0 rows affected Records: 0 Duplicates: 0 Warnings: 0 mysql> desc my_pri3 ; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | YES | | NULL | | | number | char(10) | NO | | | | +--------+-------------+------+-----+---------+-------+ 2 rows in set
主键分类
有 业务主键 和 逻辑主键 ;
使用业务字段当主键,就是业务主键;但是一般不使用业务主键,因为主键的含义,就是约束字段,我们可以用一个与业务无关的字段,来充当主键,这样主键就是逻辑主键 ;
自动增长(auto_increment)
自增长:当对应的字段,不给值,或者给 default
,或者给 NULL
,就会自动的被系统触发,系统会从当前字段的值的 曾经的最大值
(被删掉也算)+1,作为新的值 ;
-
特点:
-
任何字段想要自增长,必须满足前提,字段本身是一个索引(
key
栏有值),不是任何字段都可以自增长的-- 下面字段的 key 栏就没有值,就不是索引,就不能被自增长 +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | name | varchar(10) | YES | | NULL | | | number | char(10) | NO | | | | +--------+-------------+------+-----+---------+-------+
-
自增长字段必须是数字(整型)
-
一张表最多一个自增长
上面的三个特点说出来以后,我们发现它和主键简直是绝配!!
-
-
创建自增长
mysql> create table my_auto( -> id int primary key auto_increment comment '让id成为自增长,因为设置了主键,所有key有值' , -> name varchar(10) -> )charset utf8 ; Query OK, 0 rows affected mysql> desc my_auto ; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set
-
插入数据
-- 不插入值 mysql> insert into my_auto(name) values('哈哈'); Query OK, 1 row affected -- 插入 null mysql> insert into my_auto values(null,'呵呵'); Query OK, 1 row affected --插入 default mysql> insert into my_auto values(default,'嘻嘻'); Query OK, 1 row affected mysql> select * from my_auto ; +----+------+ | id | name | +----+------+ | 1 | 哈哈 | | 2 | 呵呵 | | 3 | 嘻嘻 | +----+------+ 3 rows in set -- 插入指定的值 mysql> insert into my_auto values(5,'嘻嘻'); Query OK, 1 row affected -- 下一次自增的值,就是 当前列值的最大值+1 mysql> insert into my_auto values(null,'嘻嘻'); Query OK, 1 row affected mysql> select * from my_auto ; +----+------+ | id | name | +----+------+ | 1 | 哈哈 | | 2 | 呵呵 | | 3 | 嘻嘻 | | 5 | 嘻嘻 | | 6 | 嘻嘻 | +----+------+ 5 rows in set
-
查看下一次自增的值
-- 查看下一次自增的值 -- table_name = '表名' mysql> select auto_increment from information_schema.tables where table_name = 'my_auto' ; +----------------+ | auto_increment | +----------------+ | 7 | +----------------+ 1 row in set
-
修改自增长
自增长如果涉及到字段的改变,则必须先删除自增长,再增加自增长,因为一张表只能有一个自增长 ;
语法:跟之前修改表的字段属性一样;
-- modify 去掉 auto_increment ; mysql> alter table my_auto modify id int ; Query OK, 6 rows affected Records: 6 Duplicates: 0 Warnings: 0 mysql> desc my_auto ; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | 0 | | | name | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set -- 添加 auto_increment mysql> alter table my_auto modify id int auto_increment ; Query OK, 6 rows affected Records: 6 Duplicates: 0 Warnings: 0 mysql> desc my_auto ; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+----------------+ 2 rows in set
修改当前自增长已经存在的值,修改的时候,只能修改为比当前的值打,不能往小了修改,那样修改是无效的 ;
语法:
alter table 表名 auto_increment = 值
;-- 查看当前的auto_increment 的值 mysql> select auto_increment from information_schema.tables where table_name = 'my_auto' ; +----------------+ | auto_increment | +----------------+ | 8 | +----------------+ 1 row in set -- 修改auto_increment 的值 mysql> alter table my_auto auto_increment = 10 ; Query OK, 5 rows affected Records: 5 Duplicates: 0 Warnings: 0 -- 查看auto_increment 的值 mysql> select auto_increment from information_schema.tables where table_name = 'my_auto' ; +----------------+ | auto_increment | +----------------+ | 10 | +----------------+ 1 row in set -- 再次插入数据 mysql> insert into my_auto values(default,'嘻嘻'); Query OK, 1 row affected -- 发现数据已经从我们改变的 auto_increment mysql> select * from my_auto ; +----+------+ | id | name | +----+------+ | 1 | 哈哈 | | 2 | 呵呵 | | 3 | 嘻嘻 | | 5 | 嘻嘻 | | 7 | 嘻嘻 | | 10 | 嘻嘻 | +----+------+ 6 rows in set
为什么自增长是从1开始的,为什么每次都是自增1?
所有的系统的变化(如之前学的字符集、校对集),都是系统内部的变量进行控制的 ;
查看自增长对应的变量:
show variables like 'auto_increment%' ;
mysql> show variables like 'auto_increment%' ; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 1 | -- 自增步长 | auto_increment_offset | 1 | -- 自增起始 +--------------------------+-------+ 2 rows in set
我们可以修改这两个变量,来达到我们想要的操作,修改是对整个数据而言的,也就是这里修改,然后在其他表的操作也会受到影响,但是它也是一个会话级别的修改,即关闭连接以后,修改就会被重置 ;
show auto_increment_increment = 新步长
;mysql> set auto_increment_increment = 5 ; Query OK, 0 rows affected mysql> show variables like 'auto_increment%' ; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 5 | | auto_increment_offset | 1 | +--------------------------+-------+ 2 rows in set
修改为步长以后,
第一次添加的值,依然会默认的使用自加1
,从第二次
开始才会按照我们修改的步长来自加!
-
删除自增长
自增长是字段的一个属性,只要
modify
去掉该属性就行,就跟前面写的一样!modify
的时候,不要再次使用primary key
这样会被当做再次添加主键 ;-- modify 去掉 auto_increment ,不要再次写上 primary key; mysql> alter table my_auto modify id int ; Query OK, 6 rows affected Records: 6 Duplicates: 0 Warnings: 0
唯一键(unique)
一张表,往往有多个地段需要具有唯一的约束,但是它们又不能笼统的使用复合主键来约束,这时候,就需要唯一键约束了 ;
唯一键默认允许为 null
(与主键恰相反),而且可以多个为空,空字段不参与唯一性的比较 ;
-
创建唯一键
基本与创建主键一致 ;
-- 直接在字段后面写上 mysql> create table my_unique( -> id int unique , -> name varchar(10) -> )charset utf8 ; Query OK, 0 rows affected mysql> desc my_unique ; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | UNI | NULL | | | name | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set -- 在所有字段后面写,可以作为复合唯一键 mysql> create table my_unique2( -> id int not null , -> name varchar(10), -> unique(id) -> )charset utf8 ; Query OK, 0 rows affected -- 查看,我们发现 key 栏里面赫然写着 pri ,吗,明明是 unique, -- 为啥变成了 PRI -- 因为该字段是 null 并且被修饰为 unique -- 并且该表还没有主键,这是主要原因,系统就不知道它到底是啥了,以为他是 PRI ,这里只是假象 -- 这里使用 show create table xxx ,就会显示出来 mysql> desc my_unique2 ; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | | | | name | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set -- 照妖镜,显示出本体 unique 了 mysql> show create table my_unique2 ; +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ | my_unique2 | CREATE TABLE `my_unique2` ( `id` int(11) NOT NULL, `name` varchar(10) default NULL, UNIQUE KEY `id` (`id`) -- 前面的 `id` 反引号中的id,就是索引名 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set -- 表创建完成以后,再添加 mysql> create table my_unique3( -> id int primary key , -> name varchar(10) not null -> )charset utf8 ; Query OK, 0 rows affected mysql> desc my_unique3 ; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | | | | name | varchar(10) | NO | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set mysql> alter table my_unique3 add unique key(name) ; Query OK, 0 rows affected Records: 0 Duplicates: 0 Warnings: 0 -- 因为已经有主键了,因此系统会很方便的识别出他是唯一键 mysql> desc my_unique3 ; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | | | | name | varchar(10) | NO | UNI | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set
-
删除唯一键
alter table 表名 drop index 索引名字 ; -- 默认索引名和字段名一致 UNIQUE KEY `id` (`id`) -- 前面的 `id` 反引号中的id,就是索引名