我应该以任何方式避免 Django 中的多表(具体)继承吗? [英] Should I avoid multi-table (concrete) inheritance in Django by any means?

查看:16
本文介绍了我应该以任何方式避免 Django 中的多表(具体)继承吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多有经验的开发人员建议不要使用 Django multi-表继承,因为它的性能很差:

  1. Django 陷阱:具体继承 Jacob Kaplan-Moss,Django 的核心贡献者.

    <块引用>

    几乎在所有情况下,抽象继承都是更好的方法长期.我已经看到不少网站在负载下被压垮了由具体继承引入,所以我强烈建议Django 用户使用大量的具体继承来处理任何使用怀疑的剂量.

  2. 两勺 Django 来自丹尼尔·格林菲尔德 (@pydanny)

    <块引用>

    多表继承,有时也称为具体继承",是作者和许多其他开发人员认为这是一件坏事.我们强烈建议不要使用它.

    不惜一切代价,每个人都应该避免多表继承因为它增加了混乱和大量开销.而不是多表继承,使用显式 OneToOneFields 和模型之间的外键,以便您可以控制何时加入穿过.

但是没有多表继承,我也不容易

  1. 在另一个模型中引用基础模型(必须使用 GenericForeignKey 或反向依赖);

  2. 获取基础模型的所有实例.

    (随意添加更多)

那么Django中的这种继承有什么问题呢?为什么显式 OneToOneFields 更好?

JOIN 对性能的影响有多大?是否有任何基准可以显示性能差异?

select_related() 不是允许我们控制何时调用 JOIN 吗?

<小时>

我已将具体示例移至单独问题,因为这个问题变得太广泛,并添加了使用多表继承的原因列表.

解决方案

首先,继承并不能自然地转化为关系数据库架构(好吧,我知道,Oracle 类型对象和其他一些RDBMS 支持继承,但 django 没有利用这个功能)

此时,请注意 django 为子类生成新表并编写大量左连接以从该中检索数据'子表'.而左连接不是你的朋友.在高性能场景中,例如游戏后端或其他东西,您应该避免它并使用一些工件(如空值、OneToOne 或外键)手动"解决继承问题.在OneToOne场景中,可以直接调用相关表,也可以仅在需要时调用.

...但是...

在我看来 (TGW)" 当您的话语世界.我这样做了,由于此功能,我为客户节省了大量开发时间.此外,代码变得干净优雅,这意味着易于维护(请注意,此类项目不会有数百个或每秒请求数)

逐个问题

问:Django 中的这种继承有什么问题?
A:很多表,很多左连接.

问:为什么显式 OneToOneFields 更好?
A:可以直接访问相关模型,无需左连接.

问:是否有任何说明性示例(基准)?
A:没有可比性.

问:select_related() 是否允许我们控制何时调用 JOIN?
A: django 连接需要的表.

问:当我需要引用另一个模型中的基类时,多表继承的替代方法是什么?
答:无效化.一对一关系和大量代码行.这取决于应用需求.

问:在这种情况下,GenericForeignKeys 是否更好?
答:不适合我.

问:如果我需要 OneToOneField 作为基础模型怎么办?
答:写吧.这没有问题.例如,您可以扩展 User 模型,也可以为某些用户创建 OneToOne 到 User 基本模型.

结论

您应该了解在没有模型继承的情况下编写和维护代码的成本,以及支持模型继承应用程序并采取相应行动的硬件成本.

开个玩笑:你可以用汇编代码编写它,它会运行得更快.

引用 Trey Hunner::><块引用>

您的时间通常比 CPU 的时间贵得多.

Many experienced developers recommend against using Django multi-table inheritance because of its poor performance:

  1. Django gotcha: concrete inheritance by Jacob Kaplan-Moss, a core contributor of Django.

    In nearly every case, abstract inheritance is a better approach for the long term. I’ve seen more than few sites crushed under the load introduced by concrete inheritance, so I’d strongly suggest that Django users approach any use of concrete inheritance with a large dose of skepticism.

  2. Two Scoops of Django by Daniel Greenfield (@pydanny)

    Multi-table inheritance, sometimes called "concrete inheritance," is considered by the authors and many other developers to be a bad thing. We strongly recommend against using it.

    At all costs, everyone should avoid multi-table inheritance since it adds both confusion and substantial overhead. Instead of multi-table inheritance, use explicit OneToOneFields and ForeignKeys between models so you can control when joins are traversed.

But without multi-table inheritance, I can't easily

  1. Reference base model in another model (have to use GenericForeignKey or reverse dependency);

  2. Get all instances of base model.

    (feel free to add more)

So what is wrong with this kind of inheritance in Django? Why are explicit OneToOneFields better?

How much does performance suffer from JOINs? Are there any benchmarks that show the difference in performance?

Does not select_related() allow us to control when JOINs are invoked?


I have moved concrete examples to a separate question since this one is becoming too broad, and added a list of reasons for using multi-table inheritance instead.

解决方案

First of all, inheritance has not a natural translation to relational database architecture (ok, I know, Oracle Type Objects and some other RDBMS support inheritance but django don't take advantage of this functionality)

At this point, notice than django generates new tables to subclasses and write lots of left joins to retrieve data from this 'sub-tables'. And left joins are not your friends. In a high performance scenario, like a game backend or something else, you should avoid it and resolve inheritance 'by hand' with some artifacts like nulls, OneToOne or foreign keys. In OneToOne scenario, you can call the related table directly or only if you need it.

... BUT ...

"In my opinion (TGW)" you should to include model inheritance in your enterprise projects when it catches to your universe of discourse. I do this, and I save a lot of development hours to my customers thanks to this feature. Also, code becomes clean and elegant and that means easy maintenance (notice that this kind of projects don't have hundreds or requests by second)

Question by question

Q: What is wrong with this kind of inheritance in Django?
A: Lot of tables, a lot of left joins.

Q: Why are explicit OneToOneFields better?
A: You can access directly to related model without left joins.

Q: Are there any illustrative examples (benchmarks)?
A: No comparable.

Q: Does not select_related() allow us to control when JOINs are invoked?
A: django joins needed tables.

Q: What are the alternatives to multi-table inheritance when I need to reference a base class in another model?
A: Nullification. OneToOne relations and lots of code lines. It depends on application needs.

Q: Are GenericForeignKeys better in this case?
A: Not for me.

Q: What if I need OneToOneField to base model?
A: Write it. There is no problem with this. For example, you can extend User model, and also you can have a OneToOne to User base model for some users.

Conclusion

You should to know the cost of write and maintenance code without model inheritance also the cost of hardware to support model inheritance applications and act accordingly.

Just a joke: you can write it on assembly code, and it will run faster.

Quoting Trey Hunner:

Your time is usually much more expensive than your CPU's time.

这篇关于我应该以任何方式避免 Django 中的多表(具体)继承吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