(八)列属性


真正约束数据,仅仅靠数据类型是不够的,我们还需要一些其他的约束,这就是 列属性


空属性(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,就是索引名
    
原文地址:https://www.cnblogs.com/young-youth/p/11665641.html