Django 模型中许多空外键的成本是多少?
我有一个帖子模型、一个图片模型和一个频道模型。我在连接到Post模型的图像模型中有一个外键。此外,我正在尝试添加一个连接到通道模型的可空外键Django 模型中许多空外键的成本是多少?,django,django-models,Django,Django Models,我有一个帖子模型、一个图片模型和一个频道模型。我在连接到Post模型的图像模型中有一个外键。此外,我正在尝试添加一个连接到通道模型的可空外键 class Image(models.Model): post = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE) comment = models.ForeignKey(Comment, null=True, blank
class Image(models.Model):
post = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
comment = models.ForeignKey(Comment, null=True, blank=True, on_delete=models.CASCADE)
news = models.ForeignKey(News, null=True, blank=True, on_delete=models.CASCADE)
message = models.ForeignKey(Message, null=True, blank=True, on_delete=models.CASCADE)
channel = models.ForeignKey(Channel, null=True, blank=True, on_delete=models.CASCADE)
file = ProcessedImageField(upload_to='uploads/%Y/%m/%d/',
processors=[Transpose()],
format='JPEG',
options={'quality': 50},
blank=True)
我担心的是通道字段大部分为空,因为每个通道只需要一个图像。但是图像必须与一个帖子连接。因此,每个通道都有一个连接到post的图像。但是,与一个通道相比,将有无可比拟的更多帖子和图像,因此图像模型中的通道字段将浪费大部分时间
我想到的另一个解决方案是专门为通道模型创建一个新的图像模型,当创建新的图像实例时,手动从原始图像后连接实例复制图像
class ChannelImage(models.Model):
channel = models.OneToOneField(Channel)
post = models.OneToOneField(Post)
file = ProcessedImageField(upload_to='uploads/%Y/%m/%d/',
processors=[Transpose()],
format='JPEG',
options={'quality': 50},
blank=True)
//copy a file from the original post
所以我的问题是,在一个模型中浪费这么多空外键的代价是什么?模型中有许多浪费的外键可以吗?首先
在很多行中都有一个属性为null的模型,这在技术上并没有什么不好的
关于你的设计
您将讨论两种设计:
Image -> Channel ( image references channel )
ChannelImage -> Image ( new model to store channel image )
但是,在你的帖子中,你说:
因此,每个通道都有一个连接到post的图像
但是,你怎么了
Channel -> Image ( channel reference image )
使用这种方法,您不会丢失信息,因为Image
仍然连接到Post
答复
在我看来,这是一种方式:
当考虑成本时,你需要考虑两个主要方面;时间和记忆 关于postgresql的外键成本有一个很好的解释。在只有一个动态参数的情况下,测试外键对时间性能的影响。结果如下: 此函数接受的唯一参数是它应该创建的引用此源表的表的数量。[…]多次收集这些计时,每次运行三次后平均为2961ms、3805ms、4606ms、5089ms和5785ms。正如我们所看到的,在仅仅五个外键之后,我们的更新性能下降了28.5%。当我们有20个外键时,更新速度慢了95% 当你考虑内存成本时,当你想到今天的计算机时,这并不是什么大问题。但是如果你认为你会有很多空外键字段,你也可以考虑创建一个交叉表,而不是使用外键。