项目数据从平面表到邻接列表

时间:2011-01-08 01:02:54

标签: sql database-design tree common-table-expression

我正在设计一个记录和报告日常测量数据的系统。数据包括类别标识符,日期/时间和测量数据(其中最多可以有浮动或整数500件)。
这些类别可视化为树结构,其中数据与节点以及叶子相关联 原始数据以CSV格式输入,格式如下:

1/6/2001 15:55, /Node1/Node2/Node3, 121, 34, 452, 651, 167  
1/6/2001 15:55, /Node1/Node2/Node3/LeafA, 12, 34, 45, 65, 67  
1/6/2001 15:55, /Node1/Node4/Node5/LeafB, 21, 32, 43, 54, 65  

我打算使用Adjacency List(参见Database Structure for Tree Data Structure)来了解树结构。我还计划为测量数据和日期/时间设置第二个表格。这样,一旦第一次生成树结构,就可以通过测量数据表反复引用树结构。此外,有一个小的Adjacency List表使系统更具可读性:)。在下面的类别表中,Name将是节点或叶子名称(例如Node1或LeafA),FullName将是整个分支路径(例如Node1 / Node2 / Node3 / LeafA)。不确定我是否需要两者,但我认为它们会派上用场,所以我不需要在需要时重新创建FullName。

CREATE TABLE [dbo].[Category](
  [CatId] [int] IDENTITY(1,1) NOT NULL,
  [ParentCatId] [int] NULL,
  [Name] [nvarchar](30) NOT NULL,
  [FullName] [nvarchar](MAX) NOT NULL
CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 
(
  [CatId] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[MeasurementData](
  [CatId] [int] NOT NULL,
  [DateCollected] [datetime] NOT NULL,
  [foo] [int] NOT NULL,
  [bar] [float] NOT NULL,
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MeasurementData]  WITH CHECK ADD  CONSTRAINT [FK_ MeasurementData _Category] FOREIGN KEY([CatId])
REFERENCES [dbo].[Category] ([CatId])
GO
ALTER TABLE [dbo].[MeasurementData] CHECK CONSTRAINT [FK_ MeasurementData _Category]
GO

要将数据加载到系统中,我考虑使用BCP将CSV加载到平面表(到SQL Server 2008)中,然后将平面表投影到分层表结构。 Q1 :我应该使用T-SQL还是C#(SQL Server以外的C#app)尝试此投影? Q2 :任何人都有一个现有的算法来快速查找(或创建并返回)给定上面类别标识符的正确叶子?

仅供参考,我也正在使用WITH关键字后跟公共表表达式来绕过递归查询语法 - 当我需要进行一些递归编程时。 https://stackoverflow.com/questions/tagged/common-table-expression
http://media.pragprog.com/titles/bksqla/trees.pdf

提前致谢

1 个答案:

答案 0 :(得分:1)

你的桌面结构可能有些不确定。

您提供的示例输入数据表明整套度量适用于整个节点列表。如果这是真的,那么你最好散列节点列表字符串,得到这样的东西:

TABLE: Category

HashId  NodeList
======  ===================
289383   node1\node2\....
139829   node6\node7\....

来自MeasurementData的外键现在位于HashId上。

这回答了你的Q1:在传递数据的同时在C#中生成哈希,为Category表和MeasurementData表生成两个BCP准备好的输出文件。

由于这是某种数据仓库,不要害怕生成其他方法优化的数据的其他副本,所以通过各种方法在CategoryDe​​tails表中进行类别的第二次表示像这样:

TABLE CategoryDetails

HashId  NodeName  ParentNodeName
======  ========= =================
289383  node1
289383  node2     node1
etc, etc,

至于如何使用Common Table Expressions,我在绕过它们时遇到了一些麻烦,但是一旦我搞清楚,我写了一篇博客文章:http://database-programmer.blogspot.com/2010/11/recursive-queries-with-common-table.html