2010-08-17 2 views
5

У меня есть таблица с индексом UNIQUE с 12 столбцами. \d sales показывает sales_uq UNIQUE, btree (a1, a2, a3, ... a12).Индекс PostgreSQL UNIQUE не уникален?

я следующий запрос:

SELECT a1, a2, a3, ... a12 FROM sales GROUP BY a1, a2, a3, ... a12 HAVING count(1) > 1; 

и я получаю кучу результатов. Как это возможно ?! Возможно ли, что индекс есть, но каким-то образом отключен? Или может возникнуть проблема с NULL? Или с номерами с плавающей запятой (два столбца индекса имеют тип double precision)?

ответ

11

потому что два NULL не сравниваются как равные, они играют в забавные игры с УНИКАЛЬНЫМИ ограничениями.

См последний абзац UNIQUE ограничений в PostgreSQL documentation:

В общем, уникальное ограничение нарушается, когда есть два или более строки в таблице, где значения все столбцы, включенные в пределе равны. Однако в этом сравнении два нулевых значения не считаются равными . Это означает, что даже в наличие единственного ограничения позволяет хранить повторяющиеся строки , содержащие нулевое значение, по меньшей мере, одного из ограниченных столбцов.

+1

Черт, это отстой. Я знал, что NULL не равен NULL, но по какой-то причине я ожидал, что он будет отличаться от индекса. :) – ibz

+0

@ionut bizau - конечно, настоящее удовольствие - то, что для целей GROUPing NULL группируются вместе. И, как указано в документации, некоторые другие серверы (например, SQL Server) реализуют ограничения UNIQUE, разрешая только один NULL (хотя это нарушает спецификацию ANSI SQL) –

2

A double is inexact, вот почему это может произойти. Используйте точный тип данных, и у вас не будет таких проблем.

+0

Хотя это не решает мою проблему, это действительно хороший момент. Я буду рассматривать изменение базы данных для использования NUMERIC. Благодарю. – ibz

+0

Не было бы, например, 45.454545454 всегда приводить к тому же неточному значению, что привело бы к тому же неточному числу, вызывающему одинаковые столбцы строк? Или вы говорите, что 45.454545454 приведет к 45.455, а иногда 45.454? Конечно, цифры, которые я использую, предназначены только для обсуждения. – Kuberchaun

Смежные вопросы