2013-07-18 1 views
1

내 문제의 본질에 삶은 아래로 DATETIME 필드와 MySQL 테이블 (InnoDB) 및 시간, 같은 날짜를 허용하지 않는 중복 검사를 구현해야합니다. 한 번 이상 사용하십시오 (예 : 2013-07-18 13 : xx : xx의 행 하나).MySQL과 고급 고유 constrant

내 첫 번째 질문은 그렇다면 MySQL 데이터베이스 자체에서 이것을 시행 할 방법이 있다면?

그렇지 않으면 내 접근 방식의 라인을 따라 다음과 같습니다

  1. 잠금을 모두 읽고 기록합니다 (
  2. 내가 새 행을 삽입 할 수 있습니다 확인하기 위해 SELECT 쿼리를 확인 방지하기 위해 테이블 ​​
  3. 다시

난 정말이 솔루션 싫어하는 테이블 잠금을 해제 삽입 -이 작업을 수행하는 방법에 대한 제안을 withou 테이블을 잠그지 않아도 될 것입니다.

+0

날짜 및 시간 구성 요소를 다른 열에 개별적으로 저장하고이를 기반으로 고유 제한 조건을 만드시겠습니까? 당신은 시간 부분과 쌍을 이루는 DATE 부분 만 필요합니다. 전체 datetime을 1 열로, 날짜 부분을 다른 부분으로, 시간 구성 요소를 3 열로 저장해야합니다. 고유 한 키 (날짜, 시간)를 사용하면 필요한 것을 제공합니다. –

+0

@ NB : datetime 열이 항상 다른 두 열과 일치하도록하려면 트리거가 필요합니다. –

+0

@ MikeSherrill'Catcall '그건 의미가 없습니다. 미안 해요. 정교하게 신경 쓰면 그렇게하십시오. –

답변

1

MySQL에서이를 수행하는 간단하고 선언적인 방법은 없습니다. 그러나 섀도 잉 열을 만들고 트리거를 사용하여 데이터를 일관성있게 유지할 수 있습니다. 여기서는 "ts"(아래)가 유효한 시간 소인이 될 수 있지만 시간당 하나의 시간 만 필요하다고 가정합니다.

create table test (
    ts datetime not null, 
    ts_uniq char(13) not null, 
    unique (ts_uniq) 
); 

"ts_uniq"열은 음영 열입니다. '2013-01-01 08'과 같은 문자열이 포함됩니다.

create trigger bef_ins_test 
before insert on test 
for each row 
set new.ts_uniq = date_format(new.ts, '%Y-%m-%d %H'); 

업데이트 전에 실행해야하는 유사한 트리거가 필요합니다.

create trigger bef_upd_test 
before update on test 
for each row 
set new.ts_uniq = date_format(new.ts, '%Y-%m-%d %H'); 

"ts"에 대한 값을 삽입하면 섀도 잉 열이 자동으로 올바르게 설정됩니다. 약간 다른 값을 삽입하려고

insert into test (ts) values ('2013-01-01 08:35:33'); 
select * from test; 

ts     ts_uniq 
-- 
2013-01-01 08:35:33 2013-01-01 08 

오류 코드 1062 (항목 중복) 상승, 제대로 실패합니다. 기존 타임 스탬프를 업데이트하는 경우

insert into test (ts) values ('2013-01-01 08:47:13'); 

는 BEFORE UPDATE 트리거는 "ts_uniq"일관성있는 열을 유지합니다. 오류가 발생하지 않겠지 만 어느 행을 변경하지 않습니다 "ts_uniq"독립적으로 업데이트하려고

update test 
set ts = '2013-01-01 17:42:42'; 

select * from test; 

ts     ts_uniq 
-- 
2013-01-01 17:42:42 2013-01-01 17 

.

update test 
set ts_uniq = '2013-12-31 18'; 

select * from test; 

ts     ts_uniq 
-- 
2013-01-01 17:42:42 2013-01-01 17