设为首页收藏本站
查看: 57|回复: 0

[PHP] 【Mysql】外键级联与级联的劣势_MySQL

[复制链接]

论坛元老

Rank: 6Rank: 6

积分
34274
主题
17031
UID
1347
M币
67
贡献
17176

  • 发表于 2017-5-12 16:11:00 | 显示全部楼层 |阅读模式
    在建表的时候时候,可以对于删除delete、修改update设置为级联。用一个例子先说明外键级联级联的概念
    假如数据库中本以存在一张usertable如下:


    此user表非常简单,id为主键。
    下面我将新建一张cascade_test表如下,这里的user_id与usertable的主键id形成参照完整性,并同时建立删除与修改的级联:


    如果用SQL语句建立上图的表则如下:
      
      CREATE TABLE `test`.`cascade_test` ( `id` INTEGER UNSIGNED NOT NULL auto_increment, `content` TEXT, `user_id` INTEGER UNSIGNED, -- 由于usertable的主键是INTEGER UNSIGNED,这里必须同为这样类型,键值对应 PRIMARY KEY (`id`), CONSTRAINT `FK_cascade_test_1` FOREIGN KEY `FK_cascade_test_1` (`user_id`) REFERENCES `test`.`usertable`(`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB; -- 数据库引擎设置,可以没有 比起普通设置外键的语句,在其下多出了两个级联的声明,ON DELETE CASCADE、ON UPDATE CASCADE  
    设置级联与不设置级联,在参照完整性上是没有区别的。
    user的id类型是怎么cascade_test的user_id类型就应该怎么样,这里需要严格照抄,由于user的id设置为无符号整形,这里cascade_test的user_id还不能是整形,一定要特意声明为无符号整形,否则会出现如下的[Err] 1005 - Can't create table 'xx' (errno: 150),其实150页就是参照完整性错误。


    之后,在新建出来的cascade_test插入如下一些数据:


    同样地,由于参照完整性的存在,cascade_test的user_id的取值范围还需要在user的id现有的值来取。
    设置级联与不设置级联唯一的区别,就是我们在删除user的id中数据的同时,同样会删除cascade_test的user_id的所有有关字段。修改级联同样如此。
    比如将user中id为6的项删除,也就是执行如下的语句:
      
      delete from usertable where id=6  
    运行效果如下图:


    usertable中id=6的项被删除是肯定的,
    由于删除级联的存在:cascade_test中user_id=6的项通通被删除。
    如果不设置级联,在usertable中id=6的项被删除的同时,cascade_test中user_id=6的项是不会删除的。造成了一定参照完整性的缺失。
    下面说说级联的劣势:
    这看来似乎很强大的样子,尤其是在网页编程的时候,就不用写这么多删除语句了,仅仅是删除一个主键,就能把所有涉及的项删除
    但是,在你的工程足够的时候,这样的删除会很慢,实质上造成了表与表之间的耦合。远远比不删新增加一个isDel的项,使用标志删除的方式,查表的时候仅查询isDel=false的项。其实delete语句在网页的编程的时间根本就是可以扔掉的。这样还有个好处,出现在需要找被删除的旧数据的时候,绝对可以找回来。
    这样你的网页的运行速度会大大加快,否则如果一旦执行级联删除的语句,会涉及的表足够多的时候,执行起来将会足够慢。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    在我站开通SVIP可同时获得17个站点VIP资源 立即登录 立即注册
    快速回复 返回顶部 返回列表