原文:数据库开发——参照完整性——在外键中使用Delete on cascade选项

原文:

http://www.mssqltips.com/sqlservertip/2743/using-delete-cascade-option-for-foreign-keys/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012731

参照完整性在设计数据库时需要重视,在我作为DBA的生涯中,看到很多设计走了极端的路子。

在进入DELETE CASCADE选项的详细说明前,先来看看另外一个选项,可以在具有外键的表中设置UDPATE CASCADE选项。在我的工作生涯中,我从来没有遇到过必须通过外键来更新一列或多列。

创建实例表:

在本例中,创建两个表,并用外键关联起来。主表有99999行记录,子表对于每条父记录,有19条记录。下面是创建语句:

-- Table creation logic

--parent table

CREATE TABLE[dbo].[Order](

[OrderID] [bigint] NOT NULL,

[OrderData] [varchar](10)NOT NULL,

CONSTRAINT [PK_Order_1] PRIMARY KEY CLUSTERED

([OrderID]ASC)

)

GO

-- child table

CREATE TABLE[dbo].[OrderDetail](

[OrderDetailID] [bigint] NOT NULL,

[OrderID] [bigint] NULL,

[OrderData] [varchar](10)NULL,

CONSTRAINT [PK_OrderDetail] PRIMARY KEY CLUSTERED

([OrderDetailID]ASC)

)

GO

-- foreign key constraint

ALTER TABLE[dbo].[OrderDetail] WITH CHECK

ADD CONSTRAINT[FK_OrderDetail_Order] FOREIGNKEY([OrderID])

REFERENCES [dbo].[Order]([OrderID])

ON DELETECASCADE

GO

-- data load

DECLARE @val BIGINT

DECLARE @val2 BIGINT

SELECT @val=1

WHILE @val< 100000

BEGIN

INSERT INTO dbo.[Order]VALUES(@val,'TEST'+ CAST(@valAS VARCHAR))

SELECT @val2=1

WHILE @val2 < 20

BEGIN

INSERT INTO dbo.[OrderDetail]VALUES ((@val*100000)+@val2,@val,'TEST'+ CAST(@valAS VARCHAR))

SELECT @val2=@val2+1

END

SELECT @val=@val+1

END

GO

第一个例子:

现在先让我们从[Order]表中移除一条数据,注意,我在每个查询中使用了DBCC DROPCLEANBUFFERS,来确保缓存中没有数据:

DBCC DROPCLEANBUFFERS

GO

DELETE FROM[Order] WHERE OrderID=24433

GO

在运行上面语句之后,可以查询[OrderDetail]表来确认记录是否已经被移除。这是为了了解,我们没有使用DELETE CASCADE选项时,要做什么操作,来确保数据移除,并看到他们的结果:

SELECT * FROM orderdetail WHERE orderid=24433

执行以后可以发现是没有数据的。下面再执行一下语句:

ALTER TABLE[dbo].[OrderDetail]DROP CONSTRAINT [FK_OrderDetail_Order]

GO

ALTER TABLE[dbo].[OrderDetail] WITH CHECK

ADD CONSTRAINT[FK_OrderDetail_Order] FOREIGNKEY([OrderID])

REFERENCES [dbo].[Order]([OrderID])

GO

现在让我们运行一下脚本,记住当有DELETECASCADE选项时,我们必须先从[OrderDetail]。中删除记录,想象一下,当我们有5、6个表对一个父表具有外键关联时,删除数据将要单独对每个表进行删除后才能删除父表。

DBCC DROPCLEANBUFFERS

GO

DELETE FROM[OrderDetail] WHEREOrderID=24032

DELETE FROM[Order] WHERE OrderID=24032

GO

我们可以通过SQL Profiler来监控两个处理方法的性能。你可以看到觉有DELETE CASCADE选项的处理占用的资源更少:

DELETE CASCADE

CPU (ms)

Reads

Writes

Duration

Yes

281

12323

2

950

No

374

24909

3

1162

第二个例子:

其中一个SQLServer最佳实践是在外键列并经常在where子句、join表中出现的字段,加上索引,现在我们对[OrderDetail]表加上索引,然后运行上面的查询,首先先加索引:

CREATE NONCLUSTEREDINDEX IX_OrderDetail_OrderIDON dbo.[OrderDetail](OrderID)

GO

接下来,运行改动后的执行,并监控性能:

DBCC DROPCLEANBUFFERS

GO

DELETE FROM[OrderDetail] WHEREOrderID=90032

DELETE FROM[Order] WHERE OrderID=90032

GO

ALTER TABLE[dbo].[OrderDetail] WITH CHECK

ADD CONSTRAINT[FK_OrderDetail_Order] FOREIGNKEY([OrderID])

REFERENCES [dbo].[Order]([OrderID])

ON DELETECASCADE

GO

DBCC DROPCLEANBUFFERS

GO

