programing

MariaDB 10.0, innodb: 조건부 고유 제약 조건?

elecom 2023. 9. 5. 19:41
반응형

MariaDB 10.0, innodb: 조건부 고유 제약 조건?

단순화된 스키마:

사용자: ID(int), 이름(문자열), allow_mails_name(int)

allow_proxy_name은 true의 경우 1이고 false의 경우 0입니다.

새 레코드의 이름 필드가 중복되지 않는 경우에만 새 레코드가 삽입되지 않도록 하고 싶습니다. allow_backets_name == 1. 따라서 다음 표가 있으면 다음과 같습니다.

id  name  allow_duplicate_name
1   jack  1
2   jack  1
3   ryan  1
4   jack  1

그러면 다음 문장이 성공할 것입니다.

INSERT INTO people (name, allow_duplicate_name)
VALUES ('jack', 1);

그러나 이 문장은 실패해야 합니다.

INSERT INTO people (name, allow_duplicate_name)
VALUES ('jack', 0);

근본적인 문제는 두 개의 동시 트랜잭션이 모두 중복 여부를 확인하고 중복되지 않는지 확인한 다음 같은 이름의 새 레코드를 삽입하고 allow_message_name=0을 사용하는 경합 조건을 가지고 있다는 것입니다.

제가 생각한 또 다른 아이디어는 각 트랜잭션을 커밋하기 전에 중복 항목이 추가되었는지 확인할 때 READ UNCommitted를 사용하고 대신 롤백하여 애플리케이션이 다른 작업(예: 새 이름 선택)을 수행하도록 하는 것입니다. 왜냐하면 우리는 용인할 수 있기 때문입니다(이상적인 것보다 훨씬 적지만 처리할 수 있습니다...).ch 트랜잭션은 다른 트랜잭션을 확인한 후 자동으로 롤백되지만 allow_download_name=0으로 중복 이름을 설정하는 삽입/업데이트는 절대 허용할 수 없습니다.

저장 프로시저는 작업하기에 엄청난 고통이 따르는 것으로 알고 있습니다. 하지만 저장 프로시저가 이 문제를 해결하는 유일한 방법일 수도 있습니다.

원하는 작업을 거의 수행할 수 있지만 변수의 이름을 변경하고 싶을 것입니다.핵심 아이디어는 고유 인덱스가 허용하는NULL중복할 값입니다.따라서 "allow_duplicate_name"이NULL그러면 당신은 복제품을 얻을 수 있습니다.

필드 이름을 다음과 같은 이름으로 변경하는 것이 좋습니다.DuplicatesNotAllowed그런 다음 인덱스를 만듭니다.

 create unique index idx_people_name_duplicatesnotallowed on people(name, duplciatesnotallowed);

다음과 같이 값을 삽입할 수 있습니다.

INSERT INTO people (name, duplciatesnotallowed)
    VALUES ('jack', NULL);

이것은 성공할 것입니다.

INSERT INTO people (name, allow_duplicate_name)
    VALUES ('jack', 1);

이 작업은 두 번째 실행 시 실패합니다.그러나 기존 행의 필드를 업데이트하면 실패합니다.그게 당신의 요구에 부합하는지 잘 모르겠습니다.

언급URL : https://stackoverflow.com/questions/25516988/mariadb-10-0-innodb-conditional-unique-constraint

반응형