2010-04-14 93 views
1

我有一个模型,说,项目。我想存储任意数量的属性,如标题,描述,release_date。我希望他们不只是字符串,但有python类型,所以字符串,布尔,日期时间等。在Django模型中的任意类型的数据

我在这里有什么选择?带有单独名称 - 值表的EAV模式将不起作用,因为所有值都具有相同的数据库类型。例如,JSONField可能可以提供帮助,但它不知道日期时间。另外我在看PickeField,它非常适合,但我对性能有点担心。

回答

4

你有几个选项,没有一个很好。其中一些已经在Stack Overflow上讨论过before

首先,如您所建议的那样,您拥有entity-attribute-value设计模式。

  • 您可以添加数据库类型检查,方法是为VARCHAR表和INT表中的一个以及一个用于BOOLEAN等的表。
  • EAV使选择非常痛苦。您必须查询多个表才能真正获取对象,并且如果必须在查找中使用EAV表中的值,则随着大小的增加,您将遇到性能问题。
  • 但是,通常情况下,EAV应该只用于非常稀疏的数据,而另一个选项根本无效。
  • 在PyPI上有一个Django包,但我没有使用它。
  • 我已经看到,使用时绝对需要很大的灵活性

一个更好的方法这样的做法是有一个表,其模式的变化和元数据表描述表中的一些相当大的规模商用产品。对于大多数项目具有大多数属性的密集数据,这比EAV有很多优势。这种方法有时称为动态表或动态行。

  • 插入,更新和删除快得多,因为一切都在1-2表
  • 类型检查,并可能限制可以加入
  • 然而,这种方法留下了非常复杂的数据库,也很难与
  • 工作我不知道Django会使用它的ORM与这种数据库的任何方式,因为您的模型将在飞行中改变。
  • 您正在使用ALTER TABLE即时更改您的数据库。您最好非常小心您的交易

如果您不需要根据这些动态属性执行查找,那么一种好方法是将动态数据存储在JSONField中,或者更好地将模式存储在经过模式验证的XMLField中。但是,如果您必须根据属于您的JSON或XML的动态属性进行查找,查找将会很痛苦。

最好的方法取决于您的数据稀疏程度以及您将如何查找该数据。另外,要问的一个很好的问题是,如果你绝对需要这种灵活性。我曾参与过一些我们决定需要EAV的项目,但自项目投入生产以来,属性很少被添加,很少被删除,所以我们得到了所有的缺点,而且没有任何好处。