表结构设计优化

表结构设计优化

增加普通字段,减少跨表查询带来的性能消耗。

class Article(models.Model):
    title = models.CharField(max_length=64, verbose_name='标题')
    desc = models.CharField(max_length=256, verbose_name='摘要')
    content = models.TextField(verbose_name='文章内容')
    publish_time = models.DateTimeField(auto_now_add=True)
    
    # 数据库优化三个字段
    up_counts = models.BigIntegerField(verbose_name='点赞数', default=0)
    down_counts = models.BigIntegerField(verbose_name='点踩数', default=0)
    comment_counts = models.BigIntegerField(verbose_name='评论数', default=0)
	
 
# 优化三个字段:up_counts、down_counts、comment_counts 
	这三个本可以直接跨表查询获取数据,但是为了避免多次跨表查询导致的访问速度慢,
    于是采用额外增加三个普通字段,这样就避免了跨表查询的问题;
    但是缺点是在使用时需要注意,修改数据需要在代码上保持表之间的同步更新,

choices参数的使用,建立外键关联一对多,自动更新字段,避免直接修改代码

class Course(models.Model):
    
    type_choices = (
        (0, 'Python'), 
        (1, 'Linux'),
    )
    
     name = models.CharField(max_length=64)
     title = models.CharField(max_length=64)
     type = models.IntegerField(choices=type_choices, default=0)
   

# 此时这个type字段的选项写死了,如果后期需要增加新的课程类型,则需要修改此处的代码,才可以实现新需求
# 其实,可以新建另一张表,课程类型表,采用外键关联的方式,则实现type由数据库驱动时时更新,扩展需求时也不需要修改代码
# 增加新需求时,直接操作数据库,不需要修改代码。

# 优化后的代码
class CourseCategory(BaseModel):
    name = models.CharField(max_length=64, unique=True, verbose_name="分类名称")
    
    
class Course(BaseModel):
    name = models.CharField(max_length=128, verbose_name="课程名称")
   
	# 外键关联
    course_category = models.ForeignKey(to="CourseCategory", on_delete=models.SET_NULL, 
                                        db_constraint=False, null=True, blank=True, 
                                        verbose_name="课程分类"
                                       )

django的ORM跨表查询的两个外键参数related_namerelated_query_name

  • 基于对象的跨表查询,使用related_name之后,再跨表就不用使用表名_set的方式,而是直接使用related_name指定的字符串
  • related_query_name,反向查询操作时,使用的连接前缀,用于替换表名
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    
    publish = models.ForeignKey(to='Publish', related_name='books') 	    # 一对多,外键关联
    authors = models.ManyToManyField(to='Author', related_query_name='u')   # 多对多,

    
    
# 反向查询,related_name
pub_obj = models.Publish.objects.filter(name='东方出版社').first()
res = pub_obj.book_set.all()		        # 不用related_name时的写法 book_set
res = pub_obj.books.all()			# 使用related_name时的写法 books


# 反向查询,related_query_name
author_obj = models.Author.objects.filter(name='xliu').first()
res = author_obj.u_set.all()
posted @ 2020-08-01 14:58  小子,你摊上事了  阅读(79)  评论(0编辑  收藏  举报