【问题标题】:Sql Server database design issueSql Server 数据库设计问题
【发布时间】:2023-03-21 21:15:02
【问题描述】:

我有一个应用程序,其中包含以下表格。

Categories - CategoryID, CategoryName, CategoryTypeID, IsActive

CategoryTypes - CategoryTypeID, CategoryTypeName, IsActive

Items - ItemID, ItemName, CategoryID, UnitID, ItemPrice, IsActive

Units - UnitID, UnitName, IsActive

我有很多表格,但我没有显示所有表格,因为如果我有一个关系船的场景,我可以为其他人做。

在上面的表格中,Item 与具有 CategoryID(ForeignKey 约束)的类别有关系

Items 也与 Units 有关系(以 UnitID 作为 Fk 约束)。

现在在我的应用程序中,如果我想删除 Items 表中引用的类别。如果没有删除 Items 表中引用的记录,我无法删除 Category。

因此,我必须删除项目,然后删除类别本身。

但问题是如果我删除项目 - 我无法删除,因为 ItemID 在另一个名为“OrderItems”和“Promotions”的表中也被引用。

这是这两个表的表结构。

OrderItems - OrderItemID, OrderID, ItemId, ItemQuantity, ... , IsActive
Promotions - PromotionID, ItemID,... IsActive

现在实际问题出现了 - 如果我想删除一个类别,我不能删除,除非我删除一个项目。

如果我想删除一个项目,项目指向的所有引用表都必须删除,即 OrderItems 和 Promotions。

但作为业务逻辑,即使数据库中不存在 ItemID(在 Items 表中),我也需要 OrderItems 和 Promotions。

由于带有 OrderItems 和 Promotions 的 Items 存在外键约束,我无法删除 Items 记录。

所以,我想知道 - 我可以将外键设置为“允许空值”还是简单地删除约束并只使用普通表(认为存在关系)。

我的另一个限制是,如果我试图保持数据退出但将 IsActive 状态设置为 true 或 false(如果我想删除记录,则将 IsActive 设置为 false)。但是数据库会继续增长,我认为这不是正确的方法。

我真的很担心这个问题,因为我对我的应用程序的删除功能感到震惊。

我希望你在这里理解我的问题。

非常感谢任何帮助。

【问题讨论】:

    标签: sql-server database database-design foreign-key-relationship


    【解决方案1】:

    我个人建议在类别表中设置为非活动状态。我知道你不喜欢数据库增长的想法,但如果你想确保引用完整性,你不应该删除正在使用的主键。

    如果您需要删除它们,那么您将需要运行一个过程,将项目表中的值设置为空,然后删除它们,确保您已将项目表的 CategoryID 列设置为允许空值。

    编辑:基于 OP 评论的附加信息

    删除外键约束也是一种选择。但请注意,具有此约束有两个好处。第一个不应该对你应用太多,但它涉及速度。外键约束允许您在列上聚集索引,这将提高您访问和连接这些行的速度。如果你的数据库那么小,只有几百兆字节,你可能不会得到显着的提升。

    另一个更重要的原因是因为它确保了数据库的完整性。尽管您可以并且人们也可以自己管理关系,但确实会带来风险。请记住,您需要在业务逻辑中编写代码来检查是否存在匹配的键,通常是在插入和访问时。对于一个小程序,这很好,但如果您打算扩展,请小心,因为这可能会在以后给您带来麻烦。

    【讨论】:

    • 是的,这就是我的想法,但它完全涉及到我的大量返工。那么,这将是对这些字段“允许 Nulls”的最终方法吗?
    • 这种方法怎么样 - 消除约束和思考存在的关系。现在由于不存在任何约束,我可以轻松删除记录而无需对其他表进行任何更新,但这种方法是正确的做法吗? @KHeaney
    • 我还有一个约束是数据库大小。即使我不打算使用它们,我也无法将这些记录保存在我的数据库中。我的应用程序允许的数据库大小非常有限。
    • 因为我的数据库非常小,我认为速度并不重要。因为我的应用程序可以选择现有值(可能是 Items UI 设计中的 Category 或 OrderItems UI 设计中的 Items)。因此,我不担心交叉检查该特定项目是否仍然存在。我正在对此进行一些研发,当我们也进行增强部分时,它甚至不应该影响我的应用程序。
    • 但是,如果我要删除一条记录(Say Items),同时还要在 Items 表上删除 OrderItems 中的约束。那么,如果我删除一个项目并读取同一个项目会发生什么。会有很多混乱发生。这就是我目前的想法。
    【解决方案2】:

    考虑过制作垃圾分类吗?将项目移到那里并抑制正在所有处理中。

    或者,允许项目没有类别 (CategoryID = null),从而将它们更新为没有类别。

    【讨论】:

    • 是的,我想到了将 Items 表中的 CategoryID 设置为 Allow Nulls 的想法。但这是正确的做法吗?如果我将 Items 表中的 CategoryID 设为“允许 Nulls”。因此,在删除类别之前,我可以将 Items 表中的列(CategoryID)更新为空,然后我可以删除类别。我在这里吗@Tom Tom
    • 再创建一张表 GarabageCategory 并移动所有已删除的项目。这又与保留所有数据相同,但在不同的表中。因为仅保留 Items (ItemId, ItemName) 是不够的,如果存在记录(想想 Category 或 Item),我可能需要所有 Item 或 Category 详细信息。
    猜你喜欢
    • 2010-12-12
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多