层次结构与许多表

Posted

技术标签:

【中文标题】层次结构与许多表【英文标题】:Hierarchy vs many tables 【发布时间】:2016-01-19 23:26:55 【问题描述】:

我们需要存储位置。有不同类型的位置。区域、街区、建筑物、地板、房间和床位。所以,床在房间里,在地板上等等。

我想我有两个选择。首先是为每种类型准备一个表。还有一个外键来保持它们之间的联系。

或者...

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 人的位置时,会大量调用递归查询以产生结果。慢的?或者有没有一种干净的方法来解决这个问题?

【问题讨论】:

我之前用过这个方法(单表层次结构),一个简单的递归CTE可以辅助快速返回数据 每种方法都有其优缺点... 您还需要确保您的树中不会出现循环。您添加其他位置类型的可能性有多大? 【参考方案1】:

所有方法都有各自的优缺点。我见过的另一种方法(尤其是日期)是使用一个表并将层次结构编码在一个字段中(没有父 ID)。

例如 ID(整数列)= 1289674566 表示床 66、楼层 45 等...

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

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

【讨论】:

【参考方案2】:

我的固定建议是将数据存储在现实世界中的样子,然后如果幸运的话,您可以查询它而不会受到太大影响。如果点击次数过多,请将数据提取为您可以轻松搜索的格式。

在您的情况下,我会采用您正在考虑的分层样式。这样一来,您就可以拥有一个带有梳妆台的房间的建筑物,带有抽屉的盒子和盒子中的盒子。然后你可以把梳妆台移到另一个房间,所有的东西都随它去。

只要您不试图“欺骗”SQL Server 做某事,您就会发现递归 CTE 的速度很快。

我刚刚在这里回答了一个分层问题,它有一个很好的例子供你参考。特别要注意SORT_PATH。在示例中,我构建了一个如下所示的 SORT_PATH:

TEST01.TEST03.LABSTL

s-s-rS: Recursive Parent Child

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

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

【讨论】:

感谢@Robert - 尝试您的示例...但出现转换错误。会继续尝试。 在另一个示例中,ParentKey (COL1) 是一个 VARCHAR,因此连接字符串很容易。您使用的是 INT,因此在构建 DISPLAY_PATH 时需要转换为 VARCHAR。我能够按原样复制答案并让它与 SQL2012 一起运行。您在哪里收到转换错误?【参考方案3】:

看看使用 hierachyid 数据类型,它是 SQL Server 原生的 CLR 数据类型,并内置了用于查询父/子类型关系的函数:

Tutorial: Using the hierarchyid Data Type

【讨论】:

以上是关于层次结构与许多表的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL多表多选

Linq中的group by多表多字段

单表多表操作 联表查询

MySQL 基础之 单表多表联查

SQL多表多字段联合查询怎么弄?最终结果用HTML页面以表格形式显示(表格已有,类似excel)。

Mysql单表多表查询