代码之家  ›  专栏  ›  技术社区  ›  Marcus L

删除FK行时是否可以更改外键ID?

  •  2
  • Marcus L  · 技术社区  · 15 年前

    我需要在我们的一个数据库表中创建一个唯一的列,并且我们希望从表中完全删除任何重复项。然而,也有一个障碍,那就是对其他表的依赖关系会受到影响。

    例如,假设我们得到了以下关系:

    -------------------   -------------------
    *     Customer    *   *      Order      *
    -------------------   -------------------
    * ID              *   * ID              *
    * Name            *   * CustomerID      *
    * Address         *   * Item            *
    -------------------   -------------------
    

    很明显,订单需要CustomerID,这是一个外键。因此,我们无法删除客户并保留订单数据。

    是否有任何方式表示删除此项,如果存在外键约束,请将CustomerID改为该ID?数据库是MS SQL 2005。

    6 回复  |  直到 15 年前
        1
  •  4
  •   Eric Darchis    15 年前

    我想说:

    该方法实际上取决于检测重复项的方式。假设你有一张桌子:

    -------------
    *  Dupes    *
    -------------
    * del_id    *
    * keep_id   *
    -------------
    

    步骤2:重新链接订单

    update order o
    set CustomerID=(select keep_id from Dupes d where d.del_id=o.CustomerID)
    where CustomerID in (select del_id from Dupes)
    

    步骤3:删除旧客户

    delete from Customer
    where ID in (select del_id from Dupes)
    

    瞧。

        2
  •  1
  •   duffymo    15 年前

    但这听起来像是一个公平的游戏,在删除前触发客户。

    您只需确保这两个操作是一个单一的工作单元。

        3
  •  1
  •   Dan Sydner    15 年前

    能够 在customer表上使用delete触发器。 Books online on create trigger.

    但是为什么不在删除客户之前更新订单记录呢?这更容易,避免了痛苦触发,IMO将保持逻辑在同一位置。

        4
  •  1
  •   Maciej Łebkowski    15 年前

    无论如何,您必须有两个ID: dupCustomerId newCustomerId ,那么你为什么不先更新引用呢?

    UPDATE Order set CustomerID = newCustomerId WHERE CustomerID = dupCustomerId
    

    DELETE from Customer WHERE ID = dupCustomerId
    

    还是我在这里遗漏了什么?

        5
  •  1
  •   John Sansom    15 年前

    您是说您有重复的客户记录,即客户详细信息相同,但客户ID不同,因此存在引用同一客户多个版本的订单?

    执行数据清理练习 .

    创建/构建包含列的查找表

    • 客户编号
    • 订单编号
    • PrimaryCustomerID-(需要计算)

    然后可以对Orders表执行更新,以确保每个订单仅引用PrimaryCustomerID。

    然后,您可以删除订单不再引用的客户记录(即,它们是重复的)。或者,您可以向Customer表添加一个属性,以便标记记录而不是删除(即duplicateFlag或isDeleted)。

        6
  •  -1
  •   HLGEM    15 年前

    我们已经构建了一个重复数据挖掘工具(您也应该这样做),它首先查找存在数据冲突的地方(例如两个不同的业务电话号码),并允许执行重复数据挖掘的人员选择正确的数据。然后,该工具将id更改为您正在保留的id,从最底层的子表开始,并向上遍历所有相关的表。一旦删除了对记录的所有引用,它就会删除父记录。重复数据消除通常是一个复杂的过程,应仔细设计此工具,以处理需要处理的内容,并允许在添加新外键表时更改此工具。当您有数据冲突时,您可以将其设置为alawys CHOSE您正在保存的记录中的信息,但如果不进行手动干预,这样做通常是不明智的。这是因为你经常需要了解客户的人的意见。否则,您最终可能会用一个坏地址替换一个好地址。以下是dup最初如何到达那里的常见场景。客户A已经成为客户一段时间了,并且已经有好几笔订单。他又去点菜了,点菜的人要他的电话号码或其他一些识别信息来帮他查找。客户A最近搬家了,有了新的电话号码和地址,因此找不到他,并创建了新记录。后来发现它是一个dup,但自动重复数据消除过程会选择较旧的记录,因为它有更多的订单,因此会用当前的新地址和电话替换该记录。客户再次致电订购,并创建另一个dup,因为订单接受者再次找不到他。这就是为什么我强烈认为重复数据消除必须是一个部分手动的过程。