层次结构与许多表格

时间:2016-01-19 23:26:55

标签: sql sql-server sql-server-2014

我们要求存储位置。有不同类型的位置。区域,街区,建筑物,楼层,房间和床。因此,一张床位于一个房间,位于一个楼层等。

我想我有两个选择。首先是为每种类型设置一个表。还有一把外键可以让它们保持联系。

... OR

CREATE TABLE [dbo].[Location]
(
 [ID] Int IDENTITY(1,1) NOT NULL,
 [ParentID] Int NULL,
 [LocationTypeID] Int NOT NULL,
 [Description] Varchar(100) COLLATE Latin1_General_CI_AS NOT NULL
)

以分层方式保存所有位置的表格。

我喜欢这个想法,就像我们添加新类型一样,它是数据驱动的。没有新表。但是,我认为查询可能很昂贵。

如果我想要显示床的详细信息(科学楼4楼5号房的床1),这是一个递归函数,比所有表格的简单INNER JOIN更难以获取细节关于某个地点。

但有一件事。

我需要记录动作。一个运动可能是从一个房间到一个区域。因此,对于单独的表格,很难在单个“移动”表中记录移动,因为我将FK表转换为哪个表格?使用层次结构,这很容易。

此外,报告1000人的位置,会调用递归查询以产生结果。慢?或者有一种干净的方式来解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

所有方法各有利弊。我看到的另一种方法(尤其是日期)是使用一个表并在单个字段中编码层次结构(没有父ID)。

例如ID(整数列)= 1289674566意味着床66,楼层45等......

当您需要“提取”特定的层次结构级别(例如计算不同建筑物的数量)时,需要做一些工作但是算术运算非常快,如果您可以在基表顶部构建视图希望让最终用户的生活更轻松。

只是另一种选择......

答案 1 :(得分:0)

我的建议是将数据存储在现实世界中,然后如果你很幸运,你可以在没有太多命中的情况下查询数据。如果命中太多,请将数据提取为您可以轻松搜索的格式。

在你的情况下,我会选择你正在思考的等级风格。这样你就可以拥有一个带有梳妆台的房间的建筑物,抽屉里有一个盒子。然后你可以将梳妆台移到另一个房间,所有的东西都随之而来。

只要您不尝试“欺骗”,您就会发现递归CTE的速度很快。 SQL服务器做的事情。

我刚刚在这里回答了一个等级问题,这个问题有一个很好的例子供你玩。特别要注意SORT_PATH。在示例中,我构建了一个类似于此的SORT_PATH:

TEST01.TEST03.LABSTL

SSRS: Recursive Parent Child

您可以在EDIT / UPDATE中将此值存储在您的表格中,只要您在更新记录时不介意命中,它就可以为您做很多事情(性能)。

如果您确实关注更新,可以使用后端进程来更新SORT_PATH。在过去,我使用了一个" DIRTY BIT"当某些东西被修改时被翻转的字段;然后,后端流程会通过并更新与该记录相关的所有内容,但由于它是后端流程,因此用户不会注意到该影响。这对于SEVICE BROKER来说是一个很好的工作 - 在编辑/更新/删除时设置DIRTY_BIT = True并向SERVICE BROKER发送一条消息,该消息将启动一个用DIRTY_BIT = True更新任何内容的进程。

答案 2 :(得分:0)

看一下使用hierachyid数据类型,它是SQL Server本机的CLR数据类型,并且内置了查询父/子类型关系的函数:

Tutorial: Using the hierarchyid Data Type