Prolog 中的实体关系数据模型

Entity-Relation data model in Prolog

我对如何在 Prolog 中建立实体关系数据模型有疑问。

如果我有两个这样的实体(以 plantuml 形式表示 https://plantuml.com/ie-diagram):

entity A {
  * a_id : number
  --
  a_data : text
}

entity B {
  * b_id : number
  --
  * a_id : number
  b_data : text

B }o--|| A

例如:

a(123, 'data1').       % a(a_id, a_data).
b(456, 123, 'data2').  % b(b_id, a_id, b_data)

这种方式迫使我为每个新事实生成标识符。

其他方式:

a(123, 'data1').
b(456, a(123, 'data1'), 'data2').

这样,如果我更改 a(123, _) a_data 值,b 关系完整性就会丢失。

另一种方式:

a(123, 'data1').
b(456, a(123, _), 'data2').

该事实的正确表述方式是什么?

此致。

我一定会用

a(123, 'data1').       % a(a_id, a_data).
b(456, 123, 'data2').  % b(b_id, a_id, b_data)

不必为事物命名(“生成新标识符”)并不丢脸,您可以轻松做到这一点,可能只需随机生成一个新的 UUID。我听说在关系数据库中对某些结构进行建模的现代方法是始终添加标识符,即使您不需要它们也是如此,以避免以后在执行扩展和迁移时出现实际问题。所以我们在命名方法上很合得来。

a(123, 'data1').
b(456, a(123, 'data1'), 'data2').

不推荐,因为它复制数据没有任何好处,既没有速度也没有清晰度。如果你放弃事实 a(123, 'data1'). 你有一个根植于 b/3 的树结构,如果 a/2 子树很小或变化很大(例如,没有具体的事实在关系 a 中存储 2x2 矩阵,然后从关系 b 中按名称引用它们;可以将任何矩阵直接放入关系 b).

a(123, 'data1').
b(456, a(123, _), 'data2').

没有什么意义,因为你只是在b/3树中的a/2树中有一个神秘的未绑定变量,它只是占用内存,你甚至无法使用它。

P.S.

关系模型的一个特点是假设实体可以“随时间变化”,同时仍保留某种“身份”(即存在可疑的 UPDATE 操作)。在时间 t 存在的关系数据库是数据库日志的顶层。这个想法似乎源于 70 年代缺乏足够大的磁盘。您可能需要考虑一个模型,在该模型中您不进行破坏性更新,而是添加新的时间戳事实以弃用旧事实(最好,事务性)。 Datomic(仅 JVM/Clojure)是该想法的实现。 Prolog 似乎对这个想法没有太多开箱即用的支持。