【问题标题】:'None' or 'Not Used' foreign key when using GUIDs as primary key使用 GUID 作为主键时的“无”或“未使用”外键
【发布时间】:2009-03-07 20:28:04
【问题描述】:

我们正在构建一个可能需要复制到许多服务器的应用程序(我希望不会,但是在我们发布在线产品之前,无法知道客户是否需要他们自己的客户端/服务器副本)。

由于服务器数量未知,我决定对任何事务表 ID 使用 GUID。由于每个客户端都有自己的数据库,我打算使用 NEWSEQUENTIALID() 默认值,并且最大的表每年将添加不超过 150 万行(但平均为 15K 行),我预计不会有太大的性能问题.

但是,我不确定如何处理我们希望外键指示“未选择”的情况。例如,一个客户端有一个管理员用户。这被设置为 login.id(GUID)的外键(login_id)。但是,如果客户端还没有管理员用户,我们如何轻松设置“None Selected”键?

在以前的应用程序中,我们使用 IDENTITY 列,并在大多数表中插入了一个 ID 为 0 的虚拟条目。是否有一种可接受的方法来提供具有 GUID 的类似功能?

【问题讨论】:

    标签: sql sql-server primary-key guid


    【解决方案1】:

    执行此操作的唯一安全方法是将 FK 值设置为 NULL。如果您需要在多个服务器之间复制数据,请确保您复制的每个表都有 GUID 作为它们的主键,这样外键关系就不会出现问题。

    复制可以通过这种方式非常简单地工作:首先按照父表到子表的顺序复制插入和更新,然后将删除的记录从子表复制到父表。 (倒序。)

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      您有 3 个选项:

      1) 在您引用的表中,添加带有全零 guid 的空白值行,然后链接到此记录

      2) 只为空白引用存储一个 null

      3) 参考表中没有空白记录,但存储一个全零的 guid。如果在数据库或报表中进行连接,这可能会导致问题。您必须针对这种特殊情况编写代码。

      我会说 1 和 2 是唯一不错的选择。

      【讨论】:

      • 我不同意选项 1,任何特殊情况都是特殊情况,是等待发生的问题。选项 2 得到广泛使用和验证。
      【解决方案3】:

      我可能在这里遗漏了一些非常明显的东西,但你不能把它设置为 NULL 吗?

      【讨论】:

      • 我很高兴不是唯一一个认为这是微不足道的人。也许我们错过了什么。
      • 对我们来说,处理代码中的 0 总是比处理 NULL 值容易得多。
      • Null 有什么问题?我使用空 FK,我没有遇到任何问题
      • LuckyLindy,您过去在使用 NULL 值时遇到过什么问题?即使这是真的,在这种情况下也没有理由不使用它们。
      • Alex - SQL 语句可能更麻烦(例如,要检查用户选择的 'None' 值,您必须执行“is null”,这意味着 2 个不同的 SQL 语句),您也有为 NULLable 类型编码(或者更糟糕的是,如果您使用的语言不支持它们)。 0 消除了这些问题。
      【解决方案4】:

      使子表中的外键字段可为空,并在没有管理员用户时保持该字段为空。像“0”标识列这样的神奇值是一场等待发生的灾难。

      【讨论】:

      • 怎么样?在代码中处理 0 不是比处理 NULL 更容易吗?几年前,我们尝试编写一个外键可以为 NULL 的应用程序,结果是个熊。从那以后,我们编写了许多使用 0 作为外键约束的应用程序,并且从未遇到过一个问题。
      • 假行比 != NULL 更难处理。随着 Nullable 的出现,不再有任何问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 2012-05-20
      • 1970-01-01
      相关资源
      最近更新 更多