我正在为MongoDB设计我的第一个数据库,我想知道我是否在一个正确的方向。
这基本上是一个模拟的剧院预订系统。2或3个层次的嵌套有什么本质上的错误吗?
会在以后的查询中产生问题吗?
性能和可用性的最佳解决方案是什么?
我是否应该像对待预订的客户那样使用推荐信?
到目前为止我写的是:
//shows
{
_id: 2132131,
name: 'something',
screenplay: ['author1', 'author2'],
show_type: 'children',
plays: {
datetime: "O0:00:00 0000-00-00",
price: 120,
seats:
{
_id:['a', 1],
status: 'reserved',
client: 1
},
{
_id:['a', 2],
status: 'reserved',
'client:1
}
}
}
//clients
{
_id:1,
name: 'Julius Cesar',
email: 'julius@rome.com',
}
你可能会听到不同的意见,但我想和你分享一下我的看法。
首先,您的模式似乎不适合您的用例。你很可能希望"plays"是一个数组而不是一个对象,所以:
{
"_id":2132131,
"name":"something",
"screenplay":[
"author1",
"author2"
],
"show_type":"children",
"plays":[
{
"datetime":"O0:00:00 0000-00-00",
"price":120,
"seats":[
{
"_id":[
"a",
1
],
"status":"reserved",
"client":1
},
{
"_id":[
"a",
2
],
"status":"reserved",
"client":1
}
]
}
]
}
如果我的假设是正确的,你现在有双嵌套数组,这是一个非常不切实际的模式,因为你不能在查询或更新中使用多个位置操作符。
尽管大多数NoSQL人群似乎认为,实际上只有少数有效的用例将集合嵌入到文档中。需要满足以下条件:- 嵌入式集合在大小方面有非常明确的上限。这个限制不应该超过几十个,否则就会变得笨拙/低效。
- 嵌入的集合不应该定期增长(这会导致文档在磁盘上移动,从而显著降低性能)
- 嵌入集合中的元素不应该包含数组属性(当前的查询语言不允许您修改双嵌套数组的特定元素)
- 你永远不应该在不查询包含该嵌入集合的根文档的情况下要求嵌套集合的元素。
你会发现并不是所有的情况都能满足以上所有的条件。其中一些标准有些主观,但轻量级引用实际上并没有那么复杂。实际上,您会发现,不能"自动"修改不同集合中的文档是唯一的复杂之处,而且在大多数情况下,这并不像听起来那么严重。
TL;DR:不要双嵌套数组;把"plays"放到一个单独的集合
通常你应该总是喜欢在MongoDB中嵌入而不是引用,所以你已经朝着正确的方向前进了。
对1:n关系使用引用的唯一原因是当您有不断增长的对象时,因为导致文档大小增长的更新可能很慢。然而,看起来您正在处理的数据不会非常频繁地增长(可能一天几次),这可能意味着您不应该遇到性能问题。