Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 层次结构与多个表_Sql_Sql Server_Sql Server 2014 - Fatal编程技术网

Sql 层次结构与多个表

Sql 层次结构与多个表,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,我们有存储位置的要求。有不同类型的位置。区域、街区、建筑物、地板、房间和床。所以,床在房间里,在地板上等等 我想我有两个选择。首先是为每种类型创建一个表。和一个外键来保持它们的链接 或者 以层次样式保存所有位置的表 我喜欢这个想法,好像我们添加了新的类型,它是数据驱动的。没有新桌子。但是,我认为查询可能很昂贵 如果我想显示床的详细信息(科学大楼4楼5号房间的1号床…),这是一个递归函数,它比简单的所有表的内部连接更复杂,以获取有关位置的详细信息 不过有一件事 我需要记录动作。运动可能是从一个房间

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

我想我有两个选择。首先是为每种类型创建一个表。和一个外键来保持它们的链接

或者

以层次样式保存所有位置的表

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

如果我想显示床的详细信息(科学大楼4楼5号房间的1号床…),这是一个递归函数,它比简单的所有表的内部连接更复杂,以获取有关位置的详细信息

不过有一件事

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


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

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

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

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


还有一个选择…

我的建议是将数据存储在现实世界中,如果你幸运的话,你可以查询它而不需要太多的点击。如果点击率太高,则将数据提取为您可以轻松搜索的格式

在你的情况下,我会同意你所想的等级风格。这样的话,你就可以拥有一个房间,一个梳妆台,一个抽屉,还有一个盒子。然后你可以把梳妆台移到另一个房间,所有的东西都跟着它

只要您不想“欺骗”SQL server去做某事,您就会发现递归CTE的速度很快

我刚才回答了一个层次问题,这是一个很好的例子。尤其要注意分拣路径。在本例中,我构建了一个排序路径,如下所示:

TEST01.TEST03.LABSTL

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


如果您不介意点击更新,您可以使用后端进程来更新排序路径。在过去,我使用了一个“脏位”字段,当某些内容被修改时会被翻转;一个后端进程随后会出现并更新与该记录相关的所有内容,但由于它是一个后端进程,用户不会注意到影响。这对于服务代理来说是一项很好的管理工作——在编辑/更新/删除时,将DIRTY_位设置为True,并向服务代理发送一条消息,该消息将启动一个进程,该进程将使用DIRTY_位=True更新任何内容。

看看如何使用hierachyid数据类型,它是SQL server本机的CLR数据类型,具有用于查询父/子类型关系的内置函数:


我以前使用过这种方法(单表层次结构),简单的递归CTE可以帮助快速返回数据。每种方法都有其优缺点……您还需要确保不会在树中出现循环。您添加其他位置类型的可能性有多大?谢谢@Robert-尝试您的示例。。。但是得到转换错误。在另一个示例中,ParentKey(COL1)是一个VARCHAR,因此很容易连接字符串。您使用的是INT,因此在构建DISPLAY_路径时需要强制转换为VARCHAR。我能够按原样复制答案,并让它与SQL2012一起运行。您从哪里得到转换错误?
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
)