PostgreSQL + Django:多类型数据的SQL设计模式

时间:2011-12-01 10:00:51

标签: sql django postgresql

我需要在SQL中存储消息数据。无法决定走哪条路。

有一个主要的消息,比如说(简化):

class Message(models.Model):
    user_id = models.ForeignKey(User)
    text = models.TextField()

另外,还有其他Message类继承了这个。

class MmsMessage(Message):
    imagedata = models.ForeignKey(ImageData)

等等。这些其他消息类当然可以有超过1个附加字段。

现在,我正在评估最好(最快)的设计模式,以使其发挥作用。 在大约25%的情况下,我不需要额外的字段,只需要原始的Message对象(Message.objects.all)。在其他情况下,我需要所有数据。其他字段可能不一定是可搜索的。尽管如此,拥有它会很棒。

我在考虑:

  • A:继承(具体,抽象)

    • 抽象继承已经完成。我无法做到:Message.objects.all()这是不可接受的。

    • 具体的继承在我看来似乎是一种方法。尝试了两种方法。 django-model-utils one(select_subclasses)不需要额外的查询,但是由于结果中存在大量内连接和冗余数据,因此与其他解决方案相比,它非常慢。

    • django_polymorphic(仍具体继承)方法(使用contenttypes来了解我们正在处理的内容然后选择相关字段)比select_subclasses快至少4倍(至少在postgresql上) - 这对我来说是一个小小的惊喜(它需要+ n个查询,其中n是多个子类型,但由于连接更简单且没有不必要的数据结果,因此仍然更快)。测试了20种不同Message子类型的10 000个对象。

  • B:EAV模型(其他属性多对多)

    • 没有测试过EAV模型,但我怀疑它会比继承解决方案更快。当我知道我想要的列名和类型时,似乎EAV模型失去了它的所有魅力。
  • [UPDATED - horse_with_no_name] B1:hstore - 与EAV类似,有很多但很快(没有连接,后端支持)

    • 非常适合添加自定义字段等字典。
    • 缺点:我失去了与其他django数据库后端的兼容性(我不愿意),它也是类型无关的,键和值是TEXT。由于hstore dict中的许多TEXT字段,我也担心一般会使Message表原始查询变慢。
  • C:消息表中的XML字段以获取其他数据

    • Message表中的XML字段对我来说有点可疑。如果我不需要这些附加字段(来自消息子类型)可搜索或可索引,那么XML字段是一个很好的解决方案吗?

您认为最佳选择是什么?

1 个答案:

答案 0 :(得分:1)

这里简单的答案是只使用一个表。然而,真正的问题是为什么你首先将东西放在数据库中。如果您的目的是扩展到大型,那么您可能希望查看混合存储模型(在数据库中索引消息并将原始消息存储在hbase之类的内容中)。