(我是数据库的新手,如果这是个奇怪的问题,我深表歉意。如果你认为我的想法不清楚,请随时反对我的观点。)
有些数据结构支持在优于O(n)
的时间内完成的操作,其中n
是当前存储在结构中的项目数。例如,heaps允许插入和删除项。我不明白在数据库中存储这种数据结构的正确方法。
问题。对于一般的数据库,特别是对于Django 2.2.7和Postgres 12.0,当需要比O(log n)
更快的操作时,存储数据结构的正确方法是什么?
这个问题的其余部分是阐述和讨论。
例如,假设我们的数据库由两个表组成,一个称为O(n)
,另一个称为Person
。每个Task
都有一个名为Task
的关联Person
字段,表示任务分配给的人,还有一个名为assignee
的关联int
字段,表示任务的紧急程度。
现在,现实世界中的任何给定的人都可能希望查询数据库,以获得他们被分配的最高优先级priority
。为此类请求提供服务的最简单方法是一次一行地遍历Task
。不幸的是,假设每个Task
至少有一个任务,随着Person
中的行数的增加,这很快就会变得低效。
为了提高查询的时间复杂度,我们可以将另一列添加到类型为Person
名为Person
的list(Task)
表中。其思想是,此字段将维护一个列表,其中列出此人已分配的所有任务。此更改会使数据库使用更多的空间,但当有人请求分配给他们的最高优先级任务时,会大大提高性能。(我不是专家,但我认为添加冗余信息以提高性能的过程称为“非规范化”-了解他们的资料的人能否发表评论并确认我正确使用了这个术语?)
无论如何,即使前面提到的非规范化已经到位,仍然存在一个问题。也就是说,如果某人有大量与之相关的任务,会发生什么?在这种情况下,即使tasks
表包含一个Person
字段,数据库服务请求所需的时间也可能非常长。
在我的计算机科学学位上,我们被教导通过选择适当的数据结构来解决这些问题。在这种情况下,我们可能会更改tasks
字段的类型,以便它不是指向tasks
类型的对象,而是指向list(Task)
类型的对象。
然而,正确的做法对我来说是不明显的。如果堆被存储在硬盘上的一个项目数组中,如果堆中的每个操作都要求我们将整个数组加载到内存中,执行操作,然后再次存储它,那么现在我们回到heap(Task)
时间复杂度,只需执行一个插入或POP操作,这通常占用O(n)
时间。
所以我的问题是如何避免这种情况。
最佳答案
我不明白在数据库中存储这种数据结构的正确方法。
不在数据库中存储数据结构,而是使用数据库提供的特定数据结构在数据库中存储数据。
你提到过PostgreSQL。这是一个特定的产品,与SQL数据库标准广泛兼容,使用与relational model数据兼容的数据结构。它定义了它使用的数据结构,以及使用它们的时间复杂度。在您的特定示例中,关系数据库提供了一种数据结构来解决您的问题,称为index。
在我的计算机科学学位上,我们被教导通过选择适当的数据结构来解决这些问题。
正确的。选择了适当的数据结构之后,您就可以使用实现它的数据存储产品来存储您的数据。Adata structure不是可以储存的东西。
注意,关系数据库只是存储和表示数据的一种方式。它们被证明是非常有用的,并且提供了各种数据结构(最显著的是表和索引)。但是,还有其他一些数据结构不能很好地由关系数据库实现。在这种情况下,你使用不同的产品。例如,Redis自称为data-structures server,并提供一组与关系数据库完全不同的特定数据结构和访问模式。Graph databases将是另一个例子。