牛腩新闻发布系统---外键约束下如何删除记录

一、为什么使用外键?

查了些资料,八个字“保持完整性、一致性”,结合我之前做的重构机房收费系统,我的理解是“防止相关表中数据没有关联而变得孤立,最终导致数据冗余”,得出这个结论是上次让贾丽敏帮忙点系统时候我最深刻的感受,因为我的数据库关系图中辣么多张表却没有丝毫关系……

既然官方解释是“完整性和一致性”,就先来说明一下:

对于完整性和一致性,不少人都混为一谈了。

完整性(integrity)更多是针对实际业务来说的,比如说一个职员ID,不能在一个表里是1,另一个表里却是2;数据库引擎一般通过主外键、触发器等来维护完整性的。

一致性(consistency)是事务一个特征,要底层一点。举例来说,针对这个语句:update a set col1=1,col2=2 where id=1(更改一行数据的两列),数据库要保证在任何情况下,都绝不能出现只更改了col1,或只更改了col2的情况,这两列(col1和col2)要么一起被改,要么都没改。还包括内部的索引结构、内部数据字典等数据都要绝对保持一致。

这个说明来自互联网,当然这一点还是要在项目中慢慢的去体会的。

二、外键约束下如何删除相关表中的信息?

如上图所示,从左到右将其定义为1、2、3层,就像是我们三层里的U、B、D那样,一环扣一环,显然右侧是最深的一层,或者称之为底层;左侧是最浅的一层,或者称之为表层。

很显然,删除表层的数据是很随意的,because它不会对其他层有任何影响,而删除中间层和底层的数据的时候,会影响上层建筑,就像我在王聚博客里看到的一个比喻,将其比喻为一座大厦,拆楼的时候是从上向下的,一层一层分解,如果直接去拆地下室,那么整个楼不就崩溃坍塌了吗?

所以这就是第一种用于删除外键约束下的数据的方法的思想:逐层分解

    方法一:通过触发器实现

就拿《牛腩新闻发布系统》的例子来说:

-- =============================================
-- Author:张振华
-- Create date:2015年月日:01:29
-- Description:	删除类别触发器
-- =============================================
ALTER TRIGGER trigCategoryDelete
   ON  Category
   instead of DELETE
AS
BEGIN
   --声明一个
   declare @caId int
   select @caId=id from deleted
   --删除评论(此处使用子查询,查询出的条件是多条,于是使用”in”而不是”=”)
   delete comment where newsId in (select newsId from news where [email protected])
   --删除新闻
   delete news where [email protected]
   --删除类别
   delete category where [email protected]
END
GO

这种方法的好处:不会破坏主外键的约束,保证完整性和一致性的同时,保证数据不会产生冗余,也不会造成误删而出现数据残缺的现象。同时,这种方法是在数据库里进行限制,使得在编程过程中直接使用该约束就OK,不用再次做其他逻辑上的约束。

另一种用于删除外键约束下数据的思想是:连根拔起

   方法二:级联删除

这种方法在重构机房的时候就接触过,只是迫于当时时间压力,把表中所有外键删除掉了,发现反而在程序中做好多逻辑上的约束,反而效果不怎么好,防不胜防。这次正好将这种方法学会。

所谓级联删除,就是删除主表记录同时删除从表中有外键关系的记录。

-- =============================================
-- Author:张振华
-- Create date:2015年7月5日
 -- Description:	级联删除举例
-- =============================================

create table category
(
id varchar(20) primary key,
name varchar(20) not null
)

create table news
(
--自增字段充当主键
id int identity(1,1) primary key,
title varchar(50) not null,
content varchar(50) not null,
--表news创建了外键caId 对应category表的主键id,同时声明了级联删除
caId varchar(20),
--on delete:删除级联
foreign key (caId) references category(id) on delete cascade
)

这样建表之后,如果在表中category中添加“体育新闻”,将其删除之后,在news表中所有关于caId是“体育新闻”的记录都会被删除。

由于是刚刚接触级联删除,和上面“逐层删除”相比,这种方法更像是将整栋楼“爆破”,从底层到上层建筑全部删掉,删除彻底,同时能保持数据的完整性以及一致性,我的感觉,有一点既是这样做的好处也是坏处就是,删除过于彻底,有点“连根拔起、一人犯罪,株连九族”的感觉,删除后没有冗余数据,但是过于彻底有可能会删除一些有用信息。

最后介绍最简单的一种方法,我将其思想定义为:解除合约

   方法三:

情景:如果需要删除底层的数据,但是表层的一些数据需要保留,也就是说仅仅需要删除一部分数据,怎么办?

暂时接触外键约束,将底层表中数据删除之后再加上外键约束,可能这样做会有种“脱掉裤子放屁”的感觉,但是对于仅仅删除一部分数据,尤其是底层数据的时候,这将是一种很好的方法,当然如果数据量大的话,这种方法还是不太好,但是至少这是解决问题的一种途径。

三、Summary

   扩展:

在设置外键约束的条件下,删除会受到约束的限制,那么“增、改、查”会受到外键的约束吗?

我猜测,“改”会受到限制,其他两个不会,大家也可以尝试去做做这样的实验,当然仅仅是自己的猜测,有待验证。

   收获:

在做重构机房收费系统的时候,就遗留了一个问题,设计数据库的过程中,因为主键冲突以及外键约束,导致我不得不删掉了当初设置的外键约束,而这样做的后果就是关系数据库的完整性和一致性遭到破坏。学习了牛腩的“删除外键约束条件下的数据”,让我解决掉了这个遗留问题,现在记录我的学习过程。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 06:15:47

牛腩新闻发布系统---外键约束下如何删除记录的相关文章

