• 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

    ![112121
    123123123

  • 相关阅读:
    oracle怎样查询注释
    kettle安装,启动spoon之后一闪就没了问题
    查看oracle当前的连接数
    在DevExpress程序中使用GridView直接录入数据的时候,增加列表选择的功能
    配置tomcat部署路径(Server Location是灰色怎么修改)
    怎样查询oracle的连接数
    64位系统安装ODBC驱动的方法
    前端日志实践
    webpack5之模块联邦
    关于前端技术、经验、团队、流程的总结
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11922527.html
Copyright © 2020-2023  润新知