我正在使用sql server中的大型分层数据集 - 使用标准的"EntityID,ParentID"方法进行建模.整棵树中大约有25,000个节点.
我经常需要访问树的子树,然后访问挂起子树节点的相关数据.几年前,我基于表值函数构建了一个数据访问层,在给定子树的根节点的情况下,使用递归查询来获取任意子树.
我正在考虑使用Entity Framework,但我无法看到如何查询这样的分层数据.AFAIK在Linq中没有递归查询,我无法在我的实体数据模型中公开TVF.
是继续使用存储过程的唯一解决方案吗?有没有人解决过这个问题?
澄清:树中的25,000个节点我指的是层次结构数据集的大小,而不是与对象或实体框架有关.
分层数据结构通常存储在关系数据库中.这种存储是灵活但平坦的,因此必须使用每个查询构建树结构.我想将论坛帖子存储为树结构,但应该可以有效地查询,例如按日期或作者选择帖子.
我想要一个可以从Java访问的开源数据库.
这样做的最佳方法是什么?CouchDB的?Neo4j的?...?
问题域
我正在开发一个相当大的应用程序,它使用分层数据模型.它采用图像,提取图像的特征并在这些特征之上创建分析对象.所以基本模型就像Object-(1:N)-Image_features-(1:1)-Image.但是同一组图像可用于创建多个分析对象(具有不同选项).
然后一个对象和图像可以有很多其他连接对象,就像分析对象可以用附加数据或复杂的结论(解决方案)可以基于分析对象和其他数据.
当前解决方案
这是解决方案的草图.堆栈表示对象集,箭头表示指针(即图像特征链接到它们的图像,但反之亦然).一些部分:图像,图像特征,附加数据,可以包含在多个分析对象中(因为用户想要对不同的对象集进行分析,以不同的方式组合).

图像,特征,附加数据和分析对象存储在全局存储(上帝对象)中.解决方案通过组合存储在分析对象内(并依次包含解决方案功能).
所有实体(图像,图像特征,分析对象,解决方案,附加数据)都是相应类的实例(如IImage,...).几乎所有部件都是可选的(即,我们可能希望在我们有解决方案后丢弃图像).
目前的解决方案缺点
我的想法
我想构建一个更具扩展性(2)和灵活(1)的数据模型.第一个想法是使用关系模型,分离对象及其关系.为什么不在这里使用RDBMS-sqlite对我来说似乎是一个合适的引擎.因此,复杂的关系可以通过数据库中的简单(左)JOIN来访问:伪代码" images JOIN images_to_image_features JOIN image_features JOIN image_features_to_objects JOIN objects JOIN solutions JOIN solution_features"),然后通过ID从全局存储中获取解决方案特征的实际C++对象.
这个问题
所以我的主要问题是
如果RDBMS没问题,我会很感激有关使用RDBMS和关系方法存储C++对象关系的任何建议.
免责声明:
这是一篇相当长的帖子.我首先解释我正在处理的数据,以及我想用它做什么.
然后我详细介绍了我考虑过的三种可能的解决方案,因为我已经尝试过做作业了(我发誓:]).我最终得到了"最佳猜测",这是第一个解决方案的变体.
我的终极问题是:使用Cassandra解决问题最明智的方法是什么?这是我的尝试之一,还是别的什么?
我正在寻找经验丰富的Cassandra用户的建议/反馈......
我的数据:
我有很多SuperDocuments在树形结构(标题,副标题,部分......)中拥有文档.
每个SuperDocument结构都可以随着时间的推移而改变(主要是重命名标题),从而为我提供了多个版本的结构,如下所示.

