下面是我正在处理的一个项目的一个非常精简的版本。
CREATE TABLE cidr_block (
id serial not null unique,
block_def cidr primary key,
dhcp_server_id int not null references computer_system (id),
...
);
CREATE TABLE ip_addr (
computer_id int not null references computer_system (id),
mac_addr macaddr not null unique,
ip_addr inet not null unique,
);
这是一个网络配置数据库。现在,预计大多数(但不是全部)ip_addr.ip_addr 记录将位于 cidr_block.block_def 块中。其他可能不是外部链接到客户位置的 vpn 接口。没有简单的、声明性的方法来确保两个表之间适用行的 fkey。所以我想知道:
在适当的地方使用触发器创建 fkey 链接是否更可取?
仅仅加入预期的地方就足够了吗?如果一台计算机被赋予了一个错误的 IP 地址,它就不会从 dhcp 服务器获得一个,我们很快就会知道这一点。(写入触发相关 dhcp 服务器更新的触发通知)
还有另一种更好的方法吗?
为了在这里回答我自己的问题,这是我最终所做的:
函数 ip_block(inet) 查找一个 inet 地址的 ip block 记录。
检查约束以确保对于适当的地址类别返回不为空。这将在插入或更新分配表时触发。
触发函数检查块中地址的分配表,如果找到则引发 RI 异常。
当更新 ip 块的 block_def 或删除 ip 块时,运行上述函数的触发器。
我暂时不接受这个答案,看看是否有其他人有更好的方法。然而,实际执行此操作的代码量比预期的要少得多,所以到目前为止我对它非常满意。