在阅读了我的另一个问题,使用关系数据库获得无架构数据之后,我开始怀疑文件系统是否比关系数据库更适合存储和查询无模式数据.
而不是仅仅在MySQL之上构建文件系统,为什么不直接将数据保存到文件系统?需要弄清楚索引,但现代文件系统非常稳定,具有复制,快照和备份功能等强大功能,并且可以灵活地存储无模式数据.
但是,我找不到任何使用文件系统而不是数据库的人的例子.
在哪里可以找到有关如何将无模式(或"面向文档")数据库实现为文件系统顶层的更多资源?是否有人使用现代文件系统作为无模式数据库?
在阅读了Bret Taylor(FriendFeed的联合创始人,Facebook当前首席技术官)撰写的一篇令人震惊的文章之后,FriendFeed 如何使用MySQL来存储无模式数据,我开始怀疑是否有使用RDBMS的最佳实践,如Oracle,用于存储和查询无模式数据的MySQL或PostgreSQL?
当NoSQL成为新的热点时,很少有人愿意承认他们正在使用关系数据库,这使得很难找到关于该主题的好文章.如何将无模式(或"面向文档")数据库实现为关系数据库之上的层?
我们使用MySQL来存储无模式数据(请参阅:使用关系数据库获取无模式数据,以获得受FriendFeed如何使用MySQL存储无模式数据的解决方案).
一个大表包含我们应用程序的所有实体:
CREATE TABLE entities (
added_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, id BINARY(16) NOT NULL
, body MEDIUMBLOB
, UNIQUE KEY (id)
) ENGINE=InnoDB ;
Run Code Online (Sandbox Code Playgroud)
一些细节:
存储实体唯一需要的属性是id一个16字节的UUID.实体的其余部分对数据库不透明.我们可以简单地通过在中存储新属性来更改"模式" body.
该added_id列存在,因为InnoDB以主键顺序物理存储数据行.AUTO_INCREMENT主键确保在旧实体之后按顺序在磁盘上写入新实体,这有助于读取/写入位置(新实体比旧实体更频繁地读取).
我们的数据库将我们的无模式数据存储在body.< - 这是这个问题的主题.
许多其他有趣的细节,比如"进入" body数据以构建异步物化视图(索引只是离线构建的表),但它们与当前的讨论无关......
我们应该如何序列化结构化数据(键值对)body?
JSON或BSON很简单,因为每行重复字段名称.这使其具有灵活性的优势,但在空间效率方面也是一个很大的缺点(序列化数据中字段名称的每行开销).我们试图将内容保留在内存中,并且最小化内存和网络占用空间非常重要.我们可以在同一空间中放置的记录越多,查询的速度就越快.我们更喜欢相对较长的描述性字段名称,并缩短它们以使我的数据库更快是错误的!
最后,JSON/BSON对于我们的目的是不可行的,除非我们变得更复杂并将小键映射到与数据库对话的应用程序驱动程序中的更具描述性的键.这让我们思考......
虽然我们的数据库是无模式的,但实际上:1)没有太多不同类型的实体,2)同一类实体的版本不经常更改,3)当它们确实发生变化时,通常只是添加另一个领域.JSON/BSON没有版本控制的原生支持.
在版本控制和数据定义更改方面,Protocol Buffers和Thrift更加复杂.Thrift和Protocol Buffers都是将数据序列化到数据库的理想选择,而Thrift的设计使得编码格式是可扩展的.
协议缓冲区看起来是在无模式数据库中序列化数据的绝佳选择.
CouchDB和MongoDB(两个最流行的无模式数据库?)分别使用JSON和BSON,但我们找不到任何关于使用更高级的东西,比如Protocol Buffers,作为存储无模式数据的序列化格式.有些产品存储特定语言的对象版本(即将Java的Externalizable对象存储在数据网格中,或者在Ruby中使用MySQL进行NoSQL),但这些都很痛苦(尝试从其他平台访问它们,甚至从MySQL本身访问它们,并忘记版本控制).
是否有人在其数据库中存储更具互操作性的协议缓冲区,或在其无模式数据库中存储其他一些高级序列化格式?这是一个问题,除了JSON/BSON/XML的直接每行序列化,还是序列化特定语言的对象之外,是否还有其他选项.它甚至可行吗?我们错过了什么吗?对不起意识风格的叙事流!