zoukankan      html  css  js  c++  java
  • Django----配置数据库读写分离

    Django配置数据库读写分离

    https://blog.csdn.net/Ayhan_huang/article/details/78784486

    https://blog.csdn.net/ayhan_huang/article/details/77575186#t4

    对网站的数据库作读写分离(Read/Write Splitting)可以提高性能,在Django中对此提供了支持,下面我们来简单看一下。注意,还需要运维人员作数据库的读写分离和数据同步。

    配置数据库

    我们知道在Django项目的settings中,可以配置数据库,除了默认的数据库,我在下面又加了一个db2。因为是演示,我这里用的是默认的SQLite,如果希望用MySQL,看这里 。

    DATABASES = {
    
    'default': {
    
    'ENGINE': 'django.db.backends.sqlite3',
    
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    
    },
    
    'db2': {
    
    'ENGINE': 'django.db.backends.sqlite3',
    
    'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    
    },
    
    }

    创建models并执行数据库迁移

    这里我简单创建一张产品表

    from django.db import models
    
    class Products(models.Model):
    
    """产品表"""
    
    prod_name = models.CharField(max_length=30)
    
    prod_price = models.DecimalField(max_digits=6, decimal_places=2)

    创建完成后,执行数据库迁移操作:

    python manage.py makemigrations # 在migrations文件夹下生成记录,迁移前检查
    
    python manage.py migrate # 创建表

    在migrations文件夹下生成记录,并在迁移前检查是否有问题,默认值检查defualt数据库,但是可以在后面的数据库路由类(Router)中通过allow_migrate()方法来指定是否检查其它的数据库。

    其实第二步迁移默认有参数python manage.py migrate --database default ,在默认数据库上创建表。因此完成以上迁移后,执行python manage.py --database db2,再迁移一次,就可以在db2上创建相同的表。这样在项目根目录下,就有了两个表结构一样的数据库,分别是db.sqlite3和db2.sqlite3。

    读写分离

    手动读写分离

    在使用数据库时,通过.using(db_name)来手动指定要使用的数据库

    from django.shortcuts import HttpResponse
    
    from . import models
    
    
    def write(request):
    
      models.Products.objects.using('default').create(prod_name='熊猫公仔', prod_price=12.99)
    
      return HttpResponse('写入成功')
    
     
    def read(request):
    
      obj = models.Products.objects.filter(id=1).using('db2').first()
    
      return HttpResponse(obj.prod_name)

    自动读写分离

    通过配置数据库路由,来自动实现,这样就不需要每次读写都手动指定数据库了。数据库路由中提供了四个方法。这里这里主要用其中的两个:def db_for_read()决定读操作的数据库,def db_for_write()决定写操作的数据库。

    定义Router类

    新建myrouter.py脚本,定义Router类:

    class Router:
    
        def db_for_read(self, model, **hints):
    
            return 'db2'
    
     
    
        def db_for_write(self, model, **hints):
        
            return 'default'

     

    配置Router

    settings.py中指定DATABASE_ROUTERS

    DATABASE_ROUTERS = ['myrouter.Router',]

    可以指定多个数据库路由,比如对于读操作,Django将会循环所有路由中的db_for_read()方法,直到其中一个有返回值,然后使用这个数据库进行当前操作。

    一主多从方案

    网站的读的性能通常更重要,因此,可以多配置几个数据库,并在读取时,随机选取,比如:

    class Router:
    
      def db_for_read(self, model, **hints):
    
      """
    
      读取时随机选择一个数据库
    
      """
    
        import random
    
        return random.choice(['db2', 'db3', 'db4'])
    
     
    
      def db_for_write(self, model, **hints):
    
      """
    
      写入时选择主库
    
      """
    
        return 'default'
    
    

    分库分表

    在大型web项目中,常常会创建多个app来处理不同的业务,如果希望实现app之间的数据库分离,比如app01走数据库db1,app02走class Rout

      def db_for_read(self, model, **hints):
        if model._meta.app_label == 'app01':
          return 'db1'
        if model._meta.app_label == 'app02':       return 'db2'   def db_for_write(self, model, **hints):     if model._meta.app_label == 'app01':       return 'db1'     if model._meta.app_label == 'app02':
          return 'db2'
  • 相关阅读:
    基于Angular和Spring WebFlux做个小Demo
    一个数据源demo
    我需要一个什么样子的动态数据源模块
    JavaScript对象类型之创建对象
    JavaScript对象类型之简单介绍
    C# 调用者信息获取
    我的收藏之数据库优化
    Linq标准查询操作符
    Nunit测试工具使用实例
    搜索引擎中的搜索技巧
  • 原文地址:https://www.cnblogs.com/hanbowen/p/9899569.html
Copyright © 2011-2022 走看看