20
十一月
2013
自由模式的MySQL vs NoSQL
2268 阅读|收藏

烟雨寒武纪般替代数据库引擎的大爆发(又名NoSQL),却很容易忽略掉一个事实,即已建立的解决方案,如关系数据库,仍然有很多贡献:稳定和可靠的代码 库,驱动程序和人人可以想象的语言工具,以及比数据库管理员关心和了解的更多功能。且不说关系与否,在面对大数据集时,很多时候其功能与其他任何单实例的 键-值存储(系统)一样---这也是 RiakVoldemort及其他人采用InnoDB 作为数据引擎的原因。诚然,“功能膨胀”也是重写是好主意的原因,但感觉NoSQL社区往往忽视这样的灰色地带-即使是“NoSQL”,但并不意味着抛弃投入关系数据库的多年工作。

不可否认的是,目前还没有对“NoSQL”的精确定义,通常的判定依据是:基于文档(document based),无模式(schema-free),分布式和“可扩展”。事实上,分布式和可扩展不是一回事,但这是另一篇文章的主题。让我们来仔细分析无模式和基于文档的实际含义。 事实上,回到本文的主题,我确实感到惊讶,还没有看到一个构建在MySQL之上的自由模式引擎。 但是你暂停怀疑,因为它并不像听起来那么离谱。

基于文档:一把双刃剑

采用关系模型的初始原因或益处是限制数据模式(读,消除数据结构的复杂性,或将其分解为关系),实际上是获得了对数据库进行查询的能力和灵活性。另一种说法是,数据设计标准化让我们拥有一个通用的查询语言 ,这使得在设计的甚至不必知道查询参数,尽管标准化设计不如此进行。虽然丧失了数据结构的灵活性,但获得了与数据交互的能力。因此,从理论上讲,如果无法预测未来的查询类型,关系模型是您最好的选择。失去一些,赢得一些,二者是矛盾的。

与此同时,我们都知道“no join is faster than on join”。分解数据的固有缺点是所需的组装性。 如果你追求”速度“或”可扩展性,那么“去数据中心化”通常是第一步。现在,为数据引入了许多潜在异常:更新,插入和删除可能会导致数据不一致,除非将所有的重复仔细核查。1对1(One-to-One),1对多(One-to-Many)关系通常易于管理,但多对多(Many-to-Many)的非规范化模式却是灾难性的。 也就是说,如果你很看重数据的一致性 。


最后,失去的是通用功能的查询语言(SQL),却需要获得新数据库所提供的DSL的怜悯。MongoDB、Couch和许多其他(NoSQL数据库)不得不引入自己的查询语言实现“Map Reduce”功能,以解决任意深度记录的查询问题。现在,我是二者的粉丝,但坦率地说,noSQL仍旧有些模糊,或不像SQL容易理解 -且不说需要学习新的查询语言的缺点。

 

 

无模式 != 基于文档(Schema-free != Document based)

基于文档和无模式,往往交替使用,但有一个重要的区别:无模式并不一定意味着嵌套的数据结构。 同理,不能因为MySQL是“关系型”就意味着它必须一个预定义的模式 - 在创建时而非运行时。结合前二者的描述,绝不意味着不能基于MySQL实现无模式(数据库)引擎。

mysql> USE noschema;
mysql> CREATE TABLE widgets;  /* look ma, no schema! */
mysql> INSERT INTO widgets (id, name) VALUES("a", "apple");
mysql> INSERT INTO widgets (id, name, type) VALUES("b", "blackberry", "phone");
mysql> SELECT * FROM widgets WHERE id = "a";
+---------+---------------+
| id      | name          |
+---------+---------------+
| a       | apple         |
+---------+---------------+
mysql> SELECT * FROM widgets;
+---------+---------------+--------+
| id      | name          | type   |
+---------+---------------+--------+
| a       | apple         | NULL   |
| b       | blackberry    | phone  |
+---------+---------------+--------+

只要避免嵌套的数据结构,那么就没有理由受限于表中定义的列,因为可在运行时组合和分解的任何(数据)关系。这不仅意味着没有迁移或需要存储空值,但却可以保留所有工具、驱动程序和SQL查询语言,同时还增加了无模式的全部灵活性。

基于MySQL的无模式数据库

无法找到任何相关的项目,周末我完成了自己的原型,不管相信与否,它工作得很好。  事实上,从上面的输出源自一个真正的mysql会话控制台。它包含一个带有点底层协议em-proxy(em:EventMachine)服务器和查询重写,突然之间,我的MySQL忘记了它还需要模式。可以自己测试一下(需要Ruby1.9)。

git clone git://github.com/igrigorik/em-proxy.git && cd em-proxy
ruby examples/schemaless-mysql/mysql_interceptor.rb
mysql -h localhost -P 3307 --protocol=tcp
# snip ... 
# build the select statements, hide the tables behind each attribute
join = "select #{table}.id as id "
tables.each do |column|
  join += " , #{table}_#{column}.value as #{column} "
end
# add the joins to stich it all together
join += " FROM #{table} "
tables.each do |column|
  join += " LEFT OUTER JOIN #{table}_#{column} ON #{table}_#{column}.id = #{table}.id "
end
join += " WHERE #{table}.id = '#{key}' " if key

mysql_interceptor.rb - MySQL Proxy in Ruby

Downloads: 583 File Size: 0.0 KB

当然,这不过是一个可爱的代码示例,也没有覆盖不同的使用情况,但是来看看其功能设置:各种语言的驱动程序支持(可以让它指向 Rails+ActiveRecord 、JDBC等,开箱即用,没问题),工具支持(GUI和命令行),复制功能,基本上不可能崩溃,事务等等。 基于后台简单的数据模型:


 

而非定义表的列,每个属性都有它自己的表(新表是动态创建的),这意味着可以随意添加和删除属性。 反之,要完成Select需要通过指定的键值 (key)连接(join)所有的表。 对于客户端,这是完全透明的,而代理服务器并不参与实际工作,这样的功能可以很容易地从一个适当的MySQL引擎中提取-但我很惊讶,没有人这样做!为谨 慎起见,可以检出代理代码,其中包含许多注释以说明整合的实现方法。

SQL相较NoSQL的灰色地带

所有这一切的要点是什么呢?是的,其 实我希望有人写这样的引擎,因为我相信它有市场。还可以阐述很多,SQL兼容,无模式(shema-free)引擎,不像什么NoSQL的宣传所说,这是 绝对没有理由我们不能基于MySQL本身获得如同“NoSQL的”好处。没有一个数据库引擎或模型的明显赢家,所以你的前提决定思路。正因为Mongo、 TC或Couch是基于文档(document-based)或无模式(shema-free)的数据库,但并不意味着它们更适用于你的应用。 同时请不要误会,我仍然全力支持所有的NoSQL项目,并对Drizzle寄予厚望 - 它们都在进行奇妙的工作。

http://www.igvita.com/2010/03/01/schema-free-mysql-vs-nosql/

已有0条评论
还没有发表任何评论!
相关资讯
0/1351NoSQL的Schema相关词语
0/1176NOSQL模式 -(2)
0/1224NOSQL模式 -(3)
0/969NOSQL模式 -(1)
0/2451设计模式比较:Adapter vs Proxy vs Facade
0/1368MySQL/HandlerSocket和VoltDB:NoSQL的竞争者
0/1155HandlerSocket client for java——MySql as NoSQL
0/4047MongoDB vs. OrientDB
推荐排行
浏览记录