不要随意使用mongoDB
作者:挨踢直男
原文:http://suo.im/6xYQqy
mongodb是一种非关系数据库,最常见的作用是在某些领域作为关系数据库的替代品,相较于关系数据库它在性能上更有优势,因为不对事务以及数据完整性有硬性要求,所以在写入数据时效率更高。同时,mongdb的数据存储结构也比较灵活,只要是一个json结构就可以存储,相较于关系数据库的表结构定义,更加快捷方便。因为这些优势,mongodb迅速崛起,不断蚕食关系数据库从上个世纪就开始积累的市场份额。
关系数据库存储数据很规则,必须是表格的形式,且表格的结构需要事先定义好,每个字段的数据类型、长度需要明确,这样做的好处是表内的一切都井井有条、很清晰,坏处就是很繁琐。
而mongodb则相反,它对集合的结构没有统一的要求,任何结构的文档数据都可以写入同一个集合,在一个集合里,既可以写入用户数据,也可以写入订单数据,mongodb本身不做任何限制,一切约束全靠程序员自身。
mongodb的这种随意性是把双刃剑,能带来高效,也能造成灾难。尤其当项目涉及的开发人员越多,需求变化越频繁,mongodb存储的数据就越容易变成一个屎坑,你无法完全知道某一个集合中的文档哪些字段是有用的,哪些字段是没用的,你的程序不得不去配合这些未知的数据,从而造成不必要的繁琐,以及带来更多的BUG。
曾经经历过一个项目,数据库采用的是mongodb,在我接手时这个项目已经开发运营了三年。那时,我需要理清楚某一个功能运行逻辑,最好的方法自然是先弄清楚功能相关联的数据结构,于是我找到了那个功能依赖的mongodb集合,查看集合文档的结构。了解了文档结构之后,我修改了程序,完成了任务。然而修改后的功能总过会在某种情况下触发一个BUG,经过排查后发现,我之前看到的数据结构并不全面,在集合中某一批文档中还有别的字段被程序所依赖,找到问题后我修好了BUG。然而在之后某些情况下程序仍旧会出现BUG,排查后找到的原因也是类似之前,总之这种状态周而复始了好久才彻底修完了BUG。这就是之前的程序员对mongodb对数据结构约束性不强这以特性滥用的结果。如果是关系数据库,查看表结构就能清楚所有的数据字段,很多BUG也就可以提前避免。
要写出健壮且易于理解的程序,数据的存取必须是有模式的,比如关系数据库的表结构。然而关系数据库太过于死板,只能存储二维的表数据结构,虽然现代的关系数据库对json和xml做了很好的支持,但是并没有被广泛使用,大多数时候只是使用基本的表功能。要兼顾灵活性和健壮性两种优点,那么我们只能引入外部模式。
有两种结构化数据协议很流行,一种是google开发的protobuf协议,一种是facebook开发的apache thrift协议。这两种技术功能很强大,应用范围也很广,要讲清楚需要花费非常巨大的篇幅,读者可自行去网上了解。
这两种协议有一个核心的功能就是数据结构的描述,以可以直接写入mongodb的JSON以及php语言为例,有一个php数组,里面是需要存到数据库里的数据,我们将这个数组转换成JSON ,然后存入mongodb,这一步一般是mongodb提供的驱动库完成,这种方式我们很难约束数组的内容,自然的也难以约束转化成存入mongodb中JSON的内容,从而导致最终的失控。使用这两种技术之后,一切变得可控了,数据协议会生成对应语言的类结构,然后通过他们内置的库序列化成JSON并存入mongodb。反过来,程序读取是mongodb中的json,反序列化成语言的类结构供程序使用,字段的语义说明则都由协议定义接管。
总而言之,mongodb不建议像关系数据库那样独立使用,必须引入外部的模式定义,才能发挥作用同时避免副作用。
好文章,我在看
好文章,我在看