DELETE FROM[Order] WHERE OrderID=90433

GO

从下面的结果可以看到,使用DELETECASCADE选项在多表删除时,性能更好,并且能自动清除子表数据:

DELETE CASCADE

CPU (ms)

Reads

Writes

Duration

Yes

0

300

7

79

No

0

312

6

64

数据库开发——参照完整性——在外键中使用Delete on cascade选项的更多相关文章

  1. MySQL外键约束_ON DELETE CASCADE/ON UPDATE CASCADE

    MySQL通过外键约束实现数据库的参照完整性,外键约束条件可在创建外键时指定,table的存储引擎只能是InnoDB,因为只有这种存储模式才支持外键. 外键约束条件有以下4种: (1)restrict ...

  2. Oracle开发 之 主-外键约束FK及约束的修改

    试验环境: 1)数据库版本:oracle 11.2.0.4 2)建表脚本:以scott的dept及emp表为基础. 父表:dept -- Create table create table DEPT ...

  3. day38:MySQL数据库之约束&索引&外键&存储引擎

    目录 part1:数据类型 part2:约束 part3:主键索引 PRI &唯一索引 UNI &普通索引 MUL part4:外键:foreign key part5:在外键中设置联 ...

  4. MySQL外键约束On Delete、On Update各取值的含义

    主键.外键和索引的区别?   主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...

  5. MySQL数据库之-foreign key 外键(一对多、多对多、一对一)、修改表、复制表

    摘要: 外键 一对多 外键 多对多 外键 一对一 --------------------------------------------------------------------------- ...

  6. 【Django 2.2文档系列】Model 外键中的on_delete参数用法

    场景 我们用Django的Model时,有时候需要关联外键.关联外键时,参数:on_delete的几个配置选项到底是干嘛的呢,你知道吗? 参数介绍 models.CASCADE 级联删除.Django ...

  7. sql操作数据库(3)-->外键约束、数据库表之间的关系、三大范式、多表查询、事务

    外键约束 在新表中添加外键约束语法: constraint 外键约束名称 foreign key(外键的字段名称) references 主表表名(主键字段名) 在已有表中添加外键约束:alter t ...

  8. python 全栈开发,Day62(外键的变种(三种关系),数据的增删改,单表查询,多表查询)

    一.外键的变种(三种关系) 本节重点: 如何找出两张表之间的关系 表的三种关系 一.介绍 因为有foreign key的约束,使得两张表形成了三种了关系: 多对一 多对多 一对一 二.重点理解如果找出 ...

  9. Oracle数据库添加删除主外键

    (一)添加主键 1.表创建的同时,添加主键约束 语法: create table "表名" ( "列名1" 数据类型及长度 constraint "主 ...

随机推荐

  1. cocos2d-x ios游戏开发初认识(五) CCsprite精灵类

    这次写一下精灵创建的几种类型: 一.通过文件创建: 在原有的基础上加入例如以下代码: //一.通过文件创建精灵 CCSprite *bg =CCSprite::create("map.png ...

  2. JDBC数据库编程常用接口(转)

    JDBC的全称是Java DataBase Connectivity,是一套面向对象的应用程序接口(API),制定了统一的访问各种关系数据库的标准接口,为各个数据库厂商提供了标准接口的实现.这东西能够 ...

  3. Error与Exception的区别

    错误和异常的区别(Error vs Exception) 错误和异常的区别(Error vs Exception) 今天面试问了这样一个问题,"Error" 和 "Exc ...

  4. JS上传图片本地实时预览缩略图

    HTML 代码如下 <body> <table width="100%" border="0" cellspacing="0&quo ...

  5. WIFI实时监控追踪小车演示视频——安卓端、小车

    文章由@超人爱因斯坦出品,转载请注明出处.         文章链接:          http://hpw123.net/a/qingsongyike/yingyinqu/2014/1019/59 ...

  6. Multitasking Apps may only use background services for their intended purposes

    2.16 Details Your app declares support for audio in the UIBackgroundModes key in your Info.plist, bu ...

  7. Broadcast Receiver注意事项

    静态登记 <receiver android:name=".MyReceiver" android:enabled="true"> <inte ...

  8. Android中目的地Intent的使用

    一.什么是Intent? Intent的中文意思是目的.在Android中也是“目的”的意思.就是我们要去哪里,从这个activity要前往另一个Activity就需要用到Intent. 示例代码一: ...

  9. 13-7-5 android Tabhost功能实现

    开始使用了一个Activity做界面切换,采用visible.gone写法,感觉太麻烦了. layoutHousehold.setVisibility(View.GONE); layoutCamera ...

  10. [Java] HttpClient有个古怪的stalecheck选项

    打开stale check会让每次http请求额外消耗15毫秒.而且stalecheck选项缺省是打开的. 这有必要吗???? 在局域网里面调用web api service的时候会死人的. http ...