Mysql&NoSQL

从InfoQ得来一篇文章

[

怎么样把NoSQL引入到我们的系统架构设计中,需要根据我们系统的业务场景来分析,什么样类型的数据适合存储在NoSQL数据库 中,什么样类型的数据必须使用关系数据库存储。明确引入的NoSQL数据库带给系统的作用,它能解决什么问题,以及可能带来的新的问 题。下面我们分析几种常见的NoSQL架构。

(一)NoSQL作为镜像

不改变原有的以MySQL作为存储的架构,使用NoSQL作为辅助镜像存储,用NoSQL的优势辅助提升性能。


//写入数据的示例伪代码 

//data为我们要存储的数据对象 
data.title=”title”; 
data.name=”name”; 
data.time=”2009-12-01 10:10:01”; 
data.from=”1”; 
id=DB.Insert(data);//写入MySQL数据库 
NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库

如果有数据一致性要求,可以像如下的方式使用

//写入数据的示例伪代码 
//data为我们要存储的数据对象 
bool status=false; 
DB.startTransaction();//开始事务 
id=DB.Insert(data);//写入MySQL数据库 
if(id>0){ 
    status=NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库 
} 
if(id>0 && status==true){ 
    DB.commit();//提交事务 
}else{ 
    DB.rollback();//不成功,进行回滚 
}

上面的代码看起来可能觉得有点麻烦,但是只需要在DB类或者ORM层做一个统一的封装,就能实现重用了,其他代码都不用做任何的修 改。

这种架构在原有基于MySQL数据库的架构上增加了一层辅助的NoSQL存储,代码量不大,技术难度小,却在可扩展性和性能上起到 了非常大的作用。只需要程序在写入MySQL数据库后,同时写入到NoSQL数据库,让MySQL和NoSQL拥有相同的镜像数据, 在某些可以根据主键查询的地方,使用高效的NoSQL数据库查询,这样就节省了MySQL的查询,用NoSQL的高性能来抵挡这些查 询。


这种不通过程序代码,而是通过MySQL把数据同步到NoSQL中,这种模式是上面一种的变体,是一种对写入透明但是具有更高技术 难度一种模式。这种模式适用于现有的比较复杂的老系统,通过修改代码不易实现,可能引起新的问题。同时也适用于需要把数据同步到多种 类型的存储中。

MySQL到NoSQL同步的实现可以使用MySQL UDF函数,MySQL binlog的解析来实现。可以利用现有的开源项目来实现,比如:

有了这两个MySQL UDF函数库,我们就能通过MySQL透明的处理Memcached或者Http协议,这样只要有兼容Memcached或者Http协议的NoSQL数 据库,那么我们就能通过MySQL去操作以进行同步数据。再结合lib_mysqludf_json , 通过UDF和MySQL触发器功能的结合,就可以实现数据的自动同步。

(二)MySQL和NoSQL组合

MySQL中只存储需要查询的小字段,NoSQL存储所有数据。


//写入数据的示例伪代码 

//data为我们要存储的数据对象 
data.title=”title”; 
data.name=”name”; 
data.time=”2009-12-01 10:10:01”;
data.from=”1”;
bool status=false; 
DB.startTransaction();//开始事务 
id=DB.Insert(“INSERT INTO table (from) VALUES(data.from)”);//写入MySQL数据库,只写from需要where查询的字段 
if(id>0){ 
    status=NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库 
} 
if(id>0 && status==true){ 
    DB.commit();//提交事务 
}else{ 
    DB.rollback();//不成功,进行回滚 
}

把需要查询的字段,一般都是数字,时间等类型的小字段存储于MySQL中,根据查询建立相应的索引,其他不需要的字段,包括大文本 字段都存储在NoSQL中。在查询的时候,我们先从MySQL中查询出数据的主键,然后从NoSQL中直接取出对应的数据即可。

这种架构模式把MySQL和NoSQL的作用进行了融合,各司其职,让MySQL专门负责处理擅长的关系存储,NoSQL作为数据 的存储。它有以下优点:

  • 节省MySQL的IO开销。由于MySQL只存储需要查询的小字段,不再负责存储大文本字段,这样就可以节省MySQL存储 的空间开销,从而节省MySQL的磁盘IO。我们曾经通过这种优化,把MySQL一个40G的表缩减到几百M。
  • 提高MySQl Query Cache缓存命中率。我们知道query cache缓存失效是表级的,在MySQL表一旦被更新就会失效,经过这种字段的分离,更新的字段如果不是存储在MySQL中,那么对query cache就没有任何影响。而NoSQL的Cache往往都是行级别的,只对更新的记录的缓存失效。
  • 提升MySQL主从同步效率。由于MySQL存储空间的减小,同步的数据记录也减小了,而部分数据的更新落在NoSQL而不 是MySQL,这样也减少了MySQL数据需要同步的次数。
  • 提高MySQL数据备份和恢复的速度。由于MySQL数据库存储的数据的减小,很容易看到数据备份和恢复的速度也将极大的提 高。
  • 比以前更容易扩展。NoSQL天生就容易扩展。经过这种优化,MySQL性能也得到提高。
]
我仔细考虑了一下,对于使用UDF来实现同步是最好的办法,理由是针对访问数据源的代码,没有必要在写的时候有
维护两个数据源的逻辑,只需要操作mysql就可以了,读的时候,mysql只是冲当了数据库结构元数据的角色,
读数据量又很小,数据都在NoSQL上,它本身又非常快,支持海量的数据。

 最近有个项目,是根据MT5的模型来开发一个外汇交易系统,正在考虑这样的数据库架构。
