고유성 제약 조건을 조건부로 적용할 수 있습니까?
내 데이터베이스에는 사용자 테이블이 있습니다.모든 활성 사용자는 고유한 사용자 이름을 가집니다.사용자를 비활성화하고 사용 중인 사용자 이름을 해제할 수 있지만 동일한 테이블에 보관하고 싶습니다.
고유성 제약 조건만 조건부로 적용할 수 있는 방법이 있습니까?
다음과 같은 열을 추가합니다.isactive
. 가 고유한 제약 조건을 만듭니다.(username, isactive)
.
그러면 활성 사용자 이름과 비활성 사용자 이름을 동시에 가질 수 있습니다.두 개의 활성 사용자 이름을 가질 수 없습니다.
비활성화된 이름을 여러 개 사용하려면NULL
의 가치를 위하여isactive
.NULL
값은 고유 인덱스에서 반복될 수 있습니다.
아니요, UNIECIAL 제약 조건은 "조건부"일 수 없습니다.
하나의 옵션은 다음을 설정하는 것입니다.username
열에서 NULL로 이동합니다.UNIUIC 제약 조건은 NULL 값을 가진 여러 행을 허용합니다.
당신은 그것을 당신이 전시하기 원하는 어떤 문자열로도 번역할 수 있습니다.응용 프로그램 또는 SQL에서
SELECT IFNULL(t.username,'USER DELETED') AS username
FROM mytable t
기록/보관 목적으로 이 행들을 유지하는 경우, 아마도 업데이트를 원하지 않을 것입니다.username
column. (값을 변경할 경우username
column(열) 그러면 다음 문장에서 이전 사용자 이름과 동일한 값의 행을 삽입할 수 있습니다.)
대신 테이블에 추가 열을 추가하여 "사용자 삭제" 조건을 나타낼 수 있습니다.예를 들어,
user_deleted TINYINT(1) UNSIGNED DEFAULT 0 COMMENT 'boolean'
당신은 이 컬럼을 확인하고 반환할 수 있습니다.'USER DELETED'
사용자 이름 열 대신 상수.user_deleted
부울이 설정됨:
SELECT IF(u.user_deleted,'USER DELETED',u.username) AS username
(논리적인 "사용자 삭제" 조건을 나타내려면 1 값을 사용합니다.)
이 접근 방식의 가장 큰 장점은username
열을 수정할 필요가 없습니다.username
value, UNIECIAL 제약 조건을 사용하면 사용자 이름이 중복된 새 행이 삽입되지 않습니다.
동일한 결과를 얻기 위한 다른 방법.질문에 실제로 필요하지 않을 수도 있습니다.참고로 말입니다.
- 삽입/업데이트 시 트리거 만들기
- 현재(NEW) 레코드 값으로 중복된 레코드가 있는지 확인합니다.
a. 중복 카운트를 통해 이를 확인하거나 동일한 값을 가진 다른 레코드를 확인할 수 있지만 기본 키가 다릅니다. - 발견된 경우 신호를 올려 오류를 던집니다.
조건이 복잡하여 고유성을 결정하는 경우 가장 적합합니다.또한 성능 비용도 고려해야 합니다.
견본
DELIMITER $$
CREATE TRIGGER `my_trigger` BEFORE INSERT/UPDATE
ON `usertable`
FOR EACH ROW BEGIN
IF EXISTS (SELECT 1 FROM usertable WHERE userid <> NEW.userid AND username = NEW.username AND isactive = 1) THEN
SELECT CONCAT(NEW.username, ' exists !') INTO @error_text;
SIGNAL SQLSTATE '45000' SET message_text = @error_text;
END IF;
END$$
DELIMITER ;
FORMER_NAME이라는 다른(고유하지 않은) 필드를 만들고 사용자가 비활성화되면 원래 이름을 해당 필드로 이동합니다.가능하지 않은 특별한 고유성 제약이 필요 없습니다.
아니요, 고유 인덱스(따라서 이름)가 있는 경우 중복을 가질 수 없습니다.각 레코드를 고유하게 만들기 위해 추가 열을 추가합니다.또는 값을 고유하게 변경합니다.
권장되지 않지만 예를 들어 "USER DELETED 2013/08/17:233805" 타임스탬프를 추가할 수 있습니다.
이것이 제가 비슷한 문제를 만났을 때의 해결책입니다.
열을 비활성으로 추가하므로 고유 키는 다음과 같습니다. (username, inactive)
inactive, inactive = 0은 사용자가 활성임을 의미하며 inactive > 0은 사용자가 활성임을 의미합니다.
사용자를 비활성화 할 때는 평소처럼 1개가 아닌 비활성 = user_id만 설정하면 됩니다!
이제 비활성 사용자에게는 중복된 사용자 이름을 허용하지만 활성 사용자에게는 고유한 사용자 이름만 허용합니다.
nullable 기능을 제공하는 생성된 열을 추가하여 @gordon-linoff 답변을 확장했습니다.나는 나중에 코드를 작성할 때 이 null 동작을 실수로 잊어버림으로써 혼란스럽지 않고 엉망이 되지 않는 읽고 쓸 수 있는 확실한 true 및 false 값을 가진 true not null active 열을 가지고 싶습니다.그래서 나는 특정 이름을 가진 열을 계산한 다음 제약 조건에 그 값을 사용하므로 nullable 고유의 active 동작을 얻지만 active 열을 내가 원하는 대로 사용할 수 있습니다.
isactive BOOL NOT NULL,
_isactive_constraint_key_ BOOL AS (CASE WHEN isactive IS true THEN true END),
CONSTRAINT active_user UNIQUE(username, _isactive_constraint_key)
언급URL : https://stackoverflow.com/questions/18293543/can-i-conditionally-enforce-a-uniqueness-constraint
'source' 카테고리의 다른 글
두 날짜의 차이를 어떻게 계산할 수 있습니까? (0) | 2023.11.05 |
---|---|
mysql feature- scaling (0) | 2023.11.05 |
내 html 페이지에 각도 변수 표시 (0) | 2023.10.31 |
할당 배열 VS 가변 길이 배열 (0) | 2023.10.31 |
부트스트랩 모달이 열린 상태에서 신체 내용의 스크롤 방지 방법 (0) | 2023.10.31 |