Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UQCLw-0002Mi-GN for pgsql-sql@arkaria.postgresql.org; Thu, 11 Apr 2013 07:55:28 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1UQCLv-0002i6-Rs for pgsql-sql@arkaria.postgresql.org; Thu, 11 Apr 2013 07:55:27 +0000 Received: from makus.postgresql.org ([2001:4800:7903:4::125]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UQCLu-0002i0-Ra for pgsql-sql@postgresql.org; Thu, 11 Apr 2013 07:55:27 +0000 Received: from mail-ee0-f53.google.com ([74.125.83.53]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UQCLr-0003Me-Eu for pgsql-sql@postgresql.org; Thu, 11 Apr 2013 07:55:25 +0000 Received: by mail-ee0-f53.google.com with SMTP id c13so621084eek.40 for ; Thu, 11 Apr 2013 00:55:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:subject:date:message-id:user-agent:mime-version :content-transfer-encoding:content-type; bh=MYQAoJjAOVtnpFZtz2WbD1EO0suJAvXPugxrRYgC+pY=; b=SE2T9LHPl2JxGKjvpb5yyDolTdeRrhZA3OpVqnYuNNS/7XDGg6SwF4v3y6lTDzsnjx /3DwhwBHBf1ck/NpHc0nYqeYI6yT5WEzHdeUUmjH5YnjXfdfq9TVUjXre3c9G0Mf8R8x wP5OqnBwxv5V43zblQRdtZpGzwrFVzYmAiF2hxtYC1TK46N3pil+FjGM1QC1kg6tRg90 SncDsMw1ML0sDdgMB2IAnHXctM7euDT6KjLQYiYfaMin9tui7f9rVp1e9f/K2RVD2tyZ RL1Ew/T0OuWXRVgzN8xlFNQO6UvXz7+wbAEVELqp4SwhJVCrT7iLYUQSdUXoVM+Wof+r WpbA== X-Received: by 10.14.182.137 with SMTP id o9mr14401250eem.13.1365666922042; Thu, 11 Apr 2013 00:55:22 -0700 (PDT) Received: from hek506.localnet ([2001:7c0:409:274:213:77ff:febe:8a56]) by mx.google.com with ESMTPS id u44sm4144359eel.7.2013.04.11.00.55.21 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 11 Apr 2013 00:55:21 -0700 (PDT) From: Matthias Nagel To: pgsql-sql@postgresql.org Subject: Restrict FOREIGN KEY to a part of the referenced table Date: Thu, 11 Apr 2013 09:55:20 +0200 Message-ID: <3358559.iSkkklqms2@hek506> User-Agent: KMail/4.10.1 (Linux/3.7.10-gentoo; KDE/4.10.1; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="utf-8" X-Pg-Spam-Score: -2.7 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org Hello, is there any best practice method how to create a foreign key that only allows values from those rows in the referenced table that fulfill an additional condition? First I present two pseudo solutions to clarify what I would like to do. They are no real solutions, because they are neither SQL standard nor postgresql compliant. The third solution actually works, but I do not like it for reason I will explain later: CREATE TABLE parent ( id SERIAL, discriminator INT NOT NULL, attribute1 VARCHAR, ... ); Pseudo solution 1 (with a hard-coded value): CREATE TABLE child ( id SERIAL NOT NULL, parent_id INT NOT NULL, attribute2 VARCHAR, ..., FOREIGN KEY ( parent_id, 42 ) REFERENCES parent ( id, discriminator ) ); Pseudo solution 2 (with a nested SELECT statement): CREATE TABLE child ( id SERIAL NOT NULL, parent_id INT NOT NULL, attribute2 VARCHAR, ..., FOREIGN KEY ( parent_id ) REFERENCES ( SELECT * FROM parent WHERE discriminator = 42 ) ( id ) ); Working solution: CREATE TABLE child ( id SERIAL NOT NULL, parent_id INT NOT NULL, parent_discriminator INT NOT NULL DEFAULT 42, attribute2 VARCHAR, ..., FOREIGN KEY ( parent_id, parent_discriminator ) REFERENCES parent ( id, discriminator ), CHECK ( parent_discriminator = 42 ) ); The third solution work, but I do not like it, because it adds an extra column to the table that always contains a constant value for the sole purpose to be able to use this column in the FOREIGN KEY clause. On the one hand this is a waste of memory and on the other hand it is not immediately obvious to an outside person what the purpose of this extra column and CHECK clause is. I am convinced that any administrator who follows me might get into problems to understand what this is supposed to be. I would like to have a more self-explanatory solution like 1 or 2. I wonder if there is something better. Best regards, Matthias ---------------------------------------------------------------------- Matthias Nagel Willy-Andreas-Allee 1, Zimmer 506 76131 Karlsruhe Telefon: +49-721-8695-1506 Mobil: +49-151-15998774 e-Mail: matthias.h.nagel@gmail.com ICQ: 499797758 Skype: nagmat84 -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql