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似乎对这个想法没有太多开箱即用的支持。

最新更新