原文:数据库开发——参照完整性——在外键中使用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. 成为JAVA软件开发工程师要学哪些东西

    2010-04-22 15:34 提问者采纳 Java EE(旧称j2ee)   第一阶段:Java基础,包括java语法,面向对象特征,常见API,集合框架: *第二阶段:java界面编程,包括AW ...

  2. jQuery Fancybox插件说明

    这里有jquery影像回放路径插件称为Fancybox,项目主页地址:http://fancybox.net/ Fancybox的特点例如以下: 1.能够支持图片.html文本.flash动画.ifr ...

  3. Go by Example

    Go by Example Go is an open source programming language designed for building simple, fast, and reli ...

  4. loading加载中效果

    (function(){ try{ var ui={ loading:{ addCssStyle:function(text) { var head = document.getElementsByT ...

  5. 讨论asp.net通过机器cookie仿百度(google)实现搜索input搜索提示弹出框自己主动

    为实现自己主动弹出通过用户输入关键词相关的搜索结果,在这里,我举两个解决方案,对于两个不同的方案. 常用的方法是建立一个用户数据库中查找关系表.然后输入用户搜索框keyword异步调用数据表中的相关数 ...

  6. Qt学习一门:直接使用QT具

    今天,通过直接使用QT一些工具来编写命令行程序.你可以看到一种Qt更一般的用法. 内容很easy,输出电流日期. 首先,用一个QDate分类,可以使用QDate类的静态方法currentDate为了得 ...

  7. GUI & Event例子

    Student No.: _______________ Name: ________________________________________1TK2934 Object-Oriented P ...

  8. iOS Dev (55) 获得本年度、月、日本和其他信息

    iOS Dev (55) 获得本年度.月.日本和其他信息 作者:大锐哥 博客:http://prevention.iteye.com - NSDate *now = [NSDate date]; NS ...

  9. telnet模拟http訪问

    HTTP协议经常使用的无非就那么几个命令 GET HEAD PUT POST 此处简单说下http的GET和HEAD 举两个简单的样例: GET的样例 telnet serverip 80 GET h ...

  10. 主机Window不能访问该虚拟机Linux Samba文件服务提供了一个文件夹

    我最近遇到一个问题.虚拟机Linux中间Samba服务常开.主办"\\192.168.229.200" (我的虚拟机Linux址)訪问不了Share文件夹(/var/test),并 ...