1
breeswish 2013-10-18 09:53:18 +08:00 1
每个小颗粒单位尽量扁平化,如果有整体小数据则可以在这里结构化。(因为MongoDB的查询和处理语言对于扁平化很方便,对于结构化的数据不方便)
|
2
Ricepig 2013-10-18 11:21:01 +08:00 1
结构化和分组的目的只有一个,那就是可读性吧
|
3
shiny 2013-10-18 11:23:36 +08:00 1
这个命题比一般人想象的更复杂,这个不应该参照普通 JSON 数据来。
应该搜索 「MongoDB 范式化 反范式化」。 举个我的血泪栗子:内嵌的 JSON 如果频繁更新,它就不应该是内嵌的,否则会有性能问题。 |
4
hepochen 2013-10-18 11:48:11 +08:00 1
JSON是JSON, MongoDB是MongoDB。
不论是扁平还是多层内嵌,是个人的选择问题;但只有一个前提,就是不能影响数据库的性能。 扁平相对而言是会简单一些,内嵌的,具体场景中,性能反倒会更高。 因为在MongoDB的底层存储中,对内嵌文档的处理并非是大家想象中的那般结构化,但比如要更新`collection.field1.field2.field3.field5`这到底更新了哪段信息?如果我有个字段名就是`field1.field2`的联合呢? @shiny 内嵌文档的大小也在频繁变化么? |
5
turing 2013-10-18 11:52:03 +08:00 1
我觉得嵌入文档还是分表存取决于数据库是主要是用来读还是写的
如果仅是展示用,比如从其他地方获取结构化的数据,保存在单一集合里,不用修改的方式,内嵌文档很好用,也很方便,如果频繁操作修改内嵌文档,就不太方便了。 |
6
shiny 2013-10-18 11:55:44 +08:00 1
除了性能,还要考虑需求实现是否方便。比如涉及日期范围的,用内嵌将会很痛苦(比如很多人把日期当做键而不是一个值……),操作内嵌文档,大多数命令也和范式化的不同。尤其是为了简洁,没什么多余字段的内嵌文档。
其次是大尺寸内嵌文档更难控制需要的字段,以前线上发现 tornado 内存不断增长却找不到原因,最后谨慎选择了下字段排除了不需要的、数据量大的字段就好了。 @hepochen 我的情况是不断 insert 的数据,卡得掉眼泪。 |
7
qiayue OP |
8
hepochen 2013-10-18 12:56:22 +08:00 3
呃,@shiny 同学,你可以考虑请我吃饭了。
用日期作为key,也未必是坏事。比如用作统计的,而且年/月/日这些固定的(非range性质)的,可以用正则的前向匹配,同时,也是可以使用索引的。所以,这反而是一个高效的处理办法。 但有一个问题,比如`2012-09`这样的key来存储一个月的数据(按天),那么,(有人)推荐的做法,是创建这个document的时候,就填充好31天的空数据。 呃,为什么是`2012-09`而不是`2012-9`呢? 这跟`2012-10`对比,会产生大小的问题,也可以很漂亮地解决时间被str化后的排序问题。 - - - - - 所有的字段如何控制,都是个人的一种选择。但是内嵌字段中出现一些特殊值,比如`$`开头的, 带`.`的,则要对MongoDB要更了解一些,不然很容易入坑。 - - - - 用内嵌文档,不会产生性能的问题。 用内嵌文档,并且不断insert,这会是性能问题产生的原因。 MongoDB是文档型的数据库,一个文档被创建的时候,默认会有保留多一点的空区域(这种机制,也会MongoDB等NoSQL数据库比较占磁盘空间的原因),可以方便以后的更新操作。但是,这个区域占满之后,磁盘空间就需要重新分派(这是极低效的)。 如果这是过程中,有多一点量的写操作涌进来,呃,肯定会“卡得掉眼泪”了。 |
9
zack 2013-10-18 13:05:08 +08:00 1
从存储空间的占用角度来看,尽量优先使用扁平化
|
10
shiny 2013-10-18 13:05:19 +08:00 1
@hepochen 谢谢
1、年月日我们是涉及一定范围内的统计的,更别说什么排序之类的,除非把数据全部取出来自己排。而如果是范式化的,就有现成的——当然数据处理不应该交给 MongoDB,这个时候才念起 SQL 的好来。 而且时间久了有可能出现巨大的内嵌文档(当然这个是设计错误,但是处理起来范式化的设计更容易处理点)。 2、字段是指有的字段包含大量数据,而不是说特殊字符。包含大量数据的字段,而且不是 PHP 这类用完就销毁的语言很可能内存爆满。范式化也有个好处是精准控制需要的数据。 3、我是在翻书后才知道,原话是「不断增长的内嵌文档将导致 IO 瓶颈」。如果 update 数据增长,也会是有问题的。当时我就一个进程后台默默写 MongoDB,也差不多写到了 IO 瓶颈——当然,数据量越大卡得越明显,刚设计完的时候还没发现。 |
11
shiny 2013-10-18 13:18:36 +08:00 1
@hepochen 有时需求很难实现,我会借助 map reduce,好像内嵌文档的 map reduce 比范式化的不易?
因为就一个人搞技术,情况复杂时有问题也没人讨论。 反正经历过这么一次后,把数据放 MongoDB 是谨慎又谨慎了。 |
13
goofansu 2013-10-19 01:10:11 +08:00 via iPhone
有本书叫mongodb design pattern,觉得还不错
|