MySQL杂谈

作者: VienFu | 来源:发表于2018-10-24 11:57 被阅读1次

    应用场景

    这个可能要依据所采用的存储引擎(myisam,innerdb)来看。

    读写分离

    在Django框架下,数据库的读写分离的设计一般有两种方式:

    1. 手动实现
      获取queryset的时候调用using
    transaction = PrepayTransactions.objects.using('read').filter(channel='wechat', deactivated_at__is_null=True).first()
    transaction.channel = 'alipy'
    transaction.save(using='read')
    
    1. 自动处理
      重写数据库路由,然后在settings文件里添加上该路由的具体path
    class MasterSlaveDBRouter(object):
        """数据库主从读写分离路由"""
    
        def db_for_read(self, model, **hints):
            """读数据库"""
            return "slave"
    
        def db_for_write(self, model, **hints):
            """写数据库"""
            return "default"
    
        def allow_relation(self, obj1, obj2, **hints):
            """是否运行关联操作"""
            return True
    

    然后配置读写分离(settings.py)
    DATABASE_ROUTERS = [‘path_to_router.MasterSlaveDBRouter’]

    主从复制

    这个一般是从MySQL的高可用性来说的,都是基于MySQL Replication来实现的,模式主要有四种:

    1. 一主一从
    2. 一主多从
    3. 主主互备
    4. 双主多从

    其中读业务数据量特别大的时候考虑多从架构,另外为了实现一台master出现故障时自动切换,可以采用keepalived(主主互备架构,只会监控到主节点的状态)、MMM(双主多从比较好,同时监控master和slave节点的状态)等工具来实现。

    乐观锁和悲观锁

    1. 乐观锁
      乐观的认为在自己取数据的时候不会有其他线程来更改数据,因此取数据的时候不加锁,但对数据进行update等写的操作时要加锁(这个一般通过版本号设计,CAS设计来实现)
    2. 悲观锁
      不管是读数据还是更新数据都加上锁,这个一般在数据库级别来实现,比如mysql自己的锁机制(行锁,表锁,读锁,写锁)

    选择问题:这个要依据实际的应用场景来决定,一般来讲,读频繁的数据库加乐观锁,而写频繁的数据库加悲观锁。

    事务及事务的隔离级别

    事务的四大特性

    ACID:
    原子性,一致性,隔离性,持久性

    事物的隔离级别

    1. 读未提交 — 脏读
    2. 读提交 — 不可重复读
    3. 可重复读 — 幻读
    4. 串行化 — 事务隔离的最高级别
      可序列化的数据库锁情况:
      事务在读取数据时,必须先对其加 表级共享锁 ,直到事务结束才释放 — 其他事务通过添加共享锁也可以读取数据
      事务在更新数据时,必须先对其加 表级排他锁 ,直到事务结束才释放 — 其他事务不能对其进行读写操作

    另外,补充几个概念:
    脏读:事务A修改了某个数据但未提交,然后事务B读了这条数据(更改后),后来事务A回滚了,这就形成事务B的脏读;
    不可重复读:事务A先读了某个数据,而事务B对这个数据进行了更改且提交了,这时候事务A再读这个数据时发现跟之前读的数据不一样了,这就是不可重复读;
    幻读:其实跟不可重复读有点类似,只不过幻读侧重新增数据,而不可重复读则侧重更新或者删除;

    相关文章

      网友评论

        本文标题:MySQL杂谈

        本文链接:https://www.haomeiwen.com/subject/afbttqtx.html