首页 > 解决方案 > 我应该使用 JSONField 而不是 ForeignKey 来存储数据吗?

问题描述

我正面临两难境地,我正在创建一个新产品,我不想搞乱我在数据库中组织信息的方式。

我的模型有这两种选择,第一种是使用外键将它们链接在一起。

Class Page(models.Model):
    data = JsonField()

Class Image(models.Model):
    page = models.ForeignKey(Page)
    data = JsonField()

Class Video(models.Model):
    page = models.ForeignKey(Page)
    data = JsonField()

etc...

第二个是将所有内容保存在Page的 JSONField 中:

Class Page(models.Model):
    data = JsonField() # videos and pictures, etc... are stored here

一个比另一个好,为什么?这对我将来组织数据库的方式有很大帮助。

我想也许第二个选项可能会更慢,因为每次发生变化时,所有的 json 都会被覆盖,但它会产生巨大的差异还是我说的是假的?

标签: djangodjango-models

解决方案


AJSONField混淆了底层数据,使得编写可读代码和充分使用 Django 的内置 ORM、验证和其他细节(ModelForm例如 s)变得困难。虽然它可以灵活地将您想要的任何内容保存到数据库中(例如,在添加新字段时无需迁移数据库),但它消除了显式字段的清晰度并使得以后很容易引入错误。

例如,如果您开始在数据中保存一个新键,然后尝试在代码中访问该键,那么旧对象将没有它,并且您可能会发现您的应用程序崩溃,具体取决于您正在访问的对象。如果您使用单独的字段,则不会发生这种情况。

我总是尽量避免它,除非没有其他办法。

通常我在两种情况下使用 JSONField:

  • 保存来自 3rd 方 API 的响应(例如作为审计跟踪)
  • 保存对归档对象的引用(例如,当我的数据库中的实时产品发生变化但我仍然有引用该产品的订单时)。

如果您使用 PostgreSQL 作为关系数据库,它经过优化以在 JOIN 上具有超级性能,因此使用ForeignKeys 实际上是一件好事。在您的代码中使用select_relatedandprefetch_related来优化查询的数量,但查询本身即使针对数百万个条目也可以很好地扩展。


推荐阅读