• 架构之美—数据库架构


    本文来自朋友圈

    数据库架构一般从简单到复杂的过程

    1、一主一从
    由一台主库和一台从库组成,从库只用作备份和容灾,当主库出现故障时,从库就手动变成主库
    随着压力的增加,加上了memcached

    2、一主多从
    通过添加多个从库来分流查询压力

    3、随着数据量的增加,读写压力都迅速增加,

    进行数据库拆分,将数据存放到不同的数据库服务器中

    数据库拆分
    一般可以按两个纬度来拆分数据:
    (1)垂直拆分
    按功能模块拆分,多个数据库之间的表结构不同
    (2)水平拆分
    将同一个表的数据进行分块保存到不同的数据库中,数据库中的表结构相同

    拆分规则
    常见的拆分方式是对表中某列值的范围或者hash值拆分,比如ID在0-10000之间的用户对应到数据库A,ID在10000-20000这个范围的对应到数据库B
    这种方法实现起来比较方便高效,但是不能满足后续的伸缩性要求,如果需要增加数据库节点,必需调整算法或移动很大的数据集,比较难做到在不停止服务的前提下进行扩充数据库节点

    采用的拆分方法有:映射表
    这种方法是指建立一个索引表,保存每个用户ID和数据库ID的对应关系,每次读写用户数据时先从这个表获取对应数据库,新用户注册后,在所有可用的数据库中随机挑选一个为其建立索引
    把索引表进行缓存,提高检索性能

    数据迁移
    如果需要平衡各个节点的压力,需要进行数据的迁移
    例如要迁移用户A的数据
    (1)将A状态置为迁移数据中,这个状态的用户不能进行写操作,并在页面上进行提示
    (2)然后将用户A的数据全部复制到新增加的节点上
    (3)更新映射表
    (4)将用户A的状态置为正常
    (5)将原数据库上的数据删除

    数据访问过程

    拆分带来的问题

    (1)跨库关联查询

    如果需要查询的数据分布于不同的数据库,不便于通过JOIN的方式查询获得

    比如要获得好友的最新照片,不能保证所有好友的数据都在同一个数据库里,需要通过多次查询,再进行聚合

    有些需求可以通过保存多份数据来解决,例如用户A、用户B的数据库分别是DB1、DB2,当A评论了B作品时

    先在B所在DB2中photo_comments表插入记录,记录B的哪个作品被谁评论了什么内容

    然后在A所在DB1中user_comments表插入记录,记录A给哪个作者的哪个作品发表过评论

    这样可以通过photo_comments得到B的某张照片的所有评论,也可以通过user_comments获得A发布过的所有评论

    (2)不能保证数据的一致/完整性

    跨库的数据没有外键约束,也没有事务保证,比如上面评论照片的例子,很可能出现成功插入photo_comments表,但是插入user_comments表时却出错了

    可以在两个库上都开启事务,然后先插入photo_comments,再插入user_comments,然后提交两个事务,但不能完全保证这个操作的原子性

    (3)自增ID

    增加了一个专门用来生成ID的数据库,表结构很简单,只有一个自增字段id

    例如要插入评论时,先在ID库的photo_comments表里插入一条空的记录,以获得一个唯一的评论ID

    定期清理ID库的数据,以保证获取新ID的效率 

  • 相关阅读:
    牛客网 CSL的英语考试
    SDNU 1016.矩形合并
    SDNU 1412.Huffuman树(优先队列)
    HDU
    HDU
    HDU
    SDNU 1504.B.Fibonacci
    Find them, Catch them(种类并查集)
    golang中的net/rpc包
    gRPC
  • 原文地址:https://www.cnblogs.com/meslog/p/5042135.html
Copyright © 2020-2023  润新知