数据库发展史

RDBMS

代表:oracle(商业),mysql(开源)。
关系型数据库 (RDBMS) 是当前应用最广泛的数据库管理系统,不仅可以存储数据,还可以进行复杂的数据运算(left join,子查询等)。
他存在着如下几个不足:

  1. 不能处理非结构化的数据。
  2. 本质上还是单机系统,很难满足海量数据的需求,要做分库分表。
  3. 可扩展性比较低。

NoSQL

NoSQL = not only SQL,分布式非关系型数据库,相比于RDBMS主要优势如下:

  1. 可以处理非结构化的数据
  2. 低延迟的读写速度
  3. 高性能和扩扩展性(牺牲了ACID事务)

NoSQL数据可以大致分为4种类型:

  1. 键值型数据库,比如Redis、Memcached等
  2. 文档型数据库,比如MongoDB等
  3. 列存储数据库,比如HBase,Cassandra等
  4. 图数据库:Neo4J等。

NewSQL

NoSQL虽然解决了RDBMS一些问题,但是并不能完全取代RDBMS,比如不能用sql查询数据,所以RDBMS还是无法满足性能问题,虽然可以通过分库分表,但是还是有一定的复杂性。
NewSQL = RDBMS + NoSQL,分布式关系型数据库,既满足线性扩展性,又能处理分布式事务,比如TiDB。

RDBMS架构演进

主从

所有业务放一个库,并做主从(通过binlog同步)。应用层的读写分离可以用第三方应用比如mycat、ShardingSphere,这两个也支持分库分表。
image.png

垂直拆分

分库,把商品、用户、订单拆出来,减少IO的竞争,而且连接数支持更多。
image.png
如果一个表的字段太长,也可以垂直拆分,把不常用的拆到新的表中,需要的时候再做表关联。比如原table的字段有(col1,col2,col3...col10),拆分后变成table(col1,col2,col3,col4,col5),table_ext(col6,col7,col8,col9,col10)。

水平拆分:

单个分片

分表,比如拆分4个,对4取模,用户表的partition key是userid,就是userId % 4。比如id为1的,在user1读写,id为6的,在user2读写。
image.png
partition key是怎么选择的呢?

  1. 根据用户城市选择,这样会造成某个库的数据比较多
  2. 根据注册时间,也会不均匀
  3. 要选随机的,这样hash的时候,每个库都比较均匀。

多个分片

上面的例子,只有一个字段是partition key,如果是多个,比如既可以按照id查询,又可以按照uname查询,怎么办?如果只有一个partition key,为id,那查询name的时候,只能全库搜索了,这样性能就很低了。
基因法(假设模16):

  1. username取后4位
  2. id生成60位
  3. 把username的后4位加到id后面

这样查找的时候,不管是对id查找,还是对username查找,都可以直接根据后四位进行查找。
image.png
上面的id,是根据username生成的,如果id是固定的,不依赖username生成的,要怎么办呢?
映射法:

  1. 建立username和id的映射表(这个必须是1对1 ,如果是1对多,依然要去多个库查找,这样还是很耗性能)
  2. 查询usename的时候,先去映射表查找对应关系,获取id
  3. 通过id取模的方式,去相应的库里查找

分库分表问题

  1. 分库分表后,sql聚合、join、子查询限制。
  2. 再次分表的成本高,已经分成4个表了,再分个8表?
  3. 恢复成本高,需要对多个已拆分的库、表恢复
  4. 运维成本高,需要多多个已拆分的库、表维护
  5. 数据一致性如何解决?

大军
847 声望183 粉丝

学而不思则罔,思而不学则殆


« 上一篇
架构演进之路
下一篇 »
原来这就是RMI