2012-05-28 3 views
2

여기에 문제가 있습니다.mysql은 여러 필드가있는 중복 레코드를 방지합니다

id : int(11) not null primary key 
name : varchar(255) not null 
status : enum('ACTIVE','DELETED') 

참고 : 나는 다음과 같은 스키마의 테이블을 가지고있는 기록은 '소프트 삭제'이며, 우리가 '삭제됨'에 상태를 플래그.

문제는 db의 기존 레코드가 '삭제됨'상태가 아닌 한 2 명의 스레드를 통해 동일한 이름의 항목을 만들 수 없기를 바라는 것입니다. 이 작업을 수행하는 방법은 무엇입니까?

우리는 'DELETED'에 같은 이름의 항목이 있고 삭제하고자하는 영역이 'ACTIVE'이므로 오류가 발생합니다. 영역을 'DELETED'플래그로 지정하십시오.

답변

3

데이터에 deleted_at 필드를 추가하는 것은 어떻습니까? 그런 다음 name + status + deleted_at에 고유 키를 사용할 수 있습니다. status = ACTIVE 인 경우 deleted_at에 대해 하나의 값만있을 수 있으므로 고유성이 이름에만 적용됩니다. 선명도

편집 :

CREATE TABLE mytable (
    id int not null primary key, 
    name varchar(255) not null, 
    status enum('active','delete'), 
    deleted_at datetime not null default 0, 
    UNIQUE KEY one_active (name, status, deleted_at) 
); 

편집 # 2 : 실제로, 당신은 할 경우 deleted_at> 0 대신의 상태를 확인하기위한 코드 검사 = 삭제 한 후, 당신을 "삭제가 있는지 확인" 상태 필드가 필요하지 않습니다.

+0

그래, 좋은 생각이야! –

+0

@PaulBellora 안타깝게도 nullable로 설정할 수 없습니다. 그렇지 않으면 UNIQUE 인덱스가 예상대로 작동하지 않습니다. NOT NULL이어야하며 기본값은 레코드가 소프트 삭제되지 않았 음을 나타내는 0이어야합니다. 직접 해보십시오. deleted_at을 nullable로 설정하면 name = '아마도 유일', deleted_at = NULL로 원하는 수만큼 레코드를 생성 할 수 있습니다. –

+0

@ zi42 - 절대적으로 옳습니다. http://stackoverflow.com/a/429827/697449) - 의심해서 죄송합니다. +1 –

0

프로그래밍 방식으로 목표를 달성해야합니다. INSERT를 제한하기 위해 name + status ACTIVE가 존재하면 언어를 확인하십시오.

+0

mmm 시도해 보았습니다. 우리는 최대 절전 모드를 사용하고 있습니다. 여러 클라이언트가 저장 속도가 빠르면 중복 레코드가 db에 삽입되는 것을 방지 할 수 있습니다. – Solid

+0

죄송합니다. 로마인, 저 자신의 답변을 수정하려고했습니다! –

+0

동의합니다. 응용 프로그램 수준에서보다 복잡한 제약 조건을 수행해야합니다. Hibernate 인터셉터 나 DAO를 통해. 또한 독창성에 제약이 있다고 가정 할 때 애플리케이션 수준 잠금을 처리해야한다고 제안하는 것 같습니다. – yclian

관련 문제