我正在寻找:
对于每个SuperDocument我需要按照上面的日期对这些结构加时间戳,并且我希望在给定的日期找到最接近的早期版本的SuperDocument结构.(即最新版本version_date < given_date)
这些考虑可能有助于更轻松地解决问题:
好吧,让我们这样做
请记住我真的只是开始使用Cassandra.我已经阅读/观看了很多关于数据建模的资源,但是在该领域没有太多(任何!)经验!
这也意味着一切都将用CQL3编写...对不起节俭爱好者!
我第一次尝试解决这个问题是创建下表:
CREATE TABLE IF NOT EXISTS superdoc_structures (
doc_id varchar,
version_date timestamp,
pre_pos int,
post_pos int,
title text,
PRIMARY KEY ((doc_id, version_date), pre_pos, post_pos)
) WITH CLUSTERING ORDER BY (pre_pos ASC);
Run Code Online (Sandbox Code Playgroud)
这会给我以下结构:

我在这里使用嵌套集模型 ; 我认为保持结构有序会很好,但我对其他建议持开放态度.
我喜欢这个解决方案:每个版本都有自己的行,其中每列代表层次结构的级别.
但问题是我(坦率地)打算查询我的数据如下:
SELECT * FROM superdoc_structures
WHERE doc_id="3399c35...14e1" AND version_date < '2014-03-11' LIMIT 1
Run Code Online (Sandbox Code Playgroud)
卡桑德拉很快提醒我,我不被允许这样做!(因为分区程序不保留群集节点上的行顺序,因此无法扫描分区键)
然后怎样呢...?
好吧,因为Cassandra不会让我在分区键上使用不等式,所以就这样吧!
我将制作version_date一个聚类键,我的所有问题都将消失.是的,不是真的...... …
我的MySQL数据库中有一种类似于树的东西.
我有一个包含类别的数据库,每个类别都有一个subcat.我将所有类别保存在一个表中,因此列如下所示:
*categories table*
id | name | parent_id
1 | Toys | 0
2 | Dolls | 1
3 | Bikes | 1
Run Code Online (Sandbox Code Playgroud)
我的数据库中的每个项目都分配给以下类别之一:
*items table*
item | category_id
barbie | 2
schwinn| 3
Run Code Online (Sandbox Code Playgroud)
问题是,如果有人想要查看所有TOYS(父类别),从项目数据库中获取信息的最佳方法是什么?我知道如何做的事情的唯一方法
SELECT *
FROM items
WHERE category_id = 2
JOIN SELECT *
FROM items
WHERE category_id = 3
etc...
Run Code Online (Sandbox Code Playgroud)
但是,如果我在Toys下有10个类别,那么我必须进行10次加入和查询.
有没有更好的方法来处理这个?
我有一个标准的自我参考表Categories.在我的实体模型中,我已经建立了联想Children和Parent.是否可以在Category没有延迟加载的情况下加载整个对象?
如果我使用下面的代码,它只加载到第二级.
db.Categories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
var query = from c in db.Categories.Include("Children")
where c.IsVisible == true
orderby c.SortOrder, c.Id
select c;
Run Code Online (Sandbox Code Playgroud)
如果我已经加载了所有类别对象,是否可以加载引用?
加载它的一种方法是Children多次添加属性
db.Categories.Include("Children.Children.Children.Children.Children")
Run Code Online (Sandbox Code Playgroud)
但是这会产生一个非常长的疯狂的T-SQL代码,而且它也没有做我想要的.
假设我有一个父子关系表.
parent child 1 4 1 5 2 6 3 7 4 8 6 9 7 10 8 11
现在我有一个返回人员列表的查询(例如1和2),我想找到他们所有的孩子,孙子等等(在这种情况下:4,5,6,8,9,11).
我知道我可以使用公共表表达式来递归搜索,但我想知道我是否可以创建一个SQL语句来一次查找所有后代而不必迭代输入集.
编辑:抱歉不够清楚.我正在寻找类似的东西:
SELECT {Hierarchical relation} from table where parent in (1,2)
这应该导致单个输出列的行为4,5,6,8,9,11.
我不再对输出中的关系感兴趣,只是对多个家庭的完整家庭成员感兴趣.
我正在尝试使用Redux构建一个复杂的全动态应用程序.我的意思是我的应用程序有很多动态生成的表单,其中包含生成的字段 - 即时组件.我想在我的Redux商店中存储有关我的组件的可视数据.但是,如果不将实际数据与可视化组件数据混合,我该怎么办呢?
例如,如果我有这样的结构
Store {
visual: {...deeply nested visual-data-tree...},
data: {...deeply-nested real-data-tree...}
}
Run Code Online (Sandbox Code Playgroud)
渲染组件很困难,因为我需要先搜索可视数据,然后在两棵树中对组件"值"进行反应.
但如果有一个类似于此的结构:
Store {
form {
visual: {...form visual data...},
data: {
//Ok here the form "data" - widgets. Or it must to be visual? :)
widget1 {
visual: {type:"ComboBox", opened: true},
data: 1
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你看到了问题,现在我在Form小部件的真实数据中有可视数据.
(表格 - 数据 - widget1 - 视觉)
真实数据中的可视数据超出了概念.
你们如何解决混合数据的相同问题?
对我可怜的英语真的很抱歉.我希望我清楚地解释了这个问题.
我在oracle中有一个名为Employee_Hierarchy的分层表,其列名为entity_code,parent_entity_code,entity_name和entity_role,没有循环.在名为Client的其他表中具有较低的子节点与使用entity_code的分层表的最低子节点连接.我必须在单行层次结构中显示数据,其中列名将由角色追加.
示例示例:
树形结构:
分层表:
降低大多数孩子的表:
预期结果:
有没有办法通过oracle查询获得预期的结果?并且预期结果取决于输入,这意味着它不总是从根元素开始,它可以从任何节点开始,例如team-lead(Shail)到最下面的子节点.
(注意:如果缺少上层,则当前节点的parent_code将是其上层的parent_code,并且缺少的层次元素在预期结果中将为空.)
提前致谢.
我的情况是,我目前正在SQL数据库中存储层次结构,该数据库快速接近15000个节点(5000个边缘).此层次结构根据树中的用户位置定义我的安全模型,授予对下面项目的访问权限.因此,当用户请求所有安全项目的列表时,我正在使用CTE将其递归到数据库中(并展平所有项目),这将开始显示其年龄(慢).
层次结构不经常更改,所以我试图将其移动到RAM(redis)中.请记住,我有许多需要这个安全调用的子系统,以及用于为CRUD操作构建树的UI.
第一次尝试
我的第一次尝试是将关系存储为键值对(这是它存储在数据库中的方式)
E
/ \
F G
/ \ / \
H I J K
mapped to:
E - [F, G]
F - [H, I]
G - [J, K]
因此,当我想要E及其所有的死者时,我递归地让它的孩子和他们的孩子使用钥匙,它允许我从任何节点开始向下移动.这个解决方案提供了很好的速度提升但是有15,000个节点,在代码中重建我的树大约有5000个缓存命中(更糟糕的情况......从E开始.性能基于起始节点位置,导致超级用户看到最糟糕的表现).这仍然很快,但似乎很健谈.我喜欢这样一个事实,即我可以通过将其从键列表中弹出而无需重建我的整个缓存来随时删除节点.这也可以快速点亮,在UI上直观地构建树.
第二次尝试
我的另一个想法是从数据库中获取层次结构,构建树并将其存储在RAM(redis)中,然后将整个内容拉出内存(大小约为2 MB,序列化).这给了我一个单独的调用(不是很健谈)到redis中拉出整个树,找到用户父节点,然后下降以获取所有子项.这些调用很频繁,在网络层传递2 MB似乎很大.这也意味着我无法轻松添加/删除和项目,而无需拉下树并编辑并将其全部推回.同时根据需要通过HTTP建立树木意味着每个请求必须下拉2MB才能获得直接子项(使用第一个解决方案非常小).
那么您认为哪种解决方案是更好的方法(长期因为它继续增长).两者都更加快速,并从数据库中减轻一些负担.或者他们是一个更好的方法来实现这一点,我没有想过?
谢谢
c# ×2
sql ×2
architecture ×1
c++ ×1
caching ×1
cassandra ×1
database ×1
datamodel ×1
flux ×1
java ×1
javascript ×1
join ×1
mysql ×1
nosql ×1
oracle ×1
performance ×1
redis ×1
redux ×1
sql-server ×1