Sql server 物种的DB模式分类法:条件联接还是重新设计?
我需要一些建议来设计DB模式。我正在做一个项目,需要对物种进行分类 所有物种都属于一个性别、一个科、一个目、一个类、一个分支,最后是一个王国 但其中一些在类和分支之间有一个分支。我首先给物种实体一个FK,指向每个分类法 然后我考虑只给物种实体一个“性别FK”,并从那里一直到它的完整分类。这似乎是可行的,但我意识到我无法检索到与之相关的物种的分支 在类实体中,我有两个FK,一个用于子分支,一个用于分支。根据物种的不同,branchId FK存在于类实体中(然后子分支FK为null),导致分支,然后是王国。或者子分支FK存在并导致子分支,然后从那里到分支,最后到kindgom 在SQL中,我在物种视图中有类似的内容(我用英语评论了我被卡住的地方): 我已经看到了一些关于条件联接的问题,但我无法让它工作。我考虑了联合,但两个查询之间的列数不同,因为其中一个查询有一个附加字段 也许模式设计需要改变Sql server 物种的DB模式分类法:条件联接还是重新设计?,sql-server,Sql Server,我需要一些建议来设计DB模式。我正在做一个项目,需要对物种进行分类 所有物种都属于一个性别、一个科、一个目、一个类、一个分支,最后是一个王国 但其中一些在类和分支之间有一个分支。我首先给物种实体一个FK,指向每个分类法 然后我考虑只给物种实体一个“性别FK”,并从那里一直到它的完整分类。这似乎是可行的,但我意识到我无法检索到与之相关的物种的分支 在类实体中,我有两个FK,一个用于子分支,一个用于分支。根据物种的不同,branchId FK存在于类实体中(然后子分支FK为null),导致分支,然
我该怎么办呢?除了两个很小的注释外,您的模式一般都很好:
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