Sql server 物种的DB模式分类法:条件联接还是重新设计?

Sql server 物种的DB模式分类法:条件联接还是重新设计?,sql-server,Sql Server,我需要一些建议来设计DB模式。我正在做一个项目,需要对物种进行分类 所有物种都属于一个性别、一个科、一个目、一个类、一个分支,最后是一个王国 但其中一些在类和分支之间有一个分支。我首先给物种实体一个FK,指向每个分类法 然后我考虑只给物种实体一个“性别FK”,并从那里一直到它的完整分类。这似乎是可行的,但我意识到我无法检索到与之相关的物种的分支 在类实体中,我有两个FK,一个用于子分支,一个用于分支。根据物种的不同,branchId FK存在于类实体中(然后子分支FK为null),导致分支,然

我需要一些建议来设计DB模式。我正在做一个项目,需要对物种进行分类

所有物种都属于一个性别、一个科、一个目、一个类、一个分支,最后是一个王国

但其中一些在类和分支之间有一个分支。我首先给物种实体一个FK,指向每个分类法

然后我考虑只给物种实体一个“性别FK”,并从那里一直到它的完整分类。这似乎是可行的,但我意识到我无法检索到与之相关的物种的分支

在类实体中,我有两个FK,一个用于子分支,一个用于分支。根据物种的不同,branchId FK存在于类实体中(然后子分支FK为null),导致分支,然后是王国。或者子分支FK存在并导致子分支,然后从那里到分支,最后到kindgom

在SQL中,我在物种视图中有类似的内容(我用英语评论了我被卡住的地方):

我已经看到了一些关于条件联接的问题,但我无法让它工作。我考虑了联合,但两个查询之间的列数不同,因为其中一个查询有一个附加字段

也许模式设计需要改变


我该怎么办呢?

除了两个很小的注释外,您的模式一般都很好:

  • 在分类学上,它通常被称为“属”,而不是“性别”
  • 我强烈建议为
    Order
    表想出一些其他名称。相信我,如果您必须针对这样的模式编写任何值得一提的代码,那么您将诅咒选择表名与这个特定保留关键字相同的那一天<代码>订单,
    订单
    订单
    (来自“分类法”)-什么都行
  • 因此,查询应该非常简单:

    select s.*,
        -- Other columns
        isnull(sb.LatinName, '(No sub-branch)') as [SubBranchLatinName],
        -- The rest of stuff
    from Species S
        inner join Genus G on G.Id = S.GenusId
        inner join Family F on F.Id = G.FamilyId
        inner join OrderT O on O.Id = F.OrderId
        inner join Class C on C.Id = O.ClassId
        inner join Branch B on B.Id = C.BranchId
        left join dbo.SubBranch sb on sb.BranchId = b.Id and sb.Id = c.SubBranchId
        inner join Kingdom K on K.Id = B.KingdomId
    

    Left join允许您引入可能不包含与条件匹配的行的表,而不会在最终输出中丢失这些行。

    我认为使用星型模式(即物种表包含FKs到每个分类表)会更快地进行选择。这还将消除条件联接的复杂性和任何其他逻辑“异常”

    如果您想使用链条,则有两种方法:

  • 条件联接:
  • 下面的例子

      from Species S
        join Gender G on G.Id = S.GenderId
        join Family F on F.Id = G.FamilyId
        join [Order] O on O.Id = F.OrderId
        join Class C on C.Id = O.ClassId
        LEFT JOIN SubBranch AS SB ON .....
        INNER JOIN Branch AS B ON SB.BranchID = B.Id OR C.BranchID = B.Id
    
    这将是缓慢的

    UNION-ALL
    方法可能会更快。要解决列数差异问题,您需要添加
    NULL
    和/或空字符串常量来代替无分支查询的分支列

  • 另一种方法是为没有分支的类添加虚拟分支记录。这样子分支表中总是有一条记录,您不需要条件联接。我推荐这个解决方案

  • 谢谢你的建议。。事实上,像Order和其他保留关键字这样的名称需要像这样放置[Order]…这让左连接很烦恼,当没有与子分支实体的链接时,我不会丢失行,但该查询会使我丢失与子分支实际有链接的记录..丢失记录?确保此特定物种的
    BranchId
    字段在
    SubBranch
    Class
    表中具有相同的值(当然
    KingdomId
    应该存在并指向有效记录)。别的。。不,这个案子太简单了,不能漏掉任何东西。
      from Species S
        join Gender G on G.Id = S.GenderId
        join Family F on F.Id = G.FamilyId
        join [Order] O on O.Id = F.OrderId
        join Class C on C.Id = O.ClassId
        LEFT JOIN SubBranch AS SB ON .....
        INNER JOIN Branch AS B ON SB.BranchID = B.Id OR C.BranchID = B.Id