在JSON中存储对象引用

时间:2013-12-12 20:37:48

标签: javascript json sqlite angularjs database-design

我目前正在构建一个非常复杂的AngularJS应用程序,它将数据存储在sqlite数据库中。我的应用程序数据包含对整个应用程序共享的对象的引用。 Angular能够渲染这些数据,比较它,到目前为止一切都很好。

这是什么意思?查看此示例,了解我的应用程序中对象的“样板”。

var Person = {
    name:'some person',
    owns:[]
}

var Cat = {
    name:'some cat'
}

var project = {
    name:'some project',
    people:[],
    cats:[]
}

我的应用程序将允许用户创建和操作这些对象,并在它们之间创建关系。可以创建Person的实例,并且每个Person对象可以存储对Cat的实例的引用。

正如您可能已经猜到的那样,在用户完成操作后,我的project最终将会显示为此内容。

var project = {
    name:'some project',
    people:[person, person, person],
    cats:[cat, cat cat, cat, cat, cat]
}

console.log(project.people[0].owns)
//logs something like "cat, cat, cat". These are references.

我的应用程序会设置视图以查看每个person,并会列出owns属性,其中包含Cat的实例。

一切都很好,直到我意识到在数据库中将这个存储为JSON可能会有并发症。 JSON.Stringify()angular.toJSON()不会将引用视为引用,而是将它们作为单个对象读取。

我希望获得一些关于保存这些关系/参考的最佳方法的见解。

以下是我认为的两种选择。

选项1: 废弃将其存储在JSON中的想法,并使用关系数据库来存储所有内容。这并不理想,因为它开始吞噬AngularJS中对象渲染的灵活性。此外,这些数据将存储在多个地方(在线和本地),这可能会带来数据库方案的差异,这将成为调试的噩梦。

选项2:PersonCat的每个实例存储唯一标识符。然后,我可以在渲染和创建关联时使用此标识符。如果我在Angular中创建自定义过滤器,这将有效,但删除对象时全局删除引用可能是一场噩梦。

1 个答案:

答案 0 :(得分:4)

传统的基于表的关系数据库已经解决了这个问题。可以在多个上下文中引用的每个记录/文档都存储在具有id的自己的表/集合中。 id由其自己的集合中的其他对象引用。

JSON本身只会保存原始数据,因此您注意到,更改的对象引用不是JSON可以处理的内容。

所以问题就变成了,数据是一阶对象之间的关系吗?或者是嵌套/嵌入另一个对象?

在您的示例中,项目有很多人,项目有很多猫,人们有很多项目。因此,人员和项目都需要被多个其他对象引用,每个资源应该是它自己的资源,由外键引用。

// projects.json
[
  {
    id: 4
    name: 'homework',
    person_ids: [1,2,3],
  }
]

// people.json
[
  {
    id: 1,
    name: 'Bob',
    project_ids: [4,5,6],
  }
]

嵌入的一个好例子可能是对项目的评论。在这种情况下,您始终可以通过项目访问注释。而且因为评论只能属于一个项目,所以嵌入它更有意义。

// projects.json
[
  {
    id: 4
    name: 'homework',
    person_ids: [1,2,3],
    comments: [
      {
         person_id: 1,
         message: 'My dog ate it'
      ]
    ]
  }
]

我建议您阅读Mongoid handles relations的方式。它是MongoDB的ruby包装器,但文档解释了它如何构建集合以实现关系。你可能会发现了解它如何运作是非常有帮助的。