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. 执行 composer update 命令的时候报 Your requirements could not be resolved to an installable set of packages. 错误

    Your requirements could not be resolved to an installable set of packages. 以上原因:不匹配composer.json要求的版 ...

  2. CGridCtrl 添加button (CGridCellButton类)

    #ifndef __GRID_CELL_BUTTON__ #define __GRID_CELL_BUTTON__ #include "../GridCtrl_src/GridCell.h& ...

  3. ubuntu安装opencv3.2

    把master分支git下来: git clone git@github.com:opencv/opencv.git 查看可用的版本: git tag 选择自己想要的版本号: git reset -- ...

  4. 花了一周整理的,这是价值10W的32个Python项目!

    今天为大家整理了32个Python爬虫项目.整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩得愉快~QQSpider ! QQ空间爬虫,包括日志.说 ...

  5. css代码实现列表等宽

    实现上面的手机页面,我们会遇到一个自适应的问题,但是手机页面的屏幕大小不一致,自适应的问题不是百分比可以好好解决的,我采用下面的布局:display:flex; <!DOCTYPE html&g ...

  6. StringBuffer类、StringBuilder类详解

    StringBuffer是一个字符串缓冲区,是一个容器,而且长度可变,可以直接操作多个数据类型, 最终会通过toString()方法变成字符串. 容器的功能有: 1.存储 public StringB ...

  7. C#高级编程(第9版) 第11章 LINQ 笔记

    概述语言集成查询(Language Integrated Query, LINQ)在C#编程语言中集成了查询语法,可以用相同的语法访问不同的数据源.LINQ提供了不同数据源的抽象层,所以可以使用相同的 ...

  8. Nginx之epoll和select poll

    epoll和 select poll 都是做I/O多路复用的. 区别在于: epoll较灵活,如果有一百万个链接状态同时保持,但是在某个时刻,只有几百个链接是活跃的.epoll的处理是通过epoll_ ...

  9. POJ 2006:Litmus Test 化学公式

    Litmus Test Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1709   Accepted: 897 Descri ...

  10. C++ 模板练习1

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