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