代码之家  ›  专栏  ›  技术社区  ›  Horai Nuri

我应该使用foreignkey上的jsonfield来存储数据吗?

  •  2
  • Horai Nuri  · 技术社区  · 6 年前

    我面临着一个两难的境地,我正在创建一个新产品,我不想把我在数据库中整理信息的方式搞砸。

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

    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都会被覆盖,但是这会有很大的区别吗,或者我说的是假的?

    1 回复  |  直到 6 年前
        1
  •  1
  •   dirkgroten    6 年前

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

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

    除非没有别的办法,否则我总是尽量避免。

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

    • 保存来自第三方API的响应(例如,作为审计跟踪)
    • 保存对存档对象的引用(例如,当我的数据库中的活动产品更改,但我仍有引用该产品的订单时)。

    如果您使用PostgreSQL作为关系数据库,那么它被优化为对连接具有超性能,因此使用 ForeignKey S实际上是一件好事。使用 select_related prefetch_related 在您的代码中优化查询的数量,但是查询本身的规模甚至可以扩展到数百万个条目。