欧洲废物目录代码的父/树参考完整性检查

Parent / tree referential integrity check for European Waste Catalogue codes

我正在尝试创建一个数据库,其中一部分涉及存储欧洲废物目录 (EWC) 代码。

EWC 代码是分层的 2、4 或 6 位数字代码,其中前 2 个字符代表章节,接下来的 2 个字符代表子章节,最后 2 个字符代表废物描述。

例如:
02 来自农业、园艺、水产养殖、林业、狩猎和渔业、食品制备和加工的废物
0202 肉类制备和加工产生的废物。鱼和其他动物源性食物
020203 不适合消费或加工的材料

需要存储整棵树,所以我想在创建子记录时确保父记录存在。

但是......我对如何处理这个问题有点困惑。不直接引用列的外键(即:首先尝试调用函数)触发语法错误:

...
foreign key substring(ewc_code, 1, length(ewc_code) - 2) references cdsw_data.ewc_codes (ewc_code) match simple on update restrict on delete cascade
...
ERROR:  syntax error at or near "substring"
LINE 5:  foreign key substring(ewc_code, 1, length(ewc_code) - 2) re...

有人可以指导我找到合适的解决方案吗?

Table结构:

create table cdsw_data.ewc_codes (
    ewc_code varchar(6) primary key,
    ewc_descrition text,
    constraint valid_ewc check(ewc_code ~ '^(\d\d){1,3}$')
);

我可以想到 3 种方法:

  • 使用 3 个不同的 table,一个包含两位数列,一个包含两个两位数列,一个包含三个两位数列。使用它们作为复合主键。声明对父 table 列的外键引用。有一个(可能重载的)函数来计算作为单个字符串的完整键。
  • 使用触发函数进行所有完整性检查
  • 使用可用作外键并断言具有预期值的辅助列:

    create table cdsw_data.ewc_codes (
        ewc_code varchar(6) primary key,
        ewc_parentcode varchar(4) references cdsw_data.ewc_codes,
        ewc_description text,
        constraint valid_ewc check(ewc_code ~ '^(\d\d){1,3}$'),
        constraint parent check(ewc_parentcode is not distinct from 
                                null_if(left(ewc_code, -2), ''))
    );