代码之家  ›  专栏  ›  技术社区  ›  user1447679

在SQL Server中,我需要更改关系的数据结构(FK)

  •  1
  • user1447679  · 技术社区  · 10 年前

    好吧,我不完全确定这个问题的标题是什么,所以情况是这样的。

    我擅长数据完整性。。。这意味着我希望在SQL Server中使用而不依赖于应用程序的约束和规则。

    所以我有一个网站,里面有一个商业目录,这些企业可以创建一个帖子。

    所以我有两张这样的桌子:

    tbl_Business ( BusinessID, Title, etc. )
    tbl_Business_Post ( PostID, BusinessID, PostTitle, etc. )
    

    两个表之间的列BusinessID存在FK关系。如果tbl_Business表中没有BusinessID,则tbl_Business_post表中不能存在帖子。

    非常标准。。。

    我最近在网站上添加了分类广告。现在我又有两张桌子:

    tbl_Classified ( ClassifiedID, SellerID, ClassifiedTitle, etc. )
    tbl_Classified_Seller ( SellerID, SellerName, etc. )
    

    我想做的是利用tbl_Business_Post表将分类广告也包含在其中。把它的用法想象成饲料。。。因此,该网站将在一个提要中显示来自企业和分类广告的最新帖子。

    这是我需要指导的地方。

    我想删除tbl_Business_Posts上的FK关系。。。 我考虑创建另一个单独的Posts表来保存分类广告的帖子。

    是否有一种方法可以基于列创建条件FK关系?例如,如果是业务发布,则BusinessID必须存在于business表中,或者如果是分类发布,则SellerID必须存在于Seller表中?

    或者我应该创建一个单独的表来保存分类广告帖子,并将查询中的两个表都UNION?

    你可能会问我为什么有“帖子”表,这很难解释。。。但我确实需要它来了解网站的组织方式和提要的工作方式。

    只是帖子表很完美,我想将所有帖子合并,并按类型(例如:“商业”、“分类”、“等”)进行组织,因为以后可能会有更多帖子。

    因此,归根结底,组织这项工作以保持SSMS数据完整性的最佳方式是什么?

    感谢您的指导。

    ==========编辑=========

    tbl_Business_Post的完整说明

    PostID PK
    Post_Type int <-- 1-21 is business types, 22 for classified type
    BusinessID INT <-- This is the FK currently for the tbl_Business
    SiblingID INT <-- This is the ID of the related item they're posting on. So for example, if they post a story about one of their products, this is the ProductID, if it's a service, this is the ServiceID.
    Post_Title <-- Depending on the post, this could be a Product title, a service title, etc.
    

    所以,如果我改变了结构,如下所示:

    PostID PK
    Post_Type int
    BusinessID INT <-- this is populated on insert if it's a business.
    SellerID INT <-- This is populated on insert if it's a classified seller
    SiblingID INT <-- This is either the classifiedID or ProductID, SeviceID, etc. Depending on post type.
    

    所以倾向于Peter的第一个解决方案/示例。。。对创建检查约束或触发器的正确方式感兴趣,如果类型为1-21,则确保BusinessID存在于Business表中;如果类型为22,则确保SellerID存在于seller表中。

    甚至更进一步:

    如果Post_Type=22,我应该确保卖家表中不仅有卖家,而且SiblingID也是Classified表中的ClassifiedID。

    1 回复  |  直到 10 年前
        1
  •  0
  •   peter.petrov    10 年前

    1) 没有办法实现您正在考虑的这种条件FK。这里需要的基本上是来自tbl_Business_Post的FK,它逻辑上指向两个表中的一个,具体取决于tbl_Business_Post另一列中的值。这种情况是人们经常遇到的。但在关系数据库中,这并不是一个非常原生的想法。 因此,好吧,这不能用FK强制执行。相反,您可能可以用tbl_Business_Post上的触发器或检查约束强制执行。

    2) 或者,您可以执行以下操作。

    创建一些表tbl_Basic_Post,将所有与帖子本身相关的列(例如PostTitle)放在那里,而不是该帖子记录所属/指向的父实体(业务或分类)。然后创建另外两个表,通过FK指向tbl_Basic_Post表,例如。

    tbl_Business_Post.Basic_Post_ID(FK)
    tbl_Classified_Post.Basic_Post_ID(FK)

    在这两个表中放入Business_Post/Classified_Post-specific列
    (你看,这在关系数据库术语中基本上是可继承的)。

    此外,使这两个表中的每一个表都具有各自父表的FK
    tbl_Business和tbl_Classified。现在这些FK变成无条件的(在你的意义上)。

    要获取商业帖子,请加入tbl_Basic_Post和tbl_business_Post。
    要获得分类文章,请加入tbl_Basic_Post和tbl_classified_Post。

    这两种方法各有利弊。 方法1)简单,不会导致创建太多表;但加强数据完整性并非易事。 方法2)不需要任何特殊的东西来强制数据完整性,但会导致创建更多的表。