zoukankan      html  css  js  c++  java
  • MySQL 约束及修改数据表(三)

    3、约束以及修改数据表

    • 约束保证数据的完整性和一致性
    • 约束分为表级约束和列级约束

    之所以把约束分为表级约束和列级约束,是根据约束所针对的字段的数目来决定的,如果约束只是针对某一个字段,称为列级约束,如果针对两个或以上的字段来使用,称为表级约束。

    约束类型包括:

    1. NOT NULL:非空约束
    2. PRIMARY KEY:主键约束
    3. UNIQUE KEY:唯一约束
    4. DEFAULT:默认约束
    5. FOREIGN KEY:外键约束

    3.1、MySQL 外键约束的要求解析

    外键约束(FOREIGN KEYp):

    • 保证数据的一致性,完整性

    • 实现一对一或一对多关系

    3.1.1、外键约束的要求

    使用外键约束,只有全部满足以下四个要求时才能使用:

    1. 父表和子表必须使用相同的存储引擎,而且禁止使用临时表
    2. 数据表的存储引擎只能为 InnoDB
    3. 外键列和参照列必须具有相似的数据类型。其中数字的长度或是否有符号位必须相同;而字符的长度则可以不同
    4. 外键列和参照列必须创建索引。如果外键列不存在索引的话,MySQL 将自动创建索引

    子表:具有外键列的表

    父表:子表所参照的表

    外键列:加过 FOREIGN 关键词的列

    参照列:外键列所参照的列

    3.1.2、编辑数据表的默认存储引擎

    修改MySQL 配置文件(my.ini):

    打开配置文件,找到 default-storage-engine=INNODB 字段,将默认引擎修改为 INNODB,保存,重启 MySQL 即可。

    default-storage-engine=INNODB
    

    查看新建的数据表默认引擎是否为 INNODB:

    (一)、数据表 province:

    # 创建一个名为province的数据表
    mysql> CREATE TABLE province(
        -> id SMALLINT(5) UNSIGNED PRIMARY KEY AUTO_INCREMENT,  # 将 id 设置为主键
        -> pname VARCHAR(20) NOT NULL   # 省份名称
        -> );
    Query OK, 0 rows affected (0.06 sec)
    
    # 查看数据表的默认引擎(SHOW CREATE TABLE 表名)
    mysql> SHOW CREATE TABLE province;
    +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table    | Create Table                                                                                                                                                             |
    +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | province | CREATE TABLE `province` (
      `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
      `pname` varchar(20) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |         # 引擎为 INNODB ,编码方式为 utf8
    +----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.01 sec)
    

    (二)、数据表 users:

    # 创建一个名为 users 的数据表
    mysql> CREATE TABLE users(
        -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
        -> username VARCHAR(10) NOT NULL,
        -> pid BIGINT,   # pid 为外键列,pid 的数据类型为 BIGINT,与参照列(id)的数据类型不一致
        -> FOREIGN KEY(pid) REFERENCES province (id)   # province 中的 id 为参照列
        -> );
    ERROR 1215 (HY000): Cannot add foreign key constraint
    
    mysql> CREATE TABLE users(
        -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
        -> username VARCHAR(10) NOT NULL,
        -> pid SMALLINT UNSIGNED,           # pid 为外键列
        -> FOREIGN KEY (pid) REFERENCES province (id)       # province 中的 id 为参照列
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    • 上面,创建了两个数据表,分别为存储省份的的数据表(province),以及存储用户的的数据表(users),province 有两个列(idpname(省份名称)),其中 id 设置为主键约束,并自动创建索引,数据类型为 SMALLINT
    • users 有三个列,(idusername、以及 pid),其中 pid 列它参照 provinceid 列(命令为:FOREIGN KEY (pid) REFERENCES province (id)),为此,我们知道了 province 为父表,users 为子表,province-id 为参照列,users-id 为外键列,根据外键约束要求,外键列的数据类型必须与参照列一致,否则无法创建成功。
    • 要使用外键约束就需要满足四个要求,因为 MySQL 的默认存储引擎为 INNODB, 所以 要求 1、2 符合
    • 外键列和参照列的数据类型都为 SMALLINT UNSIGNED,要求 3 符合
    • 参照列(province-id),因为将它设置为主键(PRIMARY KEY)并有(AUTO_INCREMENT),所有有索引
    # 查看数据表 province id 的索引
    mysql> SHOW INDEXES FROM provinceG;
    *************************** 1. row ***************************
            Table: province
       Non_unique: 0
         Key_name: PRIMARY        # 主键约束
     Seq_in_index: 1              # 索引(sequence_in_index)
      Column_name: id             # 列名
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null:
       Index_type: BTREE
          Comment:
    Index_comment:
    1 row in set (0.01 sec)
    
    # 另一种查看方式
    mysql> SHOW INDEXES FROM province;
    +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | province |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
    +----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    1 row in set (0.00 sec)
    
    # users 也创建了索引,2个索引,id 为主键约束,pid 为外键约束
    mysql> SHOW INDEXES FROM usersG;
    *************************** 1. row ***************************
            Table: users
       Non_unique: 0
         Key_name: PRIMARY
     Seq_in_index: 1
      Column_name: id
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null:
       Index_type: BTREE
          Comment:
    Index_comment:
    *************************** 2. row ***************************
            Table: users
       Non_unique: 1
         Key_name: pid
     Seq_in_index: 1
      Column_name: pid
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null: YES
       Index_type: BTREE
          Comment:
    Index_comment:
    2 rows in set (0.01 sec)
    

    3.2、外键约束的参照操作

    1. CASCADE:从父表删除或更新且自动删除或更新子表中匹配的行
    2. SET NULL:从父表删除或更新行,并设置子表中的外键列为空,如果使用该选项,必须保证子表列没有指定 NOT NULL
    3. RESTRICT:拒绝对父表的删除或更新操作
    4. NOT ACTION:标准 SQL 的关键字,在 MySQL 中与 RESTRICT 相同

    给子表中添加 CASCADE 字段:

    # 创建一个子表 users1
    mysql> CREATE TABLE users1(
        -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
        -> username VARCHAR(10) NOT NULL,
        -> pid SMALLINT UNSIGNED,
        -> FOREIGN KEY (pid) REFERENCES province (id) ON DELETE CASCADE    # 将pid设置为外键,并添加 CASCADE 字段
        -> );
    Query OK, 0 rows affected (0.06 sec)
    
    # 查看 users1
    mysql> SHOW CREATE TABLE users1;
    +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                                                                                                                                                                                                                                                               |
    +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | users1 | CREATE TABLE `users1` (
      `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
      `username` varchar(10) NOT NULL,
      `pid` smallint(5) unsigned DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `pid` (`pid`),
      CONSTRAINT `users1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `province` (`id`) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.01 sec)
    
    # 给父表代表省份名称(pname)的列,插入三条记录(A/B/C)
    mysql> INSERT province(pname) VALUES('A');      
    Query OK, 1 row affected (0.01 sec)
    
    mysql> INSERT province(pname) VALUES('B');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> INSERT province(pname) VALUES('C');
    Query OK, 1 row affected (0.00 sec)
    
    # 查看插入记录(province)
    mysql> SELECT * FROM province;
    +----+-------+
    | id | pname |
    +----+-------+
    |  1 | A     |
    |  2 | B     |
    |  3 | C     |
    +----+-------+
    3 rows in set (0.00 sec)
    
    # 给子表插入三条记录
    mysql> INSERT users1(username,pid) VALUES('Tom',1);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> INSERT users1(username,pid) VALUES('Rose',2);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> INSERT users1(username,pid) VALUES('Alice',3);
    Query OK, 1 row affected (0.00 sec)
    
    # 查看插入记录(users1)
    mysql> SELECT * FROM users1;
    +----+----------+------+
    | id | username | pid  |
    +----+----------+------+
    |  1 | Tom      |    1 |
    |  2 | Rose     |    2 |
    |  3 | Alice    |    3 |
    +----+----------+------+
    3 rows in set (0.00 sec)
    

    需要注意的是,在插入记录时,首先要先插入父表,再插入子表,因为子表是参照父表来的。

    删除或更新父表中的行,将也会删除子表中匹配的行:

    # 删除 province 中 id 为 3 的 行
    mysql> DELETE FROM province WHERE id=3;
    Query OK, 1 row affected (0.01 sec)
    
    # 查看记录,发现 3 被删除了
    mysql> SELECT * FROM province;
    +----+-------+
    | id | pname |
    +----+-------+
    |  1 | A     |
    |  2 | B     |
    +----+-------+
    2 rows in set (0.00 sec)
    
    # 查看 子表users1 中 与 3 匹配的行也被删除了
    mysql> SELECT * FROM users1;
    +----+----------+------+
    | id | username | pid  |
    +----+----------+------+
    |  1 | Tom      |    1 |
    |  2 | Rose     |    2 |
    +----+----------+------+
    2 rows in set (0.00 sec)
    

    在外键约束当中,在实际的开发过程中,我们很少使用物理的外键约束,很多都去使用逻辑的外键约束,因为物理的外键约束只有INNODB这种引擎才会支持,像我们另外的一种引擎MYISAM的引擎则不支持,反过来说,如果我想创建的数据表,假设存储引擎为MYISAM,而且又想使用外键约束的话,其实是不可能实现的,所以说,我们在实际的项目开发中,我们不去定义物理的外键,所谓的逻辑外键指的是就是我们在定义两张表的结构的时候,我们是按照存在的某种结构的方式去定义,但是不去使用FOREIGN KEY这个关键词来定义。

    3.3.、表级约束与列级约束

    • 约束按功能划分,分为主键、唯一、默认和外键等。
    • 按照数据列数目的多少,可以将约束分成表级和列级约束。
    • 列级约束:对一个数据列建立的约束,它可以在列定义时声明,也可以在列定义后声明
    • 表级约束:对多个数据列建立的约束,只能在列定义后声明。
    • 列级比表级用的多(实际开发中),如 NOT NULLDEFAULT 约束不存在表级

    3.4、修改数据表(添加/删除)

    3.4.1、添加单列

    # 如果省略[FIRST | AFTER col_name],那么添加的列将是在最后
    # 也可以选择 FIRST 或 AFTER ,在哪列之前或之后
    # 要添加到所有列之前,只需使用命令:.... FIRST;即可
    ALTER TABLE tbl_name ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name]
    

    示例:

    # 查看 users1 的数据表结构
    mysql> SHOW COLUMNS FROM users1;
    +----------+----------------------+------+-----+---------+----------------+
    | Field    | Type                 | Null | Key | Default | Extra          |
    +----------+----------------------+------+-----+---------+----------------+
    | id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
    | username | varchar(10)          | NO   |     | NULL    |                |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |                |
    +----------+----------------------+------+-----+---------+----------------+
    3 rows in set (0.00 sec)
    
    # 添加 age 列
    mysql> ALTER TABLE users1 ADD age TINYINT UNSIGNED NOT NULL DEFAULT 10;
    Query OK, 0 rows affected (0.12 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # age 列排在最后
    mysql> SHOW COLUMNS FROM users1;
    +----------+----------------------+------+-----+---------+----------------+
    | Field    | Type                 | Null | Key | Default | Extra          |
    +----------+----------------------+------+-----+---------+----------------+
    | id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
    | username | varchar(10)          | NO   |     | NULL    |                |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |                |
    | age      | tinyint(3) unsigned  | NO   |     | 10      |                |
    +----------+----------------------+------+-----+---------+----------------+
    4 rows in set (0.00 sec)
    
    # 将 password 列添加到 username之后
    mysql> ALTER TABLE users1 ADD password VARCHAR(32) NOT NULL AFTER username;
    Query OK, 0 rows affected (0.11 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users1;
    +----------+----------------------+------+-----+---------+----------------+
    | Field    | Type                 | Null | Key | Default | Extra          |
    +----------+----------------------+------+-----+---------+----------------+
    | id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
    | username | varchar(10)          | NO   |     | NULL    |                |
    | password | varchar(32)          | NO   |     | NULL    |                |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |                |
    | age      | tinyint(3) unsigned  | NO   |     | 10      |                |
    +----------+----------------------+------+-----+---------+----------------+
    5 rows in set (0.00 sec)
    

    3.4.2、添加多列

    添加多列,不可以指定位置关系,只能位于最后

    ALTER TABLE tbl_name ADD [COLUMN] (col_name column_definition,...)
    

    3.4.3、删除列

    ALTER TABLE tbl_name DROP [COLUMN] col_name
    

    删除单、多列:

    # 删除多列,只需添加个逗号,后面再加 DROP col_name即可
    mysql> ALTER TABLE users1 DROP password,DROP age;      # 在删除的同时也可以添加列
    Query OK, 0 rows affected (0.12 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users1;
    +----------+----------------------+------+-----+---------+----------------+
    | Field    | Type                 | Null | Key | Default | Extra          |
    +----------+----------------------+------+-----+---------+----------------+
    | id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
    | username | varchar(10)          | NO   |     | NULL    |                |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |                |
    +----------+----------------------+------+-----+---------+----------------+
    3 rows in set (0.00 sec)
    

    3.4.4、添加约束

    原有的列上,有的有约束,有的没有,为此我们也可以给没有约束的添加约束,有约束的删除约束:

    (1)、添加主键约束:

    ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] PROMARY KEY [index_type] [index_col_name,...]
    

    示例:

    # 首先创建了一个数据表 users2,设置了2列,然后再添加一列(id),3个列都没有设置约束,现在我们要将 id 设置为主键约束
    # 创建数据表 users2
    mysql> CREATE TABLE users2(
        -> username VARCHAR(10) NOT NULL,
        -> pid SMALLINT(5) UNSIGNED
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   |     | NULL    |       |
    | pid      | smallint(5) unsigned | YES  |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    
    # 添加 id 列
    mysql> ALTER TABLE users2 ADD id SMALLINT UNSIGNED;
    Query OK, 0 rows affected (0.07 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   |     | NULL    |       |
    | pid      | smallint(5) unsigned | YES  |     | NULL    |       |
    | id       | smallint(5) unsigned | YES  |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    # 给 id 添加主键约束,可以给添加的约束取别名(这里为 PK_users2_id )
    mysql> ALTER TABLE users2 ADD CONSTRAINT PK_users2_id PRIMARY KEY(id);
    Query OK, 0 rows affected (0.07 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构(id 已被定义为主键约束)
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   |     | NULL    |       |
    | pid      | smallint(5) unsigned | YES  |     | NULL    |       |
    | id       | smallint(5) unsigned | NO   | PRI | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    

    (2)、添加唯一约束:

    ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] [index_col_name,...]
    

    示例:

    # 给 username 列添加唯一约束
    mysql> ALTER TABLE users2 ADD UNIQUE(username);
    Query OK, 0 rows affected (0.02 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   | UNI | NULL    |       |
    | pid      | smallint(5) unsigned | YES  |     | NULL    |       |
    | id       | smallint(5) unsigned | NO   | PRI | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    

    (3)、添加外键约束:

    ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition
    

    示例:

    # 给 pid 添加外键约束,参照列为 province 的 id
    mysql> ALTER TABLE users2 ADD FOREIGN KEY (pid) REFERENCES province (id);
    Query OK, 0 rows affected (0.09 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   | UNI | NULL    |       |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |       |
    | id       | smallint(5) unsigned | NO   | PRI | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    # 查看数据表
    mysql> SHOW CREATE TABLE users2;
    +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                                                                                                                                                                                                                                                                    |
    +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | users2 | CREATE TABLE `users2` (
      `username` varchar(10) NOT NULL,
      `pid` smallint(5) unsigned DEFAULT NULL,
      `id` smallint(5) unsigned NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `username` (`username`),
      KEY `pid` (`pid`),
      CONSTRAINT `users2_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `province` (`id`)  # 外键约束添加成功
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    

    (4)、添加/删除默认约束:

    ALTER TABLE tbl_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
    

    示例:

    # 我们添加了一列 age,再添加默认约束,值为15,再删除
    # 添加 age 列
    mysql> ALTER TABLE users2 ADD age TINYINT UNSIGNED NOT NULL;
    Query OK, 0 rows affected (0.07 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   | UNI | NULL    |       |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |       |
    | id       | smallint(5) unsigned | NO   | PRI | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)
    
    # 给 age 设置默认约束(值为15)
    mysql> ALTER TABLE users2 ALTER age SET DEFAULT 15;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   | UNI | NULL    |       |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |       |
    | id       | smallint(5) unsigned | NO   | PRI | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | 15      |       |
    +----------+----------------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)
    
    # 删除 age 列的默认约束
    mysql> ALTER TABLE users2 ALTER age DROP DEFAULT;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   | UNI | NULL    |       |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |       |
    | id       | smallint(5) unsigned | NO   | PRI | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)
    

    3.4.5、删除约束

    (1)、删除主键约束:

    # 删除主键约束时,不需要指定列名,因为一个数据表中,有且仅有一个主键约束
    ALTER TABLE tbl_name DROP PRIMARY KEY
    

    (2)、删除唯一约束:

    ALTER TABLE tbl_name DROP {INDEX|KEY} index_name(索引名字)
    # 需要注意的是,删除的是约束而不是字段(列),所以需要指定索引名字
    

    示例:

    # 查看users2结构,username 有个唯一约束(PRI),首先我们找到约束的索引名字(Key_name),再根据索引名字删除约束
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   | PRI | NULL    |       |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |       |
    | id       | smallint(5) unsigned | NO   |     | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)
    
    # 查看索引结构
    mysql> SHOW INDEXES FROM users2;
    +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | users2 |          0 | username |            1 | username    | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
    | users2 |          1 | pid      |            1 | pid         | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
    +--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    2 rows in set (0.00 sec)
    
    # 查看索引结构,以网盘的形式显示
    mysql> SHOW INDEXES FROM users2G;
    *************************** 1. row ***************************
            Table: users2
       Non_unique: 0
         Key_name: username         # 索引名字为(username)
     Seq_in_index: 1
      Column_name: username
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null:
       Index_type: BTREE
          Comment:
    Index_comment:
    *************************** 2. row ***************************
            Table: users2
       Non_unique: 1
         Key_name: pid
     Seq_in_index: 1
      Column_name: pid
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null: YES
       Index_type: BTREE
          Comment:
    Index_comment:
    2 rows in set (0.00 sec)
    
    ERROR:
    No query specified
    
    # 删除唯一约束
    mysql> ALTER TABLE users2 DROP INDEXES username;
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'username' at line 1
    mysql> ALTER TABLE users2 DROP INDEX username;
    Query OK, 0 rows affected (0.09 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构(唯一约束已被删除)
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   |     | NULL    |       |
    | pid      | smallint(5) unsigned | YES  | MUL | NULL    |       |
    | id       | smallint(5) unsigned | NO   |     | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)
    

    (3)、删除外键约束:

    ALTER TABLE tbl_name DROP FOREIGN KEY fk_symblo(约束的名字)
    

    示例:

    # 要删除外键约束,需要先知道外键约束的名字
    # 查看约束名字
    mysql> SHOW CREATE TABLE users2;
    +--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                                                                                                                                                                                                                                              |
    +--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | users2 | CREATE TABLE `users2` (
      `username` varchar(10) NOT NULL,
      `pid` smallint(5) unsigned DEFAULT NULL,
      `id` smallint(5) unsigned NOT NULL,
      `age` tinyint(3) unsigned NOT NULL,
      KEY `pid` (`pid`),
      CONSTRAINT `users2_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `province` (`id`)  # 名字为 users2_ibfk_1
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    # 删除外键约束(pid)
    mysql> ALTER TABLE users2 DROP FOREIGN KEY users2_ibfk_1;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看约束
    mysql> SHOW CREATE TABLE users2;
    +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                                                                                                                                                               |
    +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | users2 | CREATE TABLE `users2` (
      `username` varchar(10) NOT NULL,
      `pid` smallint(5) unsigned DEFAULT NULL,
      `id` smallint(5) unsigned NOT NULL,
      `age` tinyint(3) unsigned NOT NULL,
      KEY `pid` (`pid`)    # 外键约束已被删除,但是 pid 索引还在
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    # 也可以删除 pid 索引
    mysql> ALTER TABLE users2 DROP pid;
    Query OK, 0 rows affected (0.07 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看约束
    mysql> SHOW CREATE TABLE users2;
    +--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                                                                                               |
    +--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | users2 | CREATE TABLE `users2` (
      `username` varchar(10) NOT NULL,
      `id` smallint(5) unsigned NOT NULL,
      `age` tinyint(3) unsigned NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    +--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    

    3.4.6、修改列定义和更改数据表

    上面我们了解了如何添加或删除列的约束,或者整个列,其实我们还可以修改列的定义(如列名、列的位置、数据类型等)

    (1)、修改列定义:

    ALTER TABLE tbl_name MODIFY [COLUMN] col_name column_definition  [FIRST | AFTER col_name]
    

    调整列的位置:

    # 将 id 的位置调到首位
    # 查看数据表结构,发现 id 在 第二位
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | username | varchar(10)          | NO   |     | NULL    |       |
    | id       | smallint(5) unsigned | NO   |     | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    # 将 id 移动至首位(因为我们只是改变位置,数据类型照抄,不改变)
    mysql> ALTER TABLE users2 MODIFY id SMALLINT UNSIGNED NOT NULL FIRST;  # 不改变数据类型
    Query OK, 0 rows affected (0.08 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | id       | smallint(5) unsigned | NO   |     | NULL    |       |
    | username | varchar(10)          | NO   |     | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    

    也可以修改列的数据结构,但是要注意的是“从大的数据结构修改到小的,可能会导致数据的丢失”

    # 将 id 的数据结构修改为 TINYINT
    ALTER TABLE users2 MODIFY id TINYINT UNSIGNED NOT NULL ;
    

    (2)、修改列名称:

    # 既可以修改列名也可以修改数据结构
    ALTER TABLE tbl_name CHANGE [COLUMN] old_name new_clo_name column_definition  [FIRST | AFTER col_name]
    

    示例:

    # 将 age 列名修改为 user_age,并将其数据类型修改为 SMALLINT
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | id       | smallint(5) unsigned | NO   |     | NULL    |       |
    | username | varchar(10)          | NO   |     | NULL    |       |
    | age      | tinyint(3) unsigned  | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    # 修改列名和数据结构
    mysql> ALTER TABLE users2 CHANGE age user_age SMALLINT UNSIGNED NOT NULL;
    Query OK, 0 rows affected (0.10 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    # 查看数据表结构
    mysql> SHOW COLUMNS FROM users2;
    +----------+----------------------+------+-----+---------+-------+
    | Field    | Type                 | Null | Key | Default | Extra |
    +----------+----------------------+------+-----+---------+-------+
    | id       | smallint(5) unsigned | NO   |     | NULL    |       |
    | username | varchar(10)          | NO   |     | NULL    |       |
    | user_age | smallint(5) unsigned | NO   |     | NULL    |       |
    +----------+----------------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    

    (3)、修改数据表名称:

    # 方法1
    ALTER TABLE tbl_name RENAME [TO|AS] new_tbl_name
    
    # 方法2
    # 一般情况不建议更改数据表和数据库名称,如果中间有引用了数据库或数据表名字,修改了名字可能导致存储错误
    RENAME TABLE tbl_name TO new_tbl_name [, tbl_name2 TO new_tbl_name2]...
    

    方法一示例:

    # 将 users2 修改为 users3
    mysql> ALTER TABLE users2 RENAME users3;
    Query OK, 0 rows affected (0.03 sec)
    
    # 查看当前数据库下数据表
    mysql> SHOW TABLES;
    +----------------+
    | Tables_in_test |
    +----------------+
    | province       |
    | tb1            |
    | tb2            |
    | tb3            |
    | tb4            |
    | tb5            |
    | tb6            |
    | users          |
    | users1         |
    | users3         |
    +----------------+
    10 rows in set (0.00 sec)
    

    方法二示例:

    # 将 users3 修改为 users2
    mysql> RENAME TABLE users3 TO users2;
    Query OK, 0 rows affected (0.01 sec)
    
    # 查看当前数据库下的数据表
    mysql> SHOW TABLES;
    +----------------+
    | Tables_in_test |
    +----------------+
    | province       |
    | tb1            |
    | tb2            |
    | tb3            |
    | tb4            |
    | tb5            |
    | tb6            |
    | users          |
    | users1         |
    | users2         |
    +----------------+
    10 rows in set (0.00 sec)
    

    3.5、小结

    约束及修改数据表

  • 相关阅读:
    中国骨干网节点
    Linux命令整理
    centos6.5安装mysql
    mysql插入中文乱码问题
    Intellij Idea使用及配置
    IntelliJ IDEA像Eclipse一样打开多个项目
    IntelliJ IDEA14如何配置tomcat
    转:IntelliJ IDEA 2016.1.3注册破解激活
    IntelliJ Idea 快捷键
    CXF生成调用webservice的客户端
  • 原文地址:https://www.cnblogs.com/midworld/p/13617351.html
Copyright © 2011-2022 走看看