Django:如何存储/查询字典类型的数据集?

0 投票
2 回答
1057 浏览
提问于 2025-04-18 12:52

如果这个问题已经有人问过,或者在别的地方有答案,我先说声抱歉。

总之,我正在做一个项目,简单来说,就是存储图片的元数据,然后让用户可以搜索这些元数据(这些元数据就像一长串的键值对)。如果这些元数据是标准化的,那就没什么大问题了。但是问题是,对于数据库中的每一张图片,它的元数据可能有很多不同的键值对。而且没有一个标准的键列表。

基本上,我需要找到一种方法,为每个模型存储一个字典,但这个字典的键值对是任意的。而且我需要能够查询这些数据。我的工作单位计划上传成千上万的图片到这个程序,所以查询速度必须要快。

我在数据库中有一个模型,就是图片模型,里面有一个 filefield

所以,我现在在两个选择之间犹豫,希望能得到一些有经验的人的帮助,帮我选择最好的方案(或者其他更好的解决办法)

  1. 使用传统的关系型数据库,比如 MySql,创建一个单独的模型,里面有一个 foreignkey 连接到图片模型,还有一个键字段和一个值字段。然后,当我需要查询数据时,我会请求这个单独表中与某张图片相关的所有实例,然后查询这些行以找到我需要的键值组合。

  2. 使用像 MongoDB 这样的数据库,配合 django-toolbox 和它的 DictField 来存储元数据。然后,当我需要查询时,我会访问这个字典,搜索我需要的键值组合。

虽然我觉得第一种方案在查询时间上会更好,但每张图片可能有多达 40 个键值对的元数据,这让我担心如果有成千上万的图片,这个单独的“字典”表会变得太大。

任何建议都非常感谢。谢谢!

2 个回答

0

元数据是什么类型的?它的键和值都是字符串吗?我猜是这样的。

你的数据集规模很重要。如果你有几千张图片,每张图片有最多40对键值对,那么在选项1中,单独的表最多会有40万条记录。对于现代数据库来说,这没什么问题,只要你的机器性能不错,数据库设置也正确。需要注意的一点是,要在表中创建复合索引字段。在Django的ORM中,这可能看起来像这样:

class ImageMeta(models.Model):
    image = models.ForeignKey('Image')
    key = models.CharField(max_length=XXXX)
    value = models.CharField(max_length=XXXX)
    class Meta:
        index_together = [ ["image", "key", "value"], ]     # Django 1.5 and above
0

在一个Django项目中,针对这类问题你有四种选择,顺序没有特别的意义:

  • 如果使用PostgreSQL,你可以用hstore字段类型,这基本上就是一个被“腌制”的Python字典。虽然在查询方面不太方便,但它能很好地保存你的数据。

  • 如果使用Django-NoRel配合mongodb,你可以使用ListField字段类型,它能做同样的事情,并且可以像查询MongoDB中的其他内容一样进行查询。(选项2)

  • 使用Django-eav来创建一个实体属性值存储来管理你的数据。这是个优雅的解决方案,但查询速度非常慢。(选项1)

  • 把你的数据存储为一个足够长的TextField中的json字符串,并创建自己的函数来进行数据的序列化和反序列化,前提是你不打算对这些数据进行查询。

根据我自己的经验,如果你需要对数据进行查询,第二个选项绝对是最好的选择。Django中的EAV,如果没有复合键,使用起来会很麻烦。

撰写回答