Database 用prolog实现数据库

Database 用prolog实现数据库,database,prolog,Database,Prolog,我想在Prolog中实现某种“数据库” 我有两个对表格和行建模的想法: % First one client('B069','Laurent','769, rue de la LALALA','LLN','A1',10000). % Second one data(client,'B069',name,'Laurent'). data(client,'B069',adress,'69, rue de la LALALA'). data(client,'B069',town,'LLN'). da

我想在Prolog中实现某种“数据库”

我有两个对表格和行建模的想法:

% First one
client('B069','Laurent','769, rue de la LALALA','LLN','A1',10000).

% Second one
data(client,'B069',name,'Laurent').
data(client,'B069',adress,'69, rue de la LALALA').
data(client,'B069',town,'LLN').
data(client,'B069',cat,'A1').
data(client,'B069',amount,10000).
例如,使用这两个模型,我可以分别为金额为正的客户创建“从客户选择ID,其中金额>0”:

% First one
client1_positive(Client) :- findall(ID,(data(client,ID,compte,Amount),Amount>0),Client).

% Second one
client2_positive(Client) :- findall(ID,(client(ID,_,_,_,_,Amount),Amount>0),Client).
它们都有相同的输出

?- client1_positive(Clients).
Client = ['B069'].

?- client2_positive(Clients).
Client = ['B069'].
但这是我的问题,因为我对Prolog非常陌生,所以我完全不知道如何使它成为动态的,比如“selectname fromclientwhereid='B069'”。我可以为这个特定的SQL查询实现一个规则,但是我找不到一种方法来实现一个更抽象的规则,以便可以解释每个查询

对于如何在Prolog中对这些数据进行建模,是否有最佳实践?关于如何在Prolog中使请求更抽象,还有一些想法(不是我问题的详细答案)


非常感谢

考虑一下如何使用关系数据库实现这一点。您可能会有一个客户机表,其中的记录包括客户机id(键)、客户机名称、地址、电话和其他联系信息。你不会想要一个单独的姓名、地址、电话等记录,这太麻烦了

对于与客户机有某种关系的客户机数据,您将有单独的表(一对一、多对一、多对多……)。如果一个客户可能有多组联系信息,那么这就是联系信息和客户之间的多对一关系,因此您可以设置一个单独的ContactInfo表,以“contact\u info\u id”作为主键,它将包含包含contact\u info\u id、client id、contact information等内容的记录。对于示例中的金额,您将有一个金额表,其中包含由金额id(键)、客户机id和金额组成的记录

要在Prolog中实现这一点,您需要以基本相同的方式构造它。设置
客户端
数据和
金额
数据:

% clients
client('B069', 'John Doe', '123 Main St', 123-456-1234).
client('B070', 'Jane Smith', '100 West Elm', 999-999-8888).
...

% amounts
amount('A010', 'B069', 10000).
amount('A010', 'B070', 10100).
...
以上可以是一对一或多对一

查询的等效项:
SELECT name FROM client,其中ID='B069'
将是:

?- client('B069', Name, Address, Phone).
client_positive(Clients) :-
    findall(ClientId, (amount(_, ClientId, Amount), Amount > 0), Clients).
您选择的正金额为:

?- client('B069', Name, Address, Phone).
client_positive(Clients) :-
    findall(ClientId, (amount(_, ClientId, Amount), Amount > 0), Clients).

考虑一下如何使用关系数据库实现这一点。您可能会有一个客户机表,其中的记录包括客户机id(键)、客户机名称、地址、电话和其他联系信息。你不会想要一个单独的姓名、地址、电话等记录,这太麻烦了

对于与客户机有某种关系的客户机数据,您将有单独的表(一对一、多对一、多对多……)。如果一个客户可能有多组联系信息,那么这就是联系信息和客户之间的多对一关系,因此您可以设置一个单独的ContactInfo表,以“contact\u info\u id”作为主键,它将包含包含contact\u info\u id、client id、contact information等内容的记录。对于示例中的金额,您将有一个金额表,其中包含由金额id(键)、客户机id和金额组成的记录

要在Prolog中实现这一点,您需要以基本相同的方式构造它。设置
客户端
数据和
金额
数据:

% clients
client('B069', 'John Doe', '123 Main St', 123-456-1234).
client('B070', 'Jane Smith', '100 West Elm', 999-999-8888).
...

% amounts
amount('A010', 'B069', 10000).
amount('A010', 'B070', 10100).
...
以上可以是一对一或多对一

查询的等效项:
SELECT name FROM client,其中ID='B069'
将是:

?- client('B069', Name, Address, Phone).
client_positive(Clients) :-
    findall(ClientId, (amount(_, ClientId, Amount), Amount > 0), Clients).
您选择的正金额为:

?- client('B069', Name, Address, Phone).
client_positive(Clients) :-
    findall(ClientId, (amount(_, ClientId, Amount), Amount > 0), Clients).

你的第一个方法很好。例如,如果是一个 一个人可以有多个地址

查询只是一个带有变量的术语:

| ?- client('B069',Name,Adress,Town,Cat,Amount).
Cat = 'A1',
Name = 'Laurent',
Town = 'LLN',
Adress = '769, rue de la LALALA',
Amount = 10000 ?
您可以将任何参数用作查询中的键。您的序言可能不会对所有这些内容进行索引,这可能是一个问题,也可能不是一个问题

| ?- client(Key,'Laurent',_,_,_,_).
Key = 'B069' ? 
如果有多个答案,则通过回溯返回。Findall将它们收集在一个列表中,这可能是您想要的,也可能不是您想要的


如果“动态”是指从数据库中添加和删除内容,那么您可以使用
assert/1
retract/1
第一种方法就可以了。例如,如果是一个 一个人可以有多个地址

查询只是一个带有变量的术语:

| ?- client('B069',Name,Adress,Town,Cat,Amount).
Cat = 'A1',
Name = 'Laurent',
Town = 'LLN',
Adress = '769, rue de la LALALA',
Amount = 10000 ?
您可以将任何参数用作查询中的键。您的序言可能不会对所有这些内容进行索引,这可能是一个问题,也可能不是一个问题

| ?- client(Key,'Laurent',_,_,_,_).
Key = 'B069' ? 
如果有多个答案,则通过回溯返回。Findall将它们收集在一个列表中,这可能是您想要的,也可能不是您想要的


如果“动态”是指从数据库中添加和删除内容,那么您可以
assert/1
retract/1

谢谢您的帮助。你知道吗,通过这个模型,我可以得到客户端的第二个参数,一个类似于
nth_arg(+谓词,+nth,-参数)
的规则。这种规则存在吗?@tomatediabolik在本例中,您知道每个参数位置的含义。按索引选择参数的用例是什么?通常,您可能有类似于,
client\u phone(ClientId,phone):-client(CllientId,电话)。
或类似的内容。如果您确实需要按索引选择它,您可以使用
arg/3
arg(+Nth,+Term,-Argument)
)来获取一个术语的第n个参数。没有关于你的用例的更多信息,我不知道还有什么要说的。谢谢你的帮助。你知道吗,通过这个模型,我可以得到客户端的第二个参数,一个类似于
nth_arg(+谓词,+nth,-参数)
的规则。这种规则存在吗?@tomatediabolik在本例中,您知道每个参数位置的含义。按索引选择参数的用例是什么?通常,您可能有类似于,
client\u phone(ClientId,phone):-client(CllientId,电话)。
或类似的内容。如果您确实需要按索引选择它,您可以使用
arg/3
arg(+Nth,+Term,-Argument)
)来获取一个术语的第n个参数。如果没有关于您的用例的更多信息,我不知道还有什么