2011-02-23 38 views
5

tôi tiếp tục nhận được:Tại sao tôi không thể đặt ràng buộc duy nhất này trong PostgreSQL?

SQL error: ERROR: could not create unique index "service_import_checksum_key" DETAIL: Key (checksum)=() is duplicated.

Trong tuyên bố:

ALTER TABLE "public"."service_import" ADD CONSTRAINT "service_import_checksum_key" UNIQUE ("checksum")

Nhưng hạn chế này không phải là một trùng lặp. Không có ràng buộc nào khác như thế này ở bất cứ đâu trong toàn bộ cơ sở dữ liệu và tôi không biết tại sao trên trái đất nó cứ khăng khăng rằng nó là một bản sao. Tôi giả định đây là một số sắc thái lạ lùng của các postgres mà tôi đang thiếu ở đây.

Tôi đang làm gì sai?

Bảng bãi:

-- 
-- PostgreSQL database dump 
-- 

SET statement_timeout = 0; 
SET client_encoding = 'UTF8'; 
SET standard_conforming_strings = off; 
SET check_function_bodies = false; 
SET client_min_messages = warning; 
SET escape_string_warning = off; 

SET search_path = public, pg_catalog; 

SET default_tablespace = ''; 

SET default_with_oids = false; 

-- 
-- Name: service_import; Type: TABLE; Schema: public; Owner: cvs_tar; Tablespace: 
-- 

CREATE TABLE service_import (
    id integer NOT NULL, 
    name character varying(32) NOT NULL, 
    importfile character varying(64) NOT NULL, 
    reportfile character varying(64) NOT NULL, 
    percent smallint NOT NULL, 
    message text NOT NULL, 
    stamp timestamp without time zone DEFAULT now() NOT NULL, 
    complete smallint DEFAULT 0 NOT NULL, 
    checksum character varying(40) NOT NULL 
); 


ALTER TABLE public.service_import OWNER TO cvs_tar; 

-- 
-- Name: service_imports_id_seq; Type: SEQUENCE; Schema: public; Owner: cvs_tar 
-- 

CREATE SEQUENCE service_imports_id_seq 
    START WITH 1 
    INCREMENT BY 1 
    NO MINVALUE 
    NO MAXVALUE 
    CACHE 1; 


ALTER TABLE public.service_imports_id_seq OWNER TO cvs_tar; 

-- 
-- Name: service_imports_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: cvs_tar 
-- 

ALTER SEQUENCE service_imports_id_seq OWNED BY service_import.id; 


-- 
-- Name: id; Type: DEFAULT; Schema: public; Owner: cvs_tar 
-- 

ALTER TABLE service_import ALTER COLUMN id SET DEFAULT nextval('service_imports_id_seq'::regclass); 


-- 
-- Name: service_import_name_key; Type: CONSTRAINT; Schema: public; Owner: cvs_tar; Tablespace: 
-- 

ALTER TABLE ONLY service_import 
    ADD CONSTRAINT service_import_name_key UNIQUE (name); 


-- 
-- Name: service_import_pkey; Type: CONSTRAINT; Schema: public; Owner: cvs_tar; Tablespace: 
-- 

ALTER TABLE ONLY service_import 
    ADD CONSTRAINT service_import_pkey PRIMARY KEY (id); 


-- 
-- Name: service_import_complete_idx; Type: INDEX; Schema: public; Owner: cvs_tar; Tablespace: 
-- 

CREATE INDEX service_import_complete_idx ON service_import USING btree (complete); 


-- 
-- Name: service_import_stamp_idx; Type: INDEX; Schema: public; Owner: cvs_tar; Tablespace: 
-- 

CREATE INDEX service_import_stamp_idx ON service_import USING btree (stamp); 


-- 
-- PostgreSQL database dump complete 
-- 
+0

Bạn có thể hiển thị cho chúng tôi 'TẠO TẠO' hoàn chỉnh hoặc cung cấp mô tả khác về bảng không? Ngoài ra, thay vào đó, 'CREATE UNIQUE INDEX' có hoạt động không? – Charles

Trả lời

14

đọc được thông báo lỗi một lần nữa:

SQL error: ERROR: could not create unique index "service_import_checksum_key" DETAIL: Key (checksum)=() is duplicated.

Hình như nó đang nói với bạn rằng có những giá trị nhân bản trong cột checksum và bạn đang cố gắng để thực thi độc đáo trên cột đó với ràng buộc của bạn. Ràng buộc không trùng lặp, dữ liệu có bản sao.

Ngoài ra, phần "()" biểu thị rằng bạn có nhiều chuỗi trống trong cột checksum. Ràng buộc duy nhất cho phép nhiều giá trị NULL (kể từ NULL = NULLNULL không đúng) nhưng các chuỗi trống không phải là NULL.

Một ví dụ để làm rõ những gì đang xảy ra:

=> CREATE TABLE x (s VARCHAR NULL); 
CREATE TABLE 
=> INSERT INTO x (s) VALUES (''), ('a'), (''); 
INSERT 0 3 
=> ALTER TABLE x ADD CONSTRAINT ux UNIQUE(s); 
NOTICE: ALTER TABLE/ADD UNIQUE will create implicit index "ux" for table "x" 
ERROR: could not create unique index "ux" 
DETAIL: Key (s)=() is duplicated. 
=> delete from x where s=''; 
DELETE 2 
=> INSERT INTO x (s) VALUES ('a'); 
INSERT 0 1 
=> ALTER TABLE x ADD CONSTRAINT ux UNIQUE(s); 
NOTICE: ALTER TABLE/ADD UNIQUE will create implicit index "ux" for table "x" 
ERROR: could not create unique index "ux" 
DETAIL: Key (s)=(a) is duplicated. 

Đặc biệt, lưu ý những gì LỖICHI TIẾT đang nói và so sánh với các BIG.

+1

Đây là một ví dụ điển hình về sự cần thiết cho một ràng buộc kiểm tra bổ sung để ngăn chặn các nhà phát triển khỏi gian lận. Trường là NOT NULL nhưng là một chuỗi không được kiểm tra, vì vậy chúng đặt chuỗi rỗng để phá vỡ ràng buộc NOT NULL. Vương quốc của tôi cho một bổ sung cho các tiêu chuẩn SQL một loại chuỗi mà không cho phép "rỗng" chuỗi (của bất kỳ chiều dài). –

+1

@Matthew Wood: Tôi muốn sử dụng ràng buộc CHECK rõ ràng để đảm bảo rằng tổng kiểm tra có độ dài mong muốn chính xác (không nhiều hơn, không ít hơn) và chỉ chứa các ký tự hợp lệ cho tổng kiểm tra; checksum có lẽ là một giá trị hex có kích thước cố định và các nhà phát triển có thể không-pad nó nếu cần thiết. Chúng tôi sẽ để lại toàn bộ "chuỗi rỗng là NULL vì! Empty_string là true và ORM của tôi quá ngu ngốc để nói sự khác biệt" ngu ngốc cho một ngày khác :) Tôi không có DBA nhưng tôi biết rằng '' và NULL là những thứ khác nhau ngay cả bên ngoài cơ sở dữ liệu. –

+0

Về: "Các ràng buộc duy nhất cho phép nhiều giá trị NULL (vì NULL = NULL là sai) nhưng các chuỗi rỗng không phải là NULL." DING! Đóng đinh nó. Tất cả đều cố định. Điều ngu ngốc là tự động điền vào các chuỗi rỗng khi tôi tạo cột và sau đó từ đó thêm chỉ mục là không thể. –

Các vấn đề liên quan