zoukankan      html  css  js  c++  java
  • MySQL外键设置 级联删除

       . cascade方式
    在父表上update/delete记录时,同步update/delete掉子表的匹配记录 

       . set null方式
    在父表上update/delete记录时,将子表上匹配记录的列设为null
    要注意子表的外键列不能为not null  

       . No action方式
    如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  

       . Restrict方式
    同no action, 都是立即检查外键约束

       . Set default方式
    父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别

    在这里我建立两张表:“ProductCategory”,“Product”.

    有一个需求是这样的:在删除某个ProductCategory 的时候,同时删除该Category的products.

    这里是创建两张表的脚本:

    CREATE TABLE [dbo].[ProductCategory](
        [Id] [uniqueidentifier] NOT NULL,
        [Name] [varchar](50) NULL,
     CONSTRAINT [PK_ProductCategory] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    CREATE TABLE [dbo].[Product](
        [Id] [uniqueidentifier] NOT NULL,
        [CategoryId] [uniqueidentifier] NULL,
        [Name] [varchar](50) NULL,
        [Price] [decimal](18, 0) NOT NULL,
     CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    创建后的表大致如下:

    B6BCCB218C4946999A038748EDD3169C

    D2AA9CB97D5E4921BF534E512CC55C88

    一些实验数据:

    INSERT INTO [Test].[dbo].[ProductCategory] VALUES('4B07A7D0-B56A-4DE3-9F55-972AC6D60994','category1');
    INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product1','1');
    INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product2','2');
    INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product3','3');
    INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product4','4');

    有很多种方法可以实现这个功能:

    在模型层中处理:

    public class ProductCategoryRepository
    {
        public bool DeleteCategory(ProductCategory category)
        { 
            // 删除Category
            // 删除该Category 下面的products.
        }
    }

    这个比较简单也很容易理解,但是它有个问题:如果是直接通过执行SQL 来删除Category的。那么这个约束就无法满足了,或者是说你必须记得如果要删除Category的话,那么就应该使用DeleteCategory方法

    于是第二种方法出现了:

    通过触发器来级联删除:

    具体的触发器代码如下:

    Create TRIGGER [dbo].[DeleteRelatedProducts] ON  [dbo].[ProductCategory]
     AFTER DELETE
    AS 
    BEGIN
        SET NOCOUNT ON;
        delete from [dbo].[product] where categoryId in 
        (
            select id from deleted
        )
    END

    这种方式比较简单,而且语法也很明了:

    具体资料可以参照:http://msdn.microsoft.com/en-us/library/ms191300(SQL.105).aspx

    还有一种方式可能并不是很多人知道:

    外键的级联删除和更新:

    在sql server 中可以通过设置外键的级联删除和更新来实现这个功能。

    这里是外键的定义:来自http://baike.baidu.com/view/68073.htm

    简介

    外键(Foreign Key)

    如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。换而言之,如果关系模式R中的某属性集不是R的主键,而是另一个关系R1的主键则该属性集是关系模式R的外键,通常在数据库设计中缩写为FK。

    外键的作用

    保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值或使用空值

    我们现在的要求是删除ProductCategory的时候,同时删除该ProductCategory下面的Product

    所以应该在Product 表中建立外键约束,

    41CAF4CCE0594D539B8FE9DFF831BC31

    看到删除规则了吗,指定为层叠的话,那么当删除ProductCategory的时候,就会删除Product了。

    
    
    select * from ProductCategory;
    select * from product;
    
    Delete from ProductCategory;
    
    select * from ProductCategory;
    select * from product;

    结果如下:

    8DD435ED59A34A0EB60B4D7AC9A81A07

  • 相关阅读:
    win10-wifi无线共享自动关闭解决
    可用的nlog配置
    cmake 常用指令,变量
    window时间服务
    命令行配置服务启动类型
    boost流gzip压缩
    mysql 查询某表的所有列,获取毫秒时间戳
    system进程占用80端口
    centos8重新分区(减小/home空间,增大root空间)
    emqx使用data_to_webservice方式配置规则引擎简单实践
  • 原文地址:https://www.cnblogs.com/ouyangping/p/6500626.html
Copyright © 2011-2022 走看看