将同一表中的行关联的最佳方式是什么



我正在尝试设计一个行表,每一行都可以以某种方式与另一行相关联。

在实践层面上,我们谈论的是土壤层(考古学(。

一行 - 一层 - 在另一层之上,本质上 A 在 B 之上高于 C,同样 C 在 B 下方低于 A。在图形数据库中,这将是非常微不足道的,不幸的是,我们正在使用关系数据库。每个关系船都有一个方向,A 在 B 之上,但 B 不在 A 之上。数据将被添加为 A 在 B 之上,尽管我们可能想要搜索并找到 B 上方的内容,无论是否明确这种关系,如果 A 高于 B,则 B 必须在 A 下方。更复杂的是,D 可以等于 E,因为它与 D=E 和 E=D 相同,但这不是定向的,因为关系是双向的。

这就是逻辑。

但是,设计一些表以允许这样做的最佳方法是什么?我应该指出我们使用PostgreSQL和Django。

下面是一个基本示例。

Table name: Layer
id
Layer_name

我假设我们需要如下所示的第二个表:

Table name: Relationship
id
layer_id1
relationship
layer_id2

我还看到了将 REFERENCES 用于非定向关系,如此处所述。

我提到我们正在使用 Django,前端可以/应该做任何清理或技巧,例如 if 语句,如果 A 高于 B,则输入 B 也低于 A,如果 A=B 或 B=A 只输入 A 等于 B。

欢迎任何建设性的建议。

虽然在 PostgreSQL 中可以将层表示为图形(或使用联结表的多对多关系(,但这样做会使运行比较不相邻层的查询的成本很高,因为您需要进行许多连接才能遍历关系序列。

为土壤层添加一列可能更简单,以便对它们进行排序和比较。

最简单的建模方法是引入数字列。您可以将此列视为一个数字,该数字允许您垂直排序图层。

该列看起来像

level double precision NOT NULL

第一层可以设置为任意起始值,例如level = 0.0

如果在所有其他图层的上方或下方添加一个图层,则其level将比最大值多 1 或比最小值少 1

。要在两个现有图层之间添加图层,请将其level设置为相邻图层的算术平均值。例如,要在级别为 2.0 的图层和级别为 3.0 的图层之间添加图层,请将新图层级别设置为 2.5。

要查询相邻图层,可以按级别值的差异进行排序,下面是负差异,上面是正差异。

正如 Iain Shelvington 所提到的,对于你的情况来说,最好的方法是 Django 的自引用、非对称的 ManyToManyField:

class SoilLayer(models.Model):
name = models.CharField(max_length=30)
lower_layers = models.ManyToManyField(
"self",                     #each layer can point to other layers
symmetrical=False,          #relationships are directional (i.e. upper/lower)
related_name="upper_layers" #look up reverse relationships easily
)

然后,您可以创建图层并对其进行排序:

D = SoilLayer.objects.create(name="D")
C = SoilLayer.objects.create(name="C")
B = SoilLayer.objects.create(name="B")
B.lower_layers.add(C, D)
A = SoilLayer.objects.create(name="A")
A.lower_layers.add(B)

最后,您可以搜索它们:

A.lower_layers.all();    #returns B
B.lower_layers.all();    #returns C and D
C.upper_layers.all();    #returns B
D.upper_layers.all();    #returns B

最新更新