X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id C200E52AAC for ; Sun, 6 Mar 2005 19:26:46 +0000 (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 40755-05 for ; Sun, 6 Mar 2005 19:26:41 +0000 (GMT) Received: from boutiquenumerique.com (boutiquenumerique.com [82.67.9.10]) by svr1.postgresql.org (Postfix) with ESMTP id DA19852A6B for ; Sun, 6 Mar 2005 19:26:40 +0000 (GMT) Received: (qmail 32508 invoked from network); 6 Mar 2005 20:27:27 +0100 Received: from unknown (HELO musicbox) (boutiquenumerique-lists@192.168.0.2) by boutiquenumerique.com with SMTP; 6 Mar 2005 20:27:27 +0100 To: "Stefan Weiss" , "Bruno Wolff III" Cc: pgsql-sql@postgresql.org Subject: Re: Links between rows in a table References: <422A8A26.1070704@foo.at> <20050306174201.GA19019@wolff.to> <422B4B9A.8020606@foo.at> Message-ID: Date: Sun, 06 Mar 2005 20:26:50 +0100 From: PFC Organization: =?iso-8859-15?Q?La_Boutique_Num=E9rique?= Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In-Reply-To: <422B4B9A.8020606@foo.at> User-Agent: Opera M2/7.54u1 (Linux, build 892) X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.004 tagged_above=0 required=5 tests=AWL X-Spam-Level: X-Archive-Number: 200503/86 X-Sequence-Number: 20565 >> It would probably be better to always have either both or neither of >> the symmetric relationships in the table. You could make a set of >> triggers >> to enforce this. Because your relation is symmetric, you should not name them "user" and "friend". The duplication is useless if you add a constraint : see this create table friendship ( user_id_1 integer references ... on delete cascade, user_id_2 integer references ... on delete cascade, CHECK( user_id_1 < user_id_2 ) ); user_id_1 < user_id_2 means : - a user can't be his own friend - only one row per friend - when you want to know if A is friend of B, no need to make two selects, just select where user_id_1 = min(user_id_A, user_id_B) AND user_id_2 = max(user_id_A, user_id_B) To get the list of friends for a user, you still need the union, but that is no real problem. Making two queries will be marginally slower than one query on a bigger table, but youu save precious cache space, so in the end it could be faster.