我正在开发一款适用于Android的简单应用。我使用Firebase数据库时遇到了一些问题,因为它使用的是JSON对象,而且我习惯使用关系数据库。
我的数据将包含两个共享值的用户。在关系数据库中,这将在如下表格中表示:
**uname1** **uname2** shared_value
其中用户名是键。如果我想要用户Bob与其他用户共享的所有值,我可以执行一个简单的union语句,该语句将返回以下行:
uname1 == Bob or unname == Bob
但是,在JSON数据库中,数据中似乎存在树状层次结构,这很复杂,因为我无法在顶层搜索用户。如果我最常见的搜索类似于上面的搜索,我正在寻找有关如何执行此操作或如何构建数据库以获得最佳效率的帮助。
如果这个信息不够,我会详细说明:我的数据库结构如下:
{
'username': 'Bob'
{
'username2': 'Alice'
{
'shared_value' = 2
}
}
'username': 'Cece'
{
'username2': 'Bob'
{
'shared_value' = 4
}
}
从示例中可以看出,Bob包含在两个关系中,但是查看Bobs节点并未显示该信息。 (这种关系是可交换的,所以谁是“第一”无法预测)。
解决此问题的最直观方法是复制所有数据。例如,当我们添加Bob-> Alice-> 2时,还添加Alice-> Bob-> 2。根据我对关系数据库的经验,重复可能是一个大问题,这就是为什么我还没有这样做。此外,复制似乎是一种低效的解决方案。
答案 0 :(得分:1)
你有没有理由不反过来?像这样的集合怎么样:
{ "_id": 2, "usernames":[ "Bob", "Alice"]}
{ "_id": 4, "usernames":[ "Bob", "Cece"]}
如果您需要“Bob”的所有值,请在“usernames”上编制索引。
编辑:
如果您需要两个用户名作为唯一键,请执行以下操作:
{ "_id": {"uname1":"Bob", "uname2":"Alice"}, "value": 2 }
但这仍然允许创建:
{ "_id": {"uname1":"Alice", "uname2":"Bob"}, "value": 78 }
(这个问题也存在于你的原型关系模型中,顺便说一句。你如何处理它?)
一般情况下,我认为通过创建多个名称为"attr1"
,"attr2"
,"attr3"
等列的列来实现数组,然后必须搜索所有可能值的值关系表建模的工件,它不支持数组值。如果要转换为面向文档的存储,这些应该是嵌入的值列表,您应该使用文档范例并对其进行建模,而不是仅仅将表行重新实现为文档。
答案 1 :(得分:1)
您仍然可以使用旧结构:
[
{ username: 'Bob', username2: 'Alice', value: 2 },
{ username: 'Cece', username2: 'Bob', value: 4 },
]
您可能希望在'username'和'username2'上创建索引以获得性能。然后做同样的工会。
答案 2 :(得分:0)
要创建树状结构,最好的方法是创建一个“祖先”数组,用于存储特定条目的所有祖先。这样,您可以查询祖先或后代以及与树中特定值相关的所有文档。使用您的示例,您将能够搜索Bob的所有后代或他的任何祖先(以及相关文档)。
上面的答案表明:
{ "_id": {"uname1":"Bob", "uname2":"Alice"}, "value": 2 }
这是正确的。但是你没有看到Bob和Cece之间的关系。我的建议来自Mongo,是将祖先密钥存储在祖先数组中。
{ "_id": {"uname1":"Bob", "uname2":"Alice"}, "value": 2 , "ancestors": [{uname: "Cece"}]}
使用此设计,您仍然可以获得重复项,这是您不想要的。我会这样设计:
{"username": "Bob", "ancestors": [{"username": "Cece", "shared_value": 4}]}
{"username": "Alice", "ancestors": [{"username": "Bob", "shared_value": 2}, {"username": "Cece"}]}