我开始对以下问题进行建模:
我有许多客户(数百万)在一个网络中交互,形成一个图形。在我的业务问题的最高粒度上,每个关系都有3个属性。
在“现实”最坏的情况下,节点组成一个唯一的网格,与大约100个其他节点有关系,但还有一个令人恼火的问题:这些关系通常是双向的,并且还应该由三个属性中的一个(即客户端操作的区域)的不同可能值来分割。这就引出了以下大小调整:
2 directions * 6 regions * 100 nodes = 1200 edges per node情况会更糟。其中一项要求是,该数据库应该包含过去5年的每月历史记录,如果用户希望查看任何节点的过去分数,这意味着我还必须考虑每个节点每月1项,给出以下大小:
2 directions * 6 regions * 100 nodes * 60 months = 72000 edges per node我们倾向于使用图形数据库来解决这个问题,但问题是:在现有的图形技术条件下,这是否可行?
发布于 2016-06-30 23:02:32
您的历史数据问题实际上很常见:与业务相关的数据通常与时间相关。
处理这件事的一种方法是拍快照。这是@CandleOrange提出的解决方案。但这似乎也是您的假设:在您的规模中,您希望每个月出现不同的组合(完全等同于快照方法)。但你想把它保存在数据库里。
例如,一个领先的商业软件包以这种方式管理销售数字:每个月,它总结当月的销售额,每一个组合的客户类别,产品组,和地区。这样,它就可以根据标准并在任何特定的时期内产生销售数字,而不必阅读数百万美元的潜在交易。
事实上,这里没有数据和历史数据之间的区别。从业务角度来看,月份是所管理数据的组成部分。而且,经常将一个月的销售数字与前一年相比,也经常将一个月的销售数字与前一个月或今年第一季度的销售数字与去年的第一季度进行比较。
但是快照方法并不总是适合需要。很多情况下,数据可能与时间有关。例如,推销员X可以在3月1日至8月18日期间负责一个地区,从8月19日至今天负责另一个地区。八月份他住在什么地方?没有一个比另一个更精确。
对于图形关系来说,这是更糟糕的事件。因为在每个数据和每个关系中都有时间相关的方面。举个例子:从1月20日到9月20日,经理A负责X部门。从去年到1月22日,员工B被分配到部门X,而员工C自从加入公司后就被分配到了该部门,现在就在这里。A经理是谁管理的?完全取决于日期。
现在,如果比较依赖时间的方法和快照,数据库的大小是多少?对于快照,每个月都必须克隆每个相关的值。因此,对于我们的例子中的3个人和1部门,您将在一年内有36项记录。你仍然无法掌握全部的真相。对于与时间相关的方法,您有原始数据3条记录,并且只有在发生更改时才有附加数据,因此总共有6条记录。
因此,数据随时间变化的版本控制非常准确地表示了真实的世界,以及空间的稀奇古怪。但是它使得查询的设计更加复杂。
为了避免完全的查询噩梦,您可以默认情况下处理每个对象的当前版本(例如,end有效性为空),并在每次更改重要数据时创建有时间限制的克隆(开始和结束有效性日期集)。然后,您将访问这些克隆,它们的有效期仅适用于需要这些克隆的两个时间依赖的查询。
数据库系统对
对于大多数数据库系统,您必须注意与时间相关的方面。数据元素的时间依赖性必须从一开始就被识别出来,这是一项艰巨的个案设计工作。
但正如已经说过的:这是一个共同的挑战。因此,幸运的是,这里有一些支持:
发布于 2016-06-28 15:34:59
我曾经通过复制数据库来解决数据库的历史问题。
一个星期以来,我每天晚上都复制一份数据库。每周一个月。每个月都有一年。每年都有备份。都是用一个简单的脚本完成的。解决了历史问题,保持了规模的合理,保持了数据库的清洁。当然,这是有局限性的,但它是解决历史需求的简单方法,在过度设计之前考虑它,而不是真正需要的东西。
复制DB方法的好处在于,除了不太庞大(每年66次+1次)之外,所有的东西仍然与它有此价值时所链接的内容相关联。缺点是:它是有损的(因此可能忽略了瞬态值),并且它是孤立的(您不能运行连接现在和过去的查询)。有其他方法,
发布于 2020-02-03 11:57:06
对聚会来说有点晚了,但也许这对最近有同样问题并发现了这条线索的人是有用的:
https://github.com/CivicGraph/CivicGraph
免责声明:我是CivicGraph的作者/维护者,我是为了解决在图形数据库中保存和查询历史的问题而做的。
https://softwareengineering.stackexchange.com/questions/323444
复制相似问题