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. SpringMVC:提交日期类型报400错误解决方法

    方法1:可以使用@ControllerAdvice增强Controller @ControllerAdvice public class BaseControllerAdvice { // 初始化绑定 ...

  2. MySQLWorkbench注释

    不改变快捷键配置文件基础上 1. 通过菜单操作 Edit -> Format -> Un/comment 2. 键盘 (Windows 10, 其他操作系统未试过) Ctrl + /  ( ...

  3. HDU - 4430 Yukari's Birthday(二分+枚举)

    题意:已知有n个蜡烛,过生日在蛋糕上摆蜡烛,将蜡烛围成同心圆,每圈个数为ki,蛋糕中心最多可摆一个蜡烛,求圈数r和看,条件为r*k尽可能小的情况下,r尽可能小. 分析:n最大为1012,k最少为2,假 ...

  4. POJ 1126:Simply Syntax

    Simply Syntax Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5264   Accepted: 2337 Des ...

  5. rdlc报表带参数打印

    1.新建rdlc文件报表 2.选中rdlc文件=>视图=>报表资料 添加几个参数,如图 设计报表页面 int WaitNum = this.queueDTOs.Where(m=>m. ...

  6. 全面掌握Nginx配置+快速搭建高可用架构 一 Nginx的访问控制

    语法 示例 allow 127.0.0.1; deny all; 缺点:局限性 如果通过代理就可以绕过访问限制,限制不准确 解决 1. http_x_forwarded_for 2. 结合geo模块作 ...

  7. Angular js 复制粘贴

    关于copy到剪切板的实现需要引用Clipboard.min.js https://pan.baidu.com/s/1eStTJlo 页面如下所示,需要实现 点击copy字样 将id为content的 ...

  8. Android自定义View——自定义ViewPager

      第一部分:自定义ViewGroup的使用,手势识别器和Scroller滑动 第二部分:处理滑动监听,处理滑动冲突,增加ViewPager的指示器   常见的滑动冲突:外部滑动方向和内部滑动方向不一 ...

  9. 启动mysql遇到问题Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

    在mysql的启动过程中有时会遇到下述错误 Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 请问mys ...

  10. go简单文件服务器

    go文件服务器 go语言实现的简单文件服务器 github