MySQL学习10:外键约束下的更新操作

上一篇只是讲述了外键约束的要求,并没有讲述外键约束的参照操作.这一次我来看看外键约束下的更新操作. 一外键约束的参照操作 我们进行外键约束的创建以后,在更新表的时候,子表是否也进行相应的更新.这是我们创建外键约束最大的好 处.有以下几种: 1)CASCADE:从父表删除或更新且自动删除或更新子表中匹配的行. 2)SET NULL:从父表删除或更新行,并设置子表中的外键列为NULL.如果使用该选项,必须保证子表列没有指 定NOT NULL. 3)RESTRICT:拒绝对父表的删除或更新操作. 4)

牛腩新闻发布系统-出错集锦(1)

在学习牛腩新闻发布系统的时候遇到了一些错误,并得出了一些解决方案,分享给大家. 错误一.由于"DAL.SQLHelper.test()"返回 void,返回关键字后面不得有对象表达式E:\提高班\进行中\牛腩新闻发布系统\DAL\SQLHelper.cs2613DAL 代码如下: public void test() { string [email protected]"server=qiwei; database=newssystem; uid=sa; pwd=123456

牛腩新闻发布系统--重构SQL Helper

天外有天,人外有人.自我进提高班以来,一直都在考虑,先前重构机房的时候,看到别人在D层加了SQL Helper,就一定要学者加上玩玩,等做完了以后,进行下一个阶段牛腩的时候,又看到了人家建的SQL Helper,不觉感慨,跟人家比,人家就是我的老师! 闲话就不多说了,进行正式的话题:如何写好SQL Helper?从宏观上讲,SQL Helper是完全体现了面向对象的抽象和封装的思想的.它对重复代码抽取出来,进行抽象,抽象就是为了封装,提高了代码的复用. 那么就该讨论怎么写的问题.如果我先上来给大

牛腩新闻发布系统-零碎拾起

在牛腩新闻发布系统的学习过程中,学到了很多的知识点.将点滴记录汇聚于此. 一.IP地址最后一位变"*"     <span style="font-size:18px;">string str = "127.0.0.1"; str = str.Substring(0, str.LastIndexOf(".") + 1); Response.Write(str + "*");</span&g

牛腩新闻发布系统总结——网站发布和分页制作

牛腩新闻发布系统的视频看了将近半个月的时间,今天成功地把它发布了,哈哈.第一次看教学视频看得这么专注,都不带走思的,很不错.给小牛老师赞一个,嘿嘿! 言归正传,每学完一个阶段,最重要的就是总结,所以就允许我以倒序的形式,颗粒归仓吧! 牛腩新闻发布系统的发布 参考博文: win7下IIS的安装和配置 http://www.jb51.net/article/29787.htm VS2010网站发布详解 http://wanghaitaoboke.blog.163.com/blog/static/17

【牛腩新闻发布系统】----你的验证码正确么

前言 这是一个神奇的网站--牛腩新闻发布系统,虽然做的不咋地,但毕竟是自己动手敲出来,还是有一点点的满足感.同时这也是小编的第一个雠小鸭,长相不算漂亮,发育还是挺健全的. 终有一天我的丑小鸭会变成白天鹅. 一步一步的进化,一步一步的蜕变-- 你的验证码正确么 哎呀--为什么我的牛腩新闻发布系统   请输入验证码的图片一直为这个样子呀--不显示,就是不显示图片,图片加载出错呀.想想估计是图片路径不正确. 尝试一:牛老师说的图片加载路径 <img src="handler/WaterMark.

牛腩新闻发布系统-验证码搞通了吗?详细注释-秒懂

牛腩新闻发布系统添加新闻和登录界面用到了验证码,生活中经常遇到形形色色的验证码,数字和字母的,12306图片形式的,百度贴吧文字形式的等等.当时见得时候感觉很神奇,现在刚好学到了,感觉很有意思,接触了BS之后,越来越多的网页神秘的内容,会慢慢的被了解,这种渴望的感觉特别棒.见到了自己喜欢的那就应该认真的分析,理解验证码的产生,这里说的是数字和字母类型的,从简单的入手. 什么是验证码,它是干什么的? 验证码:是一种区分用户是计算机还是人的公共全自动程序.可以防止:恶意破解密码.刷票.论坛灌水,有效

【牛腩新闻发布系统 二】发布后,防火墙关还是不关?

在对牛腩进行发布的时候遇到了问题,别人不能访问我发布的网站.这有个特别简单的办法,那就是直接把防火墙关闭不就得了吗?可是关闭了防火墙,我们的系统就不受保护了,别人可以随意访问我们的电脑啊,这太不安全了.所以我们要想办法在不关闭防火墙的前提下,给其他用户一个权限,他只能访问这一个端口的网站,其他的不能访问,那就要对防火墙进行设置. 1.依次打开"控制面板"--"系统和安全"--"Windows防火墙"如下图,选择"高级设置" 2

牛腩新闻发布系统总结(一)——总体感受

牛腩新闻发布系统的学习差不多用了一个月,我对它的总体评价是"麻雀虽小,五脏俱全",这是我第一次开始接触网页设计,当我把它设计完时,满满的都是成就感,虽然自己按着牛老师的意思做的,不过依旧非常开心. 牛老师的视频看完我首先想说,他是个特别有耐心,全心全意为人民服务的人,完全从初学者的角度出发,第一个让我想看他其他视频的人,这个系统虽然说很小,不过每一步设计都都很关键,很准确,让我这个没有接触过完整项目开发的人不至于跑偏. 首先是项目设计思路:文档编写(数据库设计说明书. 概要说明书.详细