X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by postgresql.org (Postfix) with ESMTP id A8DCE9DCBAD for ; Wed, 22 Mar 2006 05:15:48 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 93792-06 for ; Wed, 22 Mar 2006 05:15:48 -0400 (AST) X-Greylist: delayed 00:14:20.065984 by SQLgrey- Received: from smtp2.lc.anpe.fr (unknown [80.124.143.16]) by postgresql.org (Postfix) with ESMTP id C8CDB9DCA05 for ; Wed, 22 Mar 2006 05:15:45 -0400 (AST) Received: from HOMERE03.anpe.fr (amadeus [127.0.0.1]) by smtp2.lc.anpe.fr (antivirus) with ESMTP id 0E55473D35 for ; Wed, 22 Mar 2006 10:01:23 +0100 (CET) Received: from [10.0.32.170] ([10.0.32.170]) by HOMERE03.anpe.fr with Microsoft SMTPSVC(6.0.3790.1830); Wed, 22 Mar 2006 10:01:02 +0100 Message-ID: <44211263.5020807@anpe.fr> Date: Wed, 22 Mar 2006 10:01:23 +0100 From: Patrick JACQUOT User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 Cc: pgsql-sql@postgresql.org Subject: Re: Referential integrity broken (8.0.3), sub-select help References: <20060321145839.68211.qmail@web50301.mail.yahoo.com> In-Reply-To: <20060321145839.68211.qmail@web50301.mail.yahoo.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 22 Mar 2006 09:01:02.0732 (UTC) FILETIME=[25410CC0:01C64D8F] X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.221 required=5 tests=[AWL=0.032, MISSING_HEADERS=0.189] X-Spam-Score: 0.221 X-Spam-Level: X-Archive-Number: 200603/346 X-Sequence-Number: 24692 ogjunk-pgjedan@yahoo.com wrote: >Hello, > >I've got 2 tables, "url" (U), and "bookmark" (B), with "bookmark" pointing to "url" via FK. >Somehow I ended up with some rows in B referencing non-existent rows in U. >This sounds super strange and dangerous to me, and it's not clear to me how/why PG let this happen. >I'm using 8.0.3. > >Here are the table references I just mentioned: > >Table "bookmark": > id SERIAL > CONSTRAINT pk_bookmark_id PRIMARY KEY > > Table "url": > url_id INTEGER > CONSTRAINT fk_bookmark_id REFERENCES bookmark(id) > > > Your DDL doesn't say : "B references U", but the contrary : "U references B". So it's perfectly right that somes tuples in B are not referenced by tuples in U. Please correct your constraints. >Problem #1: Strange that PG allowed this to happen. Maybe my DDL above allows this to happen and needs to be tightened? I thought the above would ensure referential integrity, but maybe I need to specify something else? > >Problem #2: I'd like to find all rows in B that point to non-existent rows in U. I can do it with the following sub-select, I believe, but it's rather inefficient (EXPLAIN shows both tables would be sequentially scanned): > > SELECT * FROM bookmark WHERE id NOT IN (SELECT b.id FROM bookmark b, url u WHERE b.url_id=u.id); > >Is there a more efficient way to get the rows from "bookmark"? > >Thanks, >Otis > > >---------------------------(end of broadcast)--------------------------- >TIP 6: explain analyze is your friend > > > I think, for that one Scott's answer is OK You could also try SELECT * FROM url U WHERE NOT EXISTS(SELECT * FROM bookmark B WHERE B.url-id=U.id) and see wich one is faster