客户端数据存储的规范化多对多模式

时间:2017-02-27 13:26:03

标签: redux vuex database-normalization normalizr

我正在开发社交网络应用程序的浏览器前端。它有很多关系数据,具有一对多(1:m)和大多数多对多(m:m)关系,如下表所示。

我想在应用程序中使用Flux数据流架构。我在Vue.js中使用Vuex.js。

正如在Redux.js文档中所表达的那样,最好为various reasons使用平坦的,规范化的存储状态形状以便与React一起使用,我认为这也适用于Vue.js。< / p>

  • 帖子有类别(m:m)
  • 帖子有标签(m:m)
  • 发表评论(1:m)
  • 帖子中有主题标签(m:m)//或者用户创建主题标签
  • 帖子中有提及(m:m)//或用户创建用户提及

  • 用户喜欢帖子(m:m)

  • 用户关注用户,帖子,帖子类别等(m:m)
  • 用户最喜欢的帖子(m:m)

我需要显示帖子Feed以及其他实体的所有相关数据,例如用户,评论,类别,标签。为此,就像拥有 1:很多关系一样,在 one 方面持有此关系数据的多边(可以说是),即使它实际上是多对多,也可以通常查询他们组成他们的父母,即帖子 。但是,我还需要反向查询商店状态,例如,使用某个类别标记获取帖子

在这种情况下,对帖子来说并不是那么容易。我需要一个关系实体,它包含两个连接数据实体的 id 对,就像连接表关联表< / em>在RDBMS中,为了便于访问和更新,避免深入挖掘状态,并避免不必要的重新渲染(该要求是React或Vue.js和GUI特定的)。

如何相对容易和有效地实现这一目标,例如就像 1:很多关系一样?

1 个答案:

答案 0 :(得分:0)

根据您的最后评论。我将介绍在这种情况下当前使用的数据结构:

标记

{
 "type": "tag",
 "id": "tag1",
 "name": "Tag One"
}

要发布的标签

{
  "id": "someId",
  "type": "postTag",
  "tagId": "tag1",
  "postId": "post1"
}

发布

{
 "id": "post1",
 "name": "Post 1"
}

我发现M:M存储关系ID的每一面都可能产生孤儿。对这些ID的双重管理导致重复步骤和认知管理的增加,因为管理M:M的所有功能都发生在两个地方而不是一个地方。另外,关系本身可能需要包含数据,该数据将流向何处?

M:M没有实体

{
 "id": "post1",
 "name": "Post 1"
 "tagIds": [
   {id: "tag1", extraAttribute: false} //this is awkward
 ] 
}

要发布的标签-其他属性

{
  "id": "someId",
  "extraAttribute": false,
  "postId": "post1"
  "type": "postTag",
  "tagId": "tag1",
}

还有其他选项可以加快用少量肘部油脂提取标签的速度。

发布

{
 "id": "post1",
 "name": "Post 1"
 "tagIds" : ["tag1", "tag4"]
}

从理论上讲,一个帖子最多可以包含20个标签。使其成为通常可以忽略的存储要求以减少查找。我发现目前没有紧急需求,它具有10000个关系的数据库。

易于访问和更新

1:M是一个直接指向所需对象的对象。 M:M是两个指向它们之间关系的不同实体。为该关系建模,并集中逻辑

渲染器

  

如果您的应用程序呈现了很长的数据列表(数百或数千)   行),我们建议使用一种称为“窗口”的技术。这个   技术仅在任何给定时间呈现一小部分行,   并可以大大减少重新渲染   组件以及创建的DOM节点数。

https://reactjs.org/docs/optimizing-performance.html#virtualize-long-lists

我认为解决方案可能是针对特定用例的,并可能受到更广泛的意见。我遇到这个问题的原因是使用带有Vuex的沙发/小包和一个有20,000个条目的大型表。同样,在生产中这些问题并不是非常明显。结果将始终不同。

我在这里尝试了几件事:

  • 加载部分数据集:文件内(非反应性)vs内存(加载至Vuex)
  • 排序,分页,搜索文件内文件并加载结果