【问题标题】:SQL Server CascadingSQL Server 级联
【发布时间】:2010-10-06 16:48:52
【问题描述】:

我正在创建一个网站,用户可以在其中发布“帖子”,然后用户可以对这些帖子进行“评论”。我有一个包含 3 个表的数据库。一个包含用户信息,一个包含发布信息,最后一个包含评论信息。

我想设置规则,以便如果删除用户,则删除其所有帖子和 cmets,如果用户删除其中一个帖子,则删除所有关联的 cmets。但是,这会设置“多个 CASCADE 路径”。

我一直在寻找解决方案,并找到了一些关于触发器的信息。它们会是最好的使用方法吗?如果我使用它们,我是否必须更改所有 CASCADE 以由触发器完成?

谢谢

克莱夫斯特

【问题讨论】:

    标签: sql sql-server database-design triggers cascade


    【解决方案1】:

    使用声明性引用完整性。

    create table foo
    (
      id   int         not null primary key ,
      foo  varchar(32) not null ,
    )
    create table bar
    (
      id     int not null primary key ,
      foo_id int     null foreign key references foo ( id ) on delete cascade ,
    )
    

    从 foo 中删除一行将删除 bar 中所有相关的行。

    但要小心级联删除——胖手指删除语句会很快造成大量损坏,这与 *nix 中的 rm(1) 不同。如果您一举删除大量数据,级联删除也会很快破坏您的事务日志。

    【讨论】:

    • 感谢您的回复。我是 SQL 初学者。是否可以在 SQL Server Management Studios 的“关系...”选项中进行设置?
    • 在 SQL Server Management Studio 中定义外键约束时,可以选择删除或更新相关主键值时要执行的引用操作(但你应该学会写改为 DDL(CREATE/ALTER 语句)。它使您的架构在源代码控制下 [b]much[/b] 更简单。
    【解决方案2】:

    另一种选择是创建两个专用的存储过程,根据需要执行这些删除步骤

    CREATE PROCEDURE dbo.DeleteUser @UserID VARCHAR(50)
    AS BEGIN
       DELETE FROM dbo.Comments
       WHERE Author = @UserID
    
       DELETE FROM dbo.Posts
       WHERE Author = @UserID
    
       DELETE FROM dbo.User
       WHERE UserID = @UserID
    END
    

    第二条规则:

    CREATE PROCEDURE dbo.DeletePost @PostID INT
    AS BEGIN
       DELETE FROM dbo.Comments
       WHERE PostID = @PostID
    
       DELETE FROM dbo.Posts
       WHERE ID = @PostID
    END
    

    在这种情况下,您可以完全控制实际发生的事情,级联删除不会带来意外的惊喜,也不需要使用触发器。

    【讨论】:

    • 这就是我要找的。谢谢。
    【解决方案3】:

    我认为这可以很容易地设置,不会出现您遇到的错误,也无需使用触发器,如下所示:

    1) The foreign key between Users and Posts should be set up to be cascade delete
    2) The foreign key between Posts and Comments should be set up to be cascade delete
    

    【讨论】:

    • 感谢您的回复。我已经考虑过这一点,但是如果创建帖子的用户之外的用户是 cmets。如果他们的帐户被删除,那么您的解决方案不会删除他们的评论
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    相关资源
    最近更新 更多