密钥不在表中

时间:2018-03-02 15:29:34

标签: sql postgresql

表格说明

var query = new Parse.Query(Parse.Session);
    query.find({
        success: function (results) {
            console.log(results);
        }, useMasterKey:true
    });

你可以看到Foreighn Key “fk_invites_receiver_user_id”FOREIGN KEY(receiver_user_id)REFERENCES users(id)。 但是在父表中没有pk用户的记录,其中在参考表fk中存在。

# \d invites;
                          Table "public.invites"
        Column         |       Type              |   Modifiers                       
-----------------------+-----------------------------+---------------------
 id                    | integer                 | not null default 
 email                 | character varying       | 
 key                   | character varying       | 
 sender_user_id        | integer                 | not null
 receiver_user_id      | integer                     | 

Indexes:
    "invites_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "fk_invites_receiver_user_id"
               FOREIGN KEY (receiver_user_id) REFERENCES users(id)
    "fk_invites_sender_user_id"
               FOREIGN KEY (sender_user_id) REFERENCES users(id)

问题是它是怎么回事,修复冲突的简单方法是删除错误记录,但希望将来排除这种情况,当我尝试恢复数据时,有一个错误:

# select id from users where id = 958;
 id 
----
(0 rows)

select count(*) from invites where receiver_user_id = 958;
 count 
-------
     1
(1 row)

P.S。

DETAIL:  Key (receiver_user_id)=(958) is not present in table "users".
    Command was: ALTER TABLE ONLY invites
    ADD CONSTRAINT fk_invites_receiver_user_id
                   FOREIGN KEY (receiver_user_id) REFERENCES users(id);

2 个答案:

答案 0 :(得分:1)

创建失败

-- tmp schema
-- \i tmp.sql

        -- tables
CREATE TABLE users
        (id serial NOT NULL PRIMARY KEY
        , name text
        );
CREATE TABLE refs
        ( user_from INTEGER NOT NULL
        , user_to INTEGER NOT NULL
        , msg text
        );

        -- data
INSERT INTO users(name) VALUES ('Alice'), ('Bob');
INSERT INTO refs VALUES (1,2), (1,3);

        -- FK constraints
ALTER TABLE refs
        ADD CONSTRAINT bad_user_from
        FOREIGN KEY (user_from) references users(id);
ALTER TABLE refs
        ADD CONSTRAINT bad_user_to
        FOREIGN KEY (user_to) references users(id)
        NOT VALID ; -- <<--HERE


        -- This should fail; user=3 does not exist
INSERT INTO refs VALUES (3,2), (2,3);

修复

        -- "repair" the broken refs (by introducing a dummy row)
INSERT INTO users(id,name) VALUES (0, 'NoName');

        -- Make the bad FKs point to the dummy row
UPDATE refs r
SET user_to =0
WHERE NOT EXISTS(
        SELECT *
        FROM users u
        WHERE u.id= r.user_to
        );

UPDATE refs r
SET user_from =0
WHERE NOT EXISTS(
        SELECT *
        FROM users u
        WHERE u.id= r.user_from
        );

SELECT * FROM refs r
JOIN users u0 ON u0.id= r.user_from
JOIN users u1 ON u1.id= r.user_to
        ;

INSERT INTO users(name) VALUES ('NewName');
        -- see what we'v got
SELECT * FROM users;
SELECT* FROM refs r
JOIN users u0 ON u0.id= r.user_from
JOIN users u1 ON u1.id= r.user_to;

验证约束

\d refs
\d users

        -- enforce the constraint
ALTER TABLE refs
        VALIDATE CONSTRAINT bad_user_to; -- <<-- HERE

        -- check if valid
\d refs
\d users

    -- This should not fail; user=3 does exist now
INSERT INTO refs VALUES (3,2), (2,3);

答案 1 :(得分:0)

不幸的是,答案是“数据损坏”。

您应该删除有问题的行,使用pg_dumpall转储数据库并将其还原到使用initdb创建的新群集。

您还应该尝试找出导致数据损坏的原因。你最近有没有崩溃?您是否存在不可靠的存储或硬件问题?数据库日志中有什么奇怪的东西吗?

要尽可能地排除这些问题,请始终使用适用于PostgreSQL版本的最新修订包并使用可靠的硬件。