当数据库遇上外键

现在在一个数据库中,用以下命令建两张表(课程性质和grade表)

关系如下图所示:(grade中的课程性质是课程性质表的外键)

 建表语句如下:

DROP TABLE IF EXISTS `课程性质`;

CREATE TABLE `课程性质` (

  `id` int(11) NOT NULL,

  `课程性质` varchar(30) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `课程性质` (`课程性质`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

DROP TABLE IF EXISTS `grade`;

CREATE TABLE `grade` (

  `课程代码` varchar(6) NOT NULL,

  `课程名称` varchar(50) DEFAULT NULL,

  `课程性质` varchar(30) DEFAULT NULL,

  `期末成绩` double DEFAULT NULL,

  `总评成绩` double DEFAULT NULL,

  `课程学分` double DEFAULT NULL,

  PRIMARY KEY (`课程代码`),

  KEY `课程性质` (`课程性质`),

  CONSTRAINT `grade_ibfk_1` FOREIGN KEY (`课程性质`) REFERENCES `课程性质` (`课程性质`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

当你想在grade表中插入以下的记录的时候:运行如下语句

(语句一)

INSERT INTO `grade` VALUES ('000042', '大学语文', '通识教育必修课', '78', '78', '2');

 

这时你可能发现插入不了,发现你有外键依赖不能插入该记录

所以你先执行如下:运行如下语句

(语句二)

INSERT INTO `课程性质` VALUES ('1', '通识教育必修课');

这时你可能以为这次再次运行(语句一)

INSERT INTO `grade` VALUES ('000042', '大学语文', '通识教育必修课', '78', '78', '2');

没问题了吧?

你发现还是错了!!!(不要担心,这还是可恶的外键搞得鬼)

 

最后你会百度得到以下解决方案

原来要改成如下语句才可实现你所想要达成的效果

(语句三)

INSERT INTO `grade` VALUES ('000042', '大学语文',(select  `课程性质` from  `课程性质` where  `课程性质`='通识教育必修课'), '78', '78', '2');

   这下你会发现真的可以了。

 但是有时候你会发现有时并不需要这么麻烦,而且这样为了插入一条数据还得提前查询一次,肯定影响了数据库的性能

  有时候你会很庆幸你不用这么做,有的时候你还非得这么做

  那怎么办呢?

  可以将其写成存储过程,从而提高一点其执行速率。(推荐使用存储过程)

   综上所述,建立外键是个可以建立数据库中列与列的限制关系,但是无疑会增加服务器资源的消耗,编写sql语句的复杂度增加,所以在大型的数据库中能少用则少用。