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、免费课一条业务线五张表:分类、课程、老师、章节、课时

ORM表之间高级设计的更多相关文章

  1. Django中多对多关系的orm表设计

    作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍  1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...

  2. PowerDesigner如何设计表之间的关联

    PowerDesigner如何设计表之间的关联   步骤/方法 在工具箱中找到参照关系工具:   由地区表到省份表之间拉参照关系,箭头指向父表,然后双击参照关系线,打开参照关系的属性:   在这里检查 ...

  3. ORM表单操作

    准备工作: 1.在orm操作表单之前需要先修改下django中连接的数据库,默认连接的是SQLit3,这里我们修改成mysql 2.mysql使用的版本是5.6,已经安装好了,直接连接就可以使用 创建 ...

  4. 【转】Oracle - 数据库的实例、表空间、用户、表之间关系

    [转]Oracle - 数据库的实例.表空间.用户.表之间关系 完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物理文件的集合(数据文件,控制文件,联机 ...

  5. Mybatis之基于XML的表之间映射

    数据库表之间的关系有3种,一对一.一对多.多对多.既然是ORM,这肯定是必须有的.在学习EF的时候也有涉及,今天就是参考着EF的来学习下MyBatis的表关系映射. 一.准备工作 1.准备Model和 ...

  6. MySQL表与表之间的关系

    表与表之间的关系 表1 foreign key 表2 则表1的多条记录对应表2的一条记录,即多对一 利用foreign key的原理我们可以制作两张表的多对多,一对一关系 多对多: 表1的多条记录可以 ...

  7. Mysql表的约束设计和关联关系设计

    https://blog.csdn.net/u012750578/article/details/15026677 Mysql表的约束设计和关联关系设计 ======================表 ...

  8. Django 的ORM 表间操作

    Django之ORM表间操作   之前完成了简单的数据库数据增加操作.这次学习更多的表间操作. 单表操作 增加 方式一 b = Book(title="Python基础", pub ...

  9. Django --- ORM表查询

    目录 使用数据库之前的配置工作 单表操作常用的方法 一对多字段的增删改查 多对多字段数据的增删改查 跨表查询 聚合函数 分组查询 F与Q查询 使用数据库之前的配置工作 settings.py中的配置 ...

随机推荐

  1. 如何在Ubuntu 18.04上安装和卸载TeamViewer

    卸载命令:sudo apt --purge remove teamviewer 安装:https://www.linuxidc.com/Linux/2018-05/152282.htm 如何在Ubun ...

  2. PHP实现简单的双色球机选号码

    <?php header('Content-Type: text/html; charset=utf-8'); //PHP实现双色球机选号码 $red = range(1, 33);//初次设定 ...

  3. iOS基础——通过案例学知识之xib、plist、mvc

    透过案例学习xib的使用.plist的使用.mvc在iOS的使用,今天要做的案例效果图 1.xib和nib xib文件可以被XCode编译成nib文件,xib文件本质上是一个xml文件,而nib文件就 ...

  4. java Kafka 简单应用实例

    kafka官方中文文档  http://kafka.apachecn.org/ java Kafka 简单应用实例  下面是Linux下的单机模式:https://blog.csdn.net/fct2 ...

  5. Spring装配Bean的一些高级技巧

    一.使用@Profile注解来实现在不同环境下创建不同的Bean 实现方式:将不同的Bean定义整理到对应环境的Profile中,当应用部署到不同的环境时(开发环境或者是QA环境或者是生产环境),激活 ...

  6. Vuex 是什么

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具  ...

  7. springboot--入门(了解springboot)

    个人认为,springboot和maven差不多.maven方便我们管理jar包,而springboot帮助我们简化spring的配置. 未完,待续.......

  8. xv6的启动过程

    bootloader 1. bootasm.S : start32 2. bootmain.c : bootmain kernel 3. main.c : main 4. proc.c : useri ...

  9. react 16 性能提升 总结

    1. 减少子组件渲染 当 父组件 state 内的某个值(eg:value) 不变时 子组件菜 render shouldComponentUpdate(nextProps, nextState){ ...

  10. CentOS 7.3 安装redis 4.0.2服务

    CentOS 7.3 安装redis 4.0.2服务 1.下载解压 下载地址:/home/xiaoming/ wget http://download.redis.io/releases/redis- ...