【问题标题】:parent and child table foreign key父子表外键
【发布时间】:2012-04-20 19:46:50
【问题描述】:

我目前有一个父表:

CREATE TABLE members (
    member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY
    first_name varchar(20)
    last_name varchar(20)
    address address (composite type)
    contact_numbers varchar(11)[3]
    date_joined date
    type varchar(5)
);

还有两个相关的表:

CREATE TABLE basic_member (
    activities varchar[3]) // can only have 3 max activites
    INHERITS (members)
);

CREATE TABLE full_member ( 
    activities varchar[]) // can 0 to many activities
    INHERITS (members)
);

我还有一张桌子:

CREATE TABLE planner (
        day varchar(9) FOREIGN KEY REFERENCES days(day)
        time varchar(5) FOREIGN KEY REFERENCES times(time)
        activity varchar(20) FOREIGN KEY REFERENCES activities(activity)
        member bigint FOREIGN KEY REFERENCES members(member_id)
);
ALTER TABLE planner ADD CONSTRAINT pk_planner PRIMARKY KEY (day,time,activity,member);

我目前正在尝试添加

INSERT INTO planner VALUES ('monday','09:00','Weights',2);

我已经在 full_members 中添加了一个集合

INSERT INTO full_members 
VALUES (Default, 'Hayley', 'Sargent', (12,'Forest Road','Mansfield','Nottinghamshire','NG219DX'),'{01623485764,07789485763,01645586754}',20120418,'Full');

我在 Planner 中的插入目前无法正常工作 - 您能解释一下原因吗?

【问题讨论】:

  • 与您的其他问题的评论相同:请向我们展示您尝试运行的完整 CREATE TABLEINSERTs。
  • 欢迎使用 StackOverflow:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ({ } ) 在编辑器工具栏上以很好地格式化和语法突出显示它!
  • 您在插入 Planner 时遇到什么错误?是日期、时间或活动上的 FK 参考失败 - 还是成员编号?海莉萨金特的成员是 2 号吗?另外,您确定日期和时间最好用 VARCHAR 表示,而不是使用正确的 DATE 和 TIME 类型?

标签: postgresql inheritance foreign-keys primary-key


【解决方案1】:

我设法回答了我自己的问题,因为目前 posgreSQL 不能很好地处理继承和外键,所以我没有创建规则

CREATE RULE member_ref
AS ON INSERT TO planner
WHERE new.member NOT IN (SELECT member_id FROM members)
DO INSTEAD NOTHING;

这与外键基本相同

【讨论】:

    【解决方案2】:

    不确定这是否会是更好的解决方案,但它就是这样......

    原理很简单:

    • 创建新表我们称之为table_with_pkeys,它将复制继承表child1child2child3的主键列...
    • 在继承的表上创建触发器,插入后,将新的 PK 插入到 table_with_pkeys 新创建的 PK 中,更新后如果更改则更新它,删除后从 table_with_pkeys 中删除相同的 PK。
    • 然后在每个应该使用 FK 通过父表的 PK 引用 child1、child2 或任何一个的表中,将 FK 指向不是父表的 PK,而是指向 table_with_pkeys,它具有所有子 PK 的副本,这样您就可以轻松管理具有可以级联更新、限制更新等的外键。

    希望对你有帮助。

    【讨论】:

    • 我很确定这将有竞争条件,除非您对所有事情都使用 SERIALIZABLE 事务,在这种情况下,您可以直接从问题中的表上的触发器进行检查,而无需需要额外的桌子。
    • 为什么会比原来的还要多?您所做的只是具体化主键的视图。
    【解决方案3】:

    您在地址中的 12 之前缺少一个公开报价:

    INSERT INTO full_members 
    VALUES (Default, 'Hayley', 'Sargent', (12 Forest Road', 'Mansfield', 'Nottinghamshire', 'NG219DX'),
            '{01623485764,07789485763,01645586754}',20120418,'Full');
    

    应该是:

    INSERT INTO full_members 
    VALUES (Default, 'Hayley', 'Sargent', ('12 Forest Road', 'Mansfield', 'Nottinghamshire', 'NG219DX'),
            '{01623485764,07789485763,01645586754}',20120418,'Full');
    

    【讨论】:

    • 插入到 full_members 工作正常,我可以选择记录,一切都很完美,这是我遇到问题的插入计划器
    • 啊,好吧,如果您像以前那样更改 INSERT,那么是的,它会起作用。
    【解决方案4】:

    如果上述具体化视图方法不适合您,请创建约束触发器以检查参照完整性。不幸的是,声明性引用完整性目前不适用于继承。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 1970-01-01
      • 2012-03-20
      • 1970-01-01
      相关资源
      最近更新 更多