zoukankan      html  css  js  c++  java
  • ORM表之间高级设计

    ORM表之间高级设计

    一、表的继承

    # db_test1
    # 一、基表
    # Model类的内部配置Meta类要设置abstract=True,
    # 这样的Model类就是用来作为基表
    
    # 多表:Book,Publish,Author,AuthorDetail
    class BaseModel(models.Model):
        # 实现表公共字段的继承
        create_data = models.DateTimeField(auto_now_add=True)
        is_delete = models.BooleanField(default=False)
    
        class Meta:
            # 基表必须设置abstract,基表就是给普通Model类继承使用的
            # ,设置了abstract就不会完成数据库迁移完成建表,这张表不会被创建
            abstract = True
    
    class Book(BaseModel):  # 书
        name = models.CharField(max_length=49)
        price = models.DecimalField(max_digits=5, decimal_places=2)
    
    class Publish(BaseModel):  # 出版社
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=64)
    
    class Author(BaseModel):  # 作者 被关联表
        name = models.CharField(max_length=50)
        sex = models.IntegerField(choices=[(0, "男"), (1, "女")])
    
    class AuthorDetail(BaseModel):  # 作者详情 关联表
        mobile = models.CharField(max_length=11)
    
    # from django.contrib.auth.models import AbstractUser, User
    # class users(User)
    

    总结:

    1. 自定义基表,主要是用于解决多个表出现重复的字段,可以自定义基表(参考auth.models.User表)

    2. 首先需要自定义创建一个表,然后在写内部类 Meta

       class BaseModel(models.Model):
              create_data = models.DateTimeField(auto_now_add=True)
              is_delete = models.BooleanField(default=False)
      
              class Meta:
                  abstract = True
      
    3. 在Meta内部类中必须设置属性abstract = True,基表既可以别普通类继承使用

    4. 在基表中设置了abstract = True,在数据库迁移命令完成后,这张表不会被创建

    二、外键设计

    from django.db import models
    # db_test1
    # 一、基表
    # Model类的内部配置Meta类要设置abstract=True,
    # 这样的Model类就是用来作为基表
    
    # 多表:Book,Publish,Author,AuthorDetail
    class BaseModel(models.Model):
        # 实现表公共字段的继承
        create_data = models.DateTimeField(auto_now_add=True)
        is_delete = models.BooleanField(default=False)
    
        class Meta:
            # 基表必须设置abstract,基表就是给普通Model类继承使用的
            # ,设置了abstract就不会完成数据库迁移完成建表,这张表不会被创建
            abstract = True
    
    class Book(BaseModel):  # 书
        name = models.CharField(max_length=49)
        price = models.DecimalField(max_digits=5, decimal_places=2)
    
        # 出版社与书是一对多的关系,                设置反向查询字段    
        publish = models.ForeignKey(to="Publish", related_name="books")
    
        # 书与作者是多对多的关系                    
        #                                            设置反向查询字段
        author = models.ManyToManyField(to="Author", related_name="books")
    
    class Publish(BaseModel):  # 出版社
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=64)
    
    class Author(BaseModel):  # 作者 被关联表
        name = models.CharField(max_length=50)
        sex = models.IntegerField(choices=[(0, "男"), (1, "女")])
    
        # 出版社与作者一对多的关系                   设置反向查询字段     
        publish = models.ForeignKey(to="Publish", related_name="author")
    
    class AuthorDetail(BaseModel):  # 作者详情 关联表
        mobile = models.CharField(max_length=11)
    
        # 设置一对一外键: 有作者可以没有详情,删除作者,详情一定会被级联删除
        # 作者与个人信息是一对一的关系               设置反向查询字段      
        author = models.OneToOneField(to="Author", related_name="detail")
    
    """
    
    
    三、ORM外键设计
        1. 一对多: 外键攒在多的一方
        2. 多对多: 外键存放在常用的一方
        3. 一对一:外键存放在不常用的一方,
            原因,比如作者和做个人信息表,如果在作者中设置主键,设置级联关系,那么作者删除了个人信息还存在,还需要自己逻辑删除,
            所以通过将外键设置在不常用的字段中,如果作者删除了,个人信息也被删除了
        4. 外键字段为正向查询字段, 通过related_name设置为反向查询字段
    """
    
    

    总结:

    1. ORM外键设计
    2. 一对一的外键存放在不常用的一方:
      • 原因原因,比如作者和做个人信息表,如果在作者中设置主键,设置级联关系,那么作者删除了个人信息还存在,还需要自己逻辑删除,
      • 所以通过将外键设置在不常用的字段中,如果作者删除了,个人信息也被删除了
    3. 一对多的外键设置在多的一方
    4. 多对多的外键设置在常用的一方
    5. 设置外键字段可以通过正向查询字段,不能进行反向查询,可以通过 related_name,设置为反向查询字段,可以通过自己设置的字段进行反向查询

    三、表之间级联关系(断关联)

    from django.test import TestCase
    from django.db import models
    # db_test1
    # 一、基表
    # Model类的内部配置Meta类要设置abstract=True,这样的Model类就是用来作为基表
    # 多表:Book,Publish,Author,AuthorDetail
    class BaseModel(models.Model):
        # 实现表公共字段的继承
        create_data = models.DateTimeField(auto_now_add=True)
        is_delete = models.BooleanField(default=False)
    
        class Meta:
            # 基表必须设置abstract,基表就是给普通Model类继承使用的
            # ,设置了abstract就不会完成数据库迁移完成建表,这张表不会被创建
            abstract = True
    
    class Book(BaseModel):  # 书
        name = models.CharField(max_length=49)
        price = models.DecimalField(max_digits=5, decimal_places=2)
    
        # 出版社与书是一对多的关系,                设置反向查询字段     断外键之间的关系      设置级联,不进行级联删除(出版社删了,书不删) 一对多关系
        publish = models.ForeignKey(to="Publish", related_name="books",db_constraint=False, on_delete=models.DO_NOTHING)
    
        # 书与作者是多对多的关系                      断关联
    
        # 在多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联
        # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义创建第三张关系表
        author = models.ManyToManyField(to="Author", related_name="books", db_constraint=False)
    
    class Publish(BaseModel):  # 出版社
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=64)
    
    class Author(BaseModel):  # 作者 被关联表
        name = models.CharField(max_length=50)
        sex = models.IntegerField(choices=[(0, "男"), (1, "女")])
    
        # 出版社与作者一对多的关系                   设置反向查询字段     断外键之间的关联
        publish = models.ForeignKey(to="Publish", related_name="author", db_constraint=False)
    
    
    class AuthorDetail(BaseModel):  # 作者详情 关联表
        mobile = models.CharField(max_length=11)
    
        # 设置一对一外键: 有作者可以没有详情,删除作者,详情一定会被级联删除
        # 作者与个人信息是一对一的关系               设置反向查询字段      断外键之间的关联     级联删除(作者删除用户表删除)
        author = models.OneToOneField(to="Author", related_name="detail",db_constraint=False, on_delete=models.CASCADE)
    

    总结:

    1. 表之间断关联,原因在于,当项目越来越大,当要重构表是就会影响相关联的表,表之间可能会形成一个环
    2. 表之间虽然没有外键的关联,但是存在外键的逻辑关联(有充当外键的字段),这样也会导致一个问题,表中有可能会存在脏数据
    3. 断关联后表之间不会影响数据库查询效率,但是会极大提高数据的增删改效率
    4. 断关联一定要通过逻辑保证表之间的数据安全
    5. 断关联通过这只外键字段db_constraint=False,设置
    6. 外键之间的级联关系的设置(ORM级联只能删除)
      • 一对一级联删除:on_delete = models.CASCADE, eg: 作者没有了, 详情也没有
      • 一对多级联删除: on_delete=models.DO_NOTHING, eg: 出版社没了, 书还是那个出版社出版
      • 多对多级联删除:不能在外键中设置级联删除,只能在自定义创建第三张表中实现级联删除,
      • 部门没了, 员工没有部门(可以设置为空,空部门): null=True, on_delete=models.SET_NULL,
      • 部门没了,员工计入默认部门(默认值): defalult = 0, on_delete=models.SET_DEFAULT

    四、总结

    1. 自定义表

      1. 自定义基表,主要是用于解决多个表出现重复的字段,可以自定义基表(参考auth.models.User表)

      2. 首先需要自定义创建一个表,然后在写内部类 Meta

         class BaseModel(models.Model):
                create_data = models.DateTimeField(auto_now_add=True)
                is_delete = models.BooleanField(default=False)
        
                class Meta:
                    abstract = True
        
      3. 在Meta内部类中必须设置属性abstract = True,基表既可以别普通类继承使用

      4. 在基表中设置了abstract = True,在数据库迁移命令完成后,这张表不会被创建

    2. ORM外键设计

      1. ORM外键设计

      2. 一对一的外键存放在不常用的一方(根据级联关系):

        • 原因原因,比如作者和做个人信息表,如果在作者中设置主键,设置级联关系,那么作者删除了个人信息还存在,还需要自己逻辑删除,
        • 所以通过将外键设置在不常用的字段中,如果作者删除了,个人信息也被删除了
      3. 一对多的外键设置在多的一方

      4. 多对多的外键设置在常用的一方

      5. 设置外键字段可以通过正向查询字段,不能进行反向查询,可以通过 related_name="反向表名称",设置为反向查询字段,可以通过自己设置的字段进行反向查询

        # 正向查询
        print(models.Book.objects.all().filter(author=1))
        # 反向查询
        print(models.Author.objects.all().filter(book=1))
        """
        <QuerySet [<Book: Book object>]>
        <QuerySet [<Author: Author object>, <Author: Author object>]>
        """
        

      不能访问data ,save

      三个方法两个方法 minx

      单增,群查

      v4唯一键

    3. 表之间断关联:

      1. 表之间断关联,原因在于,当项目越来越大,当要重构表是就会影响相关联的表,表之间可能会形成一个环
      2. 表之间虽然没有外键的关联,但是存在外键的逻辑关联(有充当外键的字段),这样也会导致一个问题,表中有可能会存在脏数据
      3. 断关联后表之间不会影响数据库查询效率,但是会极大提高数据的增删改效率
      4. 断关联一定要通过逻辑保证表之间的数据安全
      5. 断关联通过这只外键字段db_constraint=False,设置
      6. 外键之间的级联关系的设置(ORM级联只能删除)
        • 一对一级联删除:on_delete = models.CASCADE, eg: 作者没有了, 详情也没有
        • 一对多级联删除: on_delete=models.DO_NOTHING, eg: 出版社没了, 书还是那个出版社出版
        • 多对多级联删除:不能在外键中设置级联删除,不能设置 on_delete,只能在自定义创建第三张表中实现级联删除,
        • 部门没了, 员工没有部门(可以设置为空,空部门): null=True, on_delete=models.SET_NULL,
        • 部门没了,员工计入默认部门(默认值): defalult = 0, on_delete=models.SET_DEFAULT
    4. 表设计路飞

      1、免费课、实战课、轻课业务线独立,所以设置三个数据库表,相同字段用BaseModel处理
      2、课程分类表、老师表只需要一个,三种课程公用
      3、章节表、课时表、评论表、问题表要与具体分类的课程配套(陪三套表)
      ***评论表:分三个表(因为是一对多的关系,只要拆了一方,跟随的都要拆)或者产生第三张表实现实现对应关系*****
      
      4、尽量不连表
      	主页推荐课程,可以就访问课程表,课程表增加 推荐字段
      	主页模块创建 课程推荐表,点击跳转的链接为 课程详情接口
      	推荐关系表 => 接口缓存
      	
         一下不是实时变化的数字结果(一般都是计算而来),可以直接用一个字段存储
         	总课时,热度(学习学生数)
         	
      5、免费课一条业务线五张表:分类、课程、老师、章节、课时
      
    5. 
      

    img

    img

    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    Spring spEL
    Spring 使用外部部署文件
    Spring 自动装配
    spring 属性配置细节
    hdu 1054 Strategic Game
    fzu 2037 Maximum Value Problem
    将博客搬至CSDN
    HDU 4714 Tree2Cycle
    HDU 1009 The Shortest Path in Nya Graph
    POJ 1942 Paths on a Grid 组合数的优化
  • 原文地址:https://www.cnblogs.com/randysun/p/12189361.html
Copyright © 2011-2022 走看看