文章

数据库选型

数据库产品有很多种:Redis,MySQL,Oracle,MongoDB,HBase等等。面对众多的存储技术,我们该如何进行技术选型呢?

Redis

首先,Redis的使用场景最明确,作为高速缓存或key-value数据库使用,当作为key-value数据库使用时,一般会开启持久化存储,但它的持久化是以快照的形式存在的,所以在重启导致内存数据失效,尝试用本地持久化数据恢复时,可能会造成数据丢失,另外恢复也需要额外的时间,所以更常见的做法是以集群的形式对外提供服务,集群内可以分片,分片内还可以有主-从,主-备,双写随机读等各种策略来保证可用性和性能。但Redis作为数据库使用也有它的问题,它没有办法像关系型数据库那样做范围检索,条件更新等操作,所以它更适合以单个主键型实体为核心开展的业务。

关系型数据库

然后是关系型数据库Oracle,MySQL等,适用大部分关系型实体的增删改查操作,还有事务和索引支持。Oracle在单表数据量上,功能全面性上要优于MySQL,但并不免费开源。相比之下,MySQL在社区各种魔改下,使用场景更多一些,MySQL作为单体服务,原生并不支持分布式,它的分库分表需要借助各种外部组件来实现。这些组件有些是作为客户端功能包而存在,有些则是作为独立中间件,服务而存在。分库分表又包括水平拆分和垂直拆分,是个比较大的问题。但怎么都绕不开几个核心问题:

  • join怎么处理
  • 事务怎么处理
  • 数据怎么扩容
  • 怎么迁移
  • ID怎么保证不重复

这些问题想明白了,就能设计一个分库分表组件。

文档型数据库

有时一个表的字段内容很复杂,或结构变化频率很高,为了保证表结构的稳定性,在数据设计三大范式基础上,我们还会采用一些“逆范式”设计,即把一个大字段作为一个整体以json形式存在一个字段里,这会导致条件查询和更新失效,但带来了处理上的简洁和表结构上的稳定。但如果发现有处理的业务几乎都是需要json型字段的时候,就要考虑文档型数据库MongoDB了,MongoDB不需要预先定义表结构,每个文档的字段结构也是可以动态变化的,还支持按字段的各种条件检索,并且天然就是支持分布式的,也是因为如此,它不支持事务,只能实现最终一致性。

列式数据库

最后聊聊Hbase,Hbase是一个典型的列式数据库,空值不存储数据,所以存储空间比MySQL利用率更高,单表行可以到亿级别,列可以到百万级别,也可以针对列或列族单独进行操作,它的挑战和MySQL不同,在于RowKey的设计,因为它只支持按单个RowKey查询或RowKey范围检索,所以RowKey结构设计的不合理,不符合查询习惯时,会让检索多扫描很多数据甚至不可用,此外RowKey设计还要考虑检索的集中性和避免更新热点,是个既考验技术,有考验业务理解的活儿。

总结

当然,每个存储技术都不是十全十美的,它们都有自己的长处和短板,因此也都有自己的适用场景,就像我们工具箱里的工具当我们清楚的了解每中技术的特点和背后的设计思想时,再结合应用具体的的业务场景,就能取长补短,游刃有余了。

本文由作者按照 CC BY 4.0 进行授权