Google Apps Engine将Google Datastore作为唯一的NoSQL数据库提供(我认为它基于BigTable).
在我的应用程序中,我有一个类似社交的数据结构,我想像在图形数据库中那样对其进行建模.我的应用程序必须保存异构对象(用户,文件,...)和它们之间的关系(例如user1 OWNS file2,user2 FOLLOWS user3等).
我正在寻找一种模拟这种典型情况的好方法,我想到了两个解决方案系列:
基于列表的解决方案:任何对象都包含其他相关对象的列表,列表中的对象存在本身就是这种关系(正如Google在JDO部分中所说的那样https://developers.google.com/appengine/docs/java/datastore/jdo/relationships).
基于图形的解决方案:节点和关系都是对象.对象独立于关系存在,而每个关系包含对两个(或更多)连接对象的引用.
这两种方法的优点和缺点是什么?
关于方法1:这是一个人们可以想到的更简单的方法,它也出现在官方文档中,但是:
每个有向关系都会使对象记录增长:例如,对象维度限制给出的可能关系的数量是否有任何限制?
这是JDO功能还是数据存储结构允许自然实现该方法?
关系搜索时间会随着列表而增加,这个解决方案是否适合大(百万)关系?
关于方法2:每个关系可以具有更高级别的特征(它是一个对象,它可以具有属性).我认为内存大小不是Google的问题,但是:
每个关系都需要自己的记录,因此每个相关夫妇的搜索时间将随着关系总数的增加而增加.这适合大量的关系(数百万,数十亿)?即如果Google的结构良好,Google是否有很好的搜索记录?或者我将很快处于这样一种情况:如果我想搜索User1的朋友User4,我必须等待几秒钟?
另一方面,随着新关系的添加,每个对象的维度不会增加.
你能帮助我找到两种方法的其他重点,以这种方式选择最佳模型吗?
首先,数据存储区中的搜索时间不依赖于您存储的实体数量,而仅取决于您检索的实体数量.因此,如果您需要在十亿之中找到一个关系对象,则需要花费相同的时间,就像您只有一个对象一样.
其次,列表方法有一个严重的限制,称为"爆炸指数".您必须索引包含列表的属性以使其可搜索.如果您使用的参数不仅仅引用了此属性,那么您将遇到此问题 - 谷歌了解其含义.
第三,列表方法要贵得多.每次添加新关系时,都会以相当高的写入成本重写整个实体.如果您不能使用仅限密钥查询,那么阅读成本也会更高.使用对象方法,您可以使用仅键查询来查找关系,此类查询现在是免费的.
更新:
如果您的关系是定向的,您可以考虑将关系实体作为User实体的子项,并使用Object id作为Relationship实体的id.那么您的Relationship实体将根本没有属性,这可能是最具成本效益的解决方案.您将能够使用仅限键的祖先查询来检索用户拥有的所有对象.