### MySQLNoSQL数据库的比较及区别 #### 1. 数据模型 MySQL 是一种关系型数据库管理系统 (RDBMS),采用基于表的关系模型来组织数据。这种模型强调规范化,通过外键约束和其他机制确保数据的一致性和完整性[^1]。相比之下,NoSQL 数据库并不局限于单一的数据模型,而是支持多种类型,例如键值对、文档、列族和图形等。这些灵活的数据表示形式使其非常适合处理半结构化或非结构化的复杂数据集[^2]。 #### 2. 查询语言 在查询方面,MySQL 使用标准化的 SQL(Structured Query Language)来进行定义、操纵以及控制数据库对象的操作。SQL 提供了一套强大且统一的方式去检索、更新甚至删除记录[^3]。然而,在 NoSQL 领域里并没有通用的标准语法;每种具体的实现都有自己的 API 接口或者 DSL(domain-specific language)用于执行相似的任务。比如 MongoDB 利用 JSON 样式的 BSON 文档配合 JavaScript 表达式完成 CRUD 功能[^4]。 #### 3. 扩展性 传统的垂直扩展方法适用于像 MySQL 这样的集中式存储方案,即增加单台机器上的计算能力和磁盘容量以满足增长的需求。但是当达到硬件极限后成本会急剧上升,并可能遇到瓶颈问题。另一方面,许多现代分布式架构下的 NoSQL 系统天生具备水平扩展能力,可以通过简单地向集群添加更多廉价的商品级服务器节点轻松应对海量规模的工作负载压力[^4]。 #### 4. 性能表现 对于OLTP在线交易处理类应用场景来说,经过良好调优后的 MySQL 实例往往能够在中小范围内表现出色。而对于那些需要极高并发度读取操作或是大规模数据分析挖掘工作的场合,则可能会发现某些专门针对此目的设计出来的新型态 Nosql 解决方案更加高效快捷一些。 #### 5. ACID vs BASE MySQL 默认遵循严格的ACID原则(Atomicity, Consistency, Isolation, Durability),这意味着每一次成功的事务都将永久保存下来并保持整个系统的状态一致性[^1]。而部分流行的 NoSQL 平台则倾向于宽松些的BASE理论(Basically Available Soft state Eventual consistency),它们优先考虑可用性和分区容忍度而非即时强一致性的保障[^4]。 --- ```python # 示例代码:创建简单的 MySQL 和 MongoDB 连接测试 import mysql.connector from pymongo import MongoClient try: # 创建 MySQL 连接 mydb = mysql.connector.connect( host="localhost", user="root", password="password" ) if mydb.is_connected(): print("Successfully connected to MySQL") except Exception as e: print(f"MySQL Error: {str(e)}") try: # 创建 MongoDB 客户端实例 mongo_client = MongoClient('mongodb://localhost:27017/') if 'test' in mongo_client.list_database_names(): print("MongoDB is accessible and contains test database.") except Exception as f: print(f"MongDB Error:{f}") ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值