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. CVE-2010-0249(极光)分析报告

    2019/9/10          报告doc在文件里面 1.    发现可疑流量 A.分析流量,导出字节流 B.得到网页代码,发现需要执行的代码需要解密(加密的字符串部分太长了,就省略了): C. ...

  2. 每天一点点之javascript(ES6) - Map对象

    1.语法 键/值对的集合. mapObj = new Map() 注:集合中的键和值可以是任何类型.如果使用现有密钥向集合添加值,则新值会替换旧值. 2.属性下表列出了 Map 对象的属性和描述. 构 ...

  3. HDU 5430:Reflect 欧拉函数

    Reflect  Accepts: 72  Submissions: 302  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 65536/ ...

  4. JAVAEE 和项目开发(第四课:HTTP的响应格式和响应状态码)

    HTTP 协议之响应 响应格式的结构: 响应行(状态行):HTTP 版本.状态码.状态消息 响应头:消息报头,客户端使用的附加信息 空行:响应头和响应实体之间的,必须的. 响应实体:正文,服务器返回给 ...

  5. HTML条件注释判断<!--[if IE] ![endif]-->

    很多网页中会见到这样的代码: <!--[if IE 7]> <![endif]--> /*或者*/ <!--[if lt IE 9]> <![endif]-- ...

  6. HZNU-ACM寒假集训Day3小结 搜索

    简单搜索 1.DFS UVA 548 树 1.可以用数组方式实现二叉树,在申请结点时仍用“动态化静态”的思想,写newnode函数 2.给定二叉树的中序遍历和后序遍历,可以构造出这棵二叉树,方法是根据 ...

  7. 201809-2 买菜 Java

    思路: 顺序读入,例如:小H装车的时间段为[1,3],小W装车的时间段为[2,4],重叠部分为[2,3],记在数组times[2]中.最后输出时判断数组times中值大于1的(其实就是2),即为重叠部 ...

  8. C++ 一般模板友元关系

    //一般模板友元关系 #include "stdafx.h" #include <iostream> using namespace std; template< ...

  9. Idea的类中使用实体类(有@Data注解)的Get/Set方法报错

    今天从svn上面下了一个maven项目,导入到Idea中之后,发现有的类会使用实体类的Set/Get方法(全报错),导致该问题的原因就是因为实体类中没有这个方法,代码类似如下: @Data publi ...

  10. 9.1hadoop 内置计数器、自定义枚举计数器、Streaming计数器

    1.1  计数器 计数器的作用是用来统计数量的,用于记录特定事件的次数,分为内置计数器.自定义java枚举计数器.自定义Stream计数器三大类.用于质量分析,或应用级统计.分析计数器的值比分析一堆日 ...