【发布时间】:2019-11-14 08:09:56
【问题描述】:
(我是数据库的新手,如果这是一个奇怪的问题,请道歉。如果您认为我没有清楚地思考,请随时不同意我的观点。)
一些数据结构支持可以在比O(n) 时间更好的时间内完成的操作,其中n 是当前存储在结构中的项目数。例如,heaps 允许 O(log n) 插入和删除项目。我不明白在数据库中存储此类数据结构的正确方法。
问题。关于一般数据库,特别是关于 Django 2.2.7 和 Postgres 12.0,当需要比
O(n)操作更快时,存储数据结构的正确方法是什么? ?
这个问题的其余部分是阐述和讨论。
例如,假设我们的数据库包含两张表,一张名为Person,另一张名为Task。每个Task 都有一个关联的Person 字段,称为assignee,代表任务分配给的人,还有一个关联的int 字段,称为priority,代表任务的紧迫性。
现在,现实世界中的任何给定人都可能想要查询数据库以获取分配给他们的最高优先级Task。处理此类请求的最简单方法是遍历Task 的每一行,一次一个。不幸的是,假设每个Person 至少有一个任务,随着Person 中行数的增长,这很快就会变得低效。
为了提高查询的时间复杂性,我们可能会在Person 表中添加另一列,类型为list(Task),称为tasks。这个想法是,该字段将维护此人已分配的所有任务的列表。此更改会导致数据库使用更多空间,但当有人请求分配给他们的最高优先级任务时,会大大提高性能。 (我不是专家,但我认为这种添加冗余信息以提高性能的过程称为“非规范化” - 知道他们的东西的人可以发表评论并确认我正确使用了这个术语吗?)
无论如何,即使上述非规范化已经到位,仍然存在问题。也就是说,如果某人有大量与之相关的任务会发生什么?在这种情况下,即使Person 表包含tasks 字段,数据库为请求提供服务所花费的时间也可能非常长。
在我的计算机科学学位中,我们被教导通过选择适当的数据结构来解决这类问题。在这种情况下,我们可能会更改tasks 字段的类型,这样它就不会指向list(Task) 类型的对象,而是指向heap(Task) 类型的对象。
但是,这样做的正确方法对我来说并不明显。如果堆在硬盘驱动器上存储为一个项目数组,并且如果对堆的每个操作都需要我们将整个数组加载到内存中,执行操作,然后再次存储它,那么现在我们回到@ 987654346@ 的时间复杂度只是执行一次插入或弹出操作,通常需要O(log n) 时间。
所以我的问题是如何避免这种情况。
【问题讨论】:
-
是的,这将被称为database denormalization。
标签: django database postgresql time-complexity storage