Unix Technical Forum

Unique index with Null value in one field

This is a discussion on Unique index with Null value in one field within the Pgsql General forums, part of the PostgreSQL category; --> Hi, I need to define a Unique index on 3 non-PK fields (composite key) on my table in PostgreSQL ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > Pgsql General

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-09-2008, 06:22 AM
Hrishi Joshi
 
Posts: n/a
Default Unique index with Null value in one field

Hi,

I need to define a Unique index on 3 non-PK fields (composite key) on my
table in PostgreSQL 8.0.3.

The problem is, if any of those 3 fields is Null, PostgreSQL allows
duplicate rows to be inserted. While searching through archives, I found
more information about this.

But I need to know how can I make PostgreSQL throw error on attempt to
insert second record having same 3 field values, one of them being Null.


------------------------------------------------
myid | field1 | field2 | field3 | description
PK | <--- Unique Index ---> |
------------------------------------------------
100 | ABC | XYZ | <null> | Record 1 -> This is ok.
101 | ABC | XYZ | <null> | Record 2 -> * This should error!
------------------------------------------------

Fields {field1, field2, field3} have unique index on them and "myid" is
the primary key of my table.


Oracle 9i throws exception in such case, but PostgreSQL does not.


Thanks,
- Hrishi Joshi.



---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo@postgresql.org so that your
message can get through to the mailing list cleanly

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-09-2008, 06:22 AM
Tom Lane
 
Posts: n/a
Default Re: Unique index with Null value in one field

Hrishi Joshi <hjoshi@abcsinc.com> writes:
> I need to define a Unique index on 3 non-PK fields (composite key) on my
> table in PostgreSQL 8.0.3.


> The problem is, if any of those 3 fields is Null, PostgreSQL allows
> duplicate rows to be inserted.


That is the behavior defined by the SQL standard.

> But I need to know how can I make PostgreSQL throw error on attempt to
> insert second record having same 3 field values, one of them being Null.


You can't. Rethink your data representation, instead. You are misusing
NULL if you think that it represents something unique.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-09-2008, 06:22 AM
Stephan Szabo
 
Posts: n/a
Default Re: Unique index with Null value in one field


On Tue, 11 Oct 2005, Hrishi Joshi wrote:

> I need to define a Unique index on 3 non-PK fields (composite key) on my
> table in PostgreSQL 8.0.3.
>
> The problem is, if any of those 3 fields is Null, PostgreSQL allows
> duplicate rows to be inserted. While searching through archives, I found
> more information about this.
>
> But I need to know how can I make PostgreSQL throw error on attempt to
> insert second record having same 3 field values, one of them being Null.
>
>
> ------------------------------------------------
> myid | field1 | field2 | field3 | description
> PK | <--- Unique Index ---> |
> ------------------------------------------------
> 100 | ABC | XYZ | <null> | Record 1 -> This is ok.
> 101 | ABC | XYZ | <null> | Record 2 -> * This should error!
> ------------------------------------------------
>
> Fields {field1, field2, field3} have unique index on them and "myid" is
> the primary key of my table.
>
>
> Oracle 9i throws exception in such case, but PostgreSQL does not.


We're pretty sure that the standard UNIQUE constraint requires this
behavior and our unique index is the mechanism for checking that
constraint and so has the same behavior.

If there's a non-null value that you know can't be there, you might be
able to use a unique index on something like
(coalesce(field1, <v>)), (coalesce(field2,<v>)), (coalesce(field3,<v>))

Otherwise, you might be able to use a set of partial unique indexes for
the null cases. I'm not sure how many it would require, though.


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-09-2008, 06:23 AM
Jaime Casanova
 
Posts: n/a
Default Re: Unique index with Null value in one field

On 11 Oct 2005 17:36:59 -0500, Hrishi Joshi <hjoshi@abcsinc.com> wrote:
> Hi,
>
> I need to define a Unique index on 3 non-PK fields (composite key) on my
> table in PostgreSQL 8.0.3.
>
> The problem is, if any of those 3 fields is Null, PostgreSQL allows
> duplicate rows to be inserted. While searching through archives, I found
> more information about this.
>
> But I need to know how can I make PostgreSQL throw error on attempt to
> insert second record having same 3 field values, one of them being Null.
>
>
> ------------------------------------------------
> myid | field1 | field2 | field3 | description
> PK | <--- Unique Index ---> |
> ------------------------------------------------
> 100 | ABC | XYZ | <null> | Record 1 -> This is ok.
> 101 | ABC | XYZ | <null> | Record 2 -> * This should error!
> ------------------------------------------------
>
> Fields {field1, field2, field3} have unique index on them and "myid" is
> the primary key of my table.
>
>
> Oracle 9i throws exception in such case, but PostgreSQL does not.
>
>
> Thanks,
> - Hrishi Joshi.
>
>


maybe with a function and comparing yourself...

--
Atentamente,
Jaime Casanova
(DBA: DataBase Aniquilator

---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-09-2008, 06:34 AM
Chris Travers
 
Posts: n/a
Default Re: Unique index with Null value in one field

Hrishi Joshi wrote:

>Hi,
>
>I need to define a Unique index on 3 non-PK fields (composite key) on my
>table in PostgreSQL 8.0.3.
>
>The problem is, if any of those 3 fields is Null, PostgreSQL allows
>duplicate rows to be inserted. While searching through archives, I found
>more information about this.
>
>But I need to know how can I make PostgreSQL throw error on attempt to
>insert second record having same 3 field values, one of them being Null.
>
>
>------------------------------------------------
>myid | field1 | field2 | field3 | description
>PK | <--- Unique Index ---> |
>------------------------------------------------
>100 | ABC | XYZ | <null> | Record 1 -> This is ok.
>101 | ABC | XYZ | <null> | Record 2 -> * This should error!
>
>

Why? PostgreSQL knows that we cannot determine whether these records
are different or not. See the discussion on what NULL means...

IMO, people who use NULL to mean "not applicable" are misusing the
value. Not applicable should always be equal to not applicable, but it
is always unknown whether unknown is equal to another unknown. I would
suggest using a different table for that column if it is not always
applicable. The typical example is:

You have 500 employees. Some employees have salaries, some have wages.
Some people might:

create table employee(
employee_id serial,
ssn varchar not null,
....
wage numeric,
salary numeric
);

but here NULL could either mean "unknown" or "not applicable" so we
don't really know which is which and it can create data management issues.

In this case it is better to:

create table employee(
employee_id serial,
ssn varchar not null,
....
);
create table wage (
employee_id,
wage numeric
);
create table salary (
employee_id,
salary numeric
);

>------------------------------------------------
>
>Fields {field1, field2, field3} have unique index on them and "myid" is
>the primary key of my table.
>
>
>
>Oracle 9i throws exception in such case, but PostgreSQL does not.
>
>

You could use a custom trigger, or a custom function and a functional
index.... Or even an index on COALESCE...

But Oracle's handling of NULL's is broken, especially in string fields
(varchar, char, etc) because it wrongly assumes that an empty string and
NULL are equivalent. Search for prior discussions on this list....

Best Wishes,
Chris Travers
Metatron Technology Consulting

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 09:11 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com