MYSQL创建/删除外键

创建外键的条件

1、所关联字段数量、顺序要一一对应;
2、所关联的字段数据类型一致。
3、所关联的字段必须是主键,或者是被包含在唯一索引中且在唯一索引中必须处于开头部分。

以第3条为例:
a表唯一索引:
    (`school_no`,`grade_no`,`class_no`,`student_no`)
b表唯一索引:
    (`book_no`,`create_time`,`school_no`,`grade_no`,`class_no`,`personnel_no`)
此时
a表的(`school_no`,`grade_no`,`class_no`,`student_no`)
和
b表的(`school_no`,`grade_no`,`class_no`,`personnel_no`)
无法创建外键,需要改变b表的索引顺序或者新增b表的索引为:
(`school_no`,`grade_no`,`class_no`,`personnel_no`,`book_no`,`create_time`)

创建方法(以学生表和借书记录表为例)

方法一:建表时创建

/*先创建一张学生表*/
/*指定`school_no`,`grade_no`,`class_no`,`student_no`为唯一索引*/
CREATE TABLE `student_info` (
  `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `school_no` BIGINT(20) NOT NULL COMMENT '学校编号',
  `grade_no` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '年级编号',
  `class_no` VARCHAR(64) NOT NULL COMMENT '班级编号',
  `student_no` VARCHAR(64) NOT NULL COMMENT '学生编号',
  `student_name` VARCHAR(64) NOT NULL COMMENT '学生姓名',
  `student_id` VARCHAR(18) DEFAULT NULL COMMENT '身份证ID',
  `address` TEXT NOT NULL COMMENT '住址',
  `guardian` VARCHAR(64) NOT NULL COMMENT '监护人',
  `guardian_tel` VARCHAR(16) NOT NULL COMMENT '监护人联系号码',
  `head_portrait_url` TEXT COMMENT '头像url',
  `head_portrait_key` TEXT COMMENT '头像key',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '修改/创建时间',
  `remarks1` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks2` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks3` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks4` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks5` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `student_no` (`school_no`,`grade_no`,`class_no`,`student_no`)
) ENGINE=INNODB AUTO_INCREMENT=259 DEFAULT CHARSET=utf8 COMMENT='学生信息'
/*创建学生借书表*/
/*指定`school_no`,`grade_no`,`class_no`,`personnel_no`,`book_no`,`create_time`为唯一索引*/
/*相关字段与学生表关联产生外键*/
CREATE TABLE `book_outbound_student_details` (
  `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `school_no` BIGINT(20) NOT NULL COMMENT '学校编号',
  `grade_no` VARCHAR(64) NOT NULL COMMENT '年级编号',
  `class_no` VARCHAR(64) NOT NULL COMMENT '班级编号',
  `personnel_no` VARCHAR(64) NOT NULL COMMENT '人员编号',
  `book_no` DECIMAL(10,0) NOT NULL COMMENT '图书编号',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '借阅时间',
  `appoint_return_time` DATETIME DEFAULT NULL COMMENT '约定归还时间',
  `actual_return_time` DATETIME DEFAULT NULL COMMENT '实际归还时间',
  `book_state` VARCHAR(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '0、已归还;1未归还;2、丢失未赔偿;3、丢失已赔偿;4、已经购买',
  `amount` DOUBLE(8,2) DEFAULT NULL COMMENT '赔偿/购买金额',
  `rental` DOUBLE(8,2) DEFAULT NULL COMMENT '租金',
  `lease_quantity` INT(10) NOT NULL COMMENT '租借数量',
  `remarks1` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作人',
  `remarks2` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks3` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks4` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks5` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `school_no` (`school_no`,`grade_no`,`class_no`,`personnel_no`,`book_no`,`create_time`),
  CONSTRAINT `book_outbound_student_details_ibfk_1` FOREIGN KEY (`school_no`, `grade_no`, `class_no`, `personnel_no`) REFERENCES `student_info` (`school_no`, `grade_no`, `class_no`, `student_no`)
) ENGINE=INNODB AUTO_INCREMENT=330 DEFAULT CHARSET=utf8 COMMENT='学生借书记录'

方法二:建表后创建

/*先创建一张学生表*/
/*指定`school_no`,`grade_no`,`class_no`,`student_no`为唯一索引*/
CREATE TABLE `student_info` (
  `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `school_no` BIGINT(20) NOT NULL COMMENT '学校编号',
  `grade_no` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '年级编号',
  `class_no` VARCHAR(64) NOT NULL COMMENT '班级编号',
  `student_no` VARCHAR(64) NOT NULL COMMENT '学生编号',
  `student_name` VARCHAR(64) NOT NULL COMMENT '学生姓名',
  `student_id` VARCHAR(18) DEFAULT NULL COMMENT '身份证ID',
  `address` TEXT NOT NULL COMMENT '住址',
  `guardian` VARCHAR(64) NOT NULL COMMENT '监护人',
  `guardian_tel` VARCHAR(16) NOT NULL COMMENT '监护人联系号码',
  `head_portrait_url` TEXT COMMENT '头像url',
  `head_portrait_key` TEXT COMMENT '头像key',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '修改/创建时间',
  `remarks1` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks2` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks3` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks4` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks5` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `student_no` (`school_no`,`grade_no`,`class_no`,`student_no`)
) ENGINE=INNODB AUTO_INCREMENT=259 DEFAULT CHARSET=utf8 COMMENT='学生信息'
/*创建学生借书记录表*/
/*指定`school_no`,`grade_no`,`class_no`,`personnel_no`,`book_no`,`create_time`为唯一索引*/
CREATE TABLE `book_outbound_student_details` (
  `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `school_no` BIGINT(20) NOT NULL COMMENT '学校编号',
  `grade_no` VARCHAR(64) NOT NULL COMMENT '年级编号',
  `class_no` VARCHAR(64) NOT NULL COMMENT '班级编号',
  `personnel_no` VARCHAR(64) NOT NULL COMMENT '人员编号',
  `book_no` DECIMAL(10,0) NOT NULL COMMENT '图书编号',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '借阅时间',
  `appoint_return_time` DATETIME DEFAULT NULL COMMENT '约定归还时间',
  `actual_return_time` DATETIME DEFAULT NULL COMMENT '实际归还时间',
  `book_state` VARCHAR(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '0、已归还;1未归还;2、丢失未赔偿;3、丢失已赔偿;4、已经购买',
  `amount` DOUBLE(8,2) DEFAULT NULL COMMENT '赔偿/购买金额',
  `rental` DOUBLE(8,2) DEFAULT NULL COMMENT '租金',
  `lease_quantity` INT(10) NOT NULL COMMENT '租借数量',
  `remarks1` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作人',
  `remarks2` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks3` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks4` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  `remarks5` VARCHAR(1) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `school_no` (`school_no`,`grade_no`,`class_no`,`personnel_no`,`book_no`,`create_time`)
) ENGINE=INNODB AUTO_INCREMENT=330 DEFAULT CHARSET=utf8 COMMENT='学生借书记录'
/*创建表后,执行下面SQL创建外键。*/
ALTER TABLE book_outbound_student_details ADD FOREIGN KEY (`school_no`,`grade_no`,`class_no`,`personnel_no`)
REFERENCES   `student_info`(`school_no`,`grade_no`,`class_no`,`student_no`); 

/*总结格式*/
/*注意:字段顺序和字段数量要一一对应。*/
ALTER TABLE 子表 ADD FOREIGN KEY (字段1,字段2,……) REFERENCES 父表(字段1,字段2,……); 

查看唯一索引的字段排列顺序

/*方法一:直接查询*/
SELECT * FROM mysql.`innodb_index_stats` a WHERE a.`database_name` = '数据库名' AND 
a.table_name="表名称" ;
/*方法二(推荐):查询表结构*/
SHOW CREATE TABLE 表名称

查询外键

book_outbound_student_details_ibfk_3;
 SELECT C.TABLE_SCHEMA            拥有者,
           C.REFERENCED_TABLE_NAME  父表名称 ,
           C.TABLE_NAME             子表名称,
           C.REFERENCED_COLUMN_NAME 父表字段 ,
           C.COLUMN_NAME            子表字段,
           C.CONSTRAINT_NAME        约束名,
           T.TABLE_COMMENT          表注释,
           R.UPDATE_RULE            约束更新规则,
           R.DELETE_RULE            约束删除规则
      FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE C
      JOIN INFORMATION_SCHEMA. TABLES T
        ON T.TABLE_NAME = C.TABLE_NAME
      JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
        ON R.TABLE_NAME = C.TABLE_NAME
       AND R.CONSTRAINT_NAME = C.CONSTRAINT_NAME
       AND R.REFERENCED_TABLE_NAME = C.REFERENCED_TABLE_NAME
      WHERE C.REFERENCED_TABLE_NAME IS NOT NULL 
AND       C.TABLE_SCHEMA ='数据库名称' AND C.REFERENCED_TABLE_NAME='父表名称' ;   

删除外键

/*通过上方查询到约束名,然后删除约束名。*/
 ALTER TABLE `book_outbound_student_details` DROP FOREIGN KEY 约束名; 
/*总结格式*/
 ALTER TABLE 子表 DROP FOREIGN KEY 约束名; 

相关错误码

1822: 
    相关字段不存在主键或所关联字段不包含在唯一索引的头部,参考上述创建外键条件的第3条规则。
3780:
    数据类型不匹配。
1239:
    匹配字段数量不一致。

相关博客

  • MYSQL如何添加/删除唯一约束;
  • JAVA处理MYSQL唯一索引异常;
  • MYSQL总结。

你可能感兴趣的:(MySQL)