수 CURRENT_TIMESTAMP
A와 사용 PRIMARY KEY
?
둘 이상의 다른 INSERT가 동일 할 가능성이 CURRENT_TIMESTAMP
있습니까?
수 CURRENT_TIMESTAMP
A와 사용 PRIMARY KEY
?
둘 이상의 다른 INSERT가 동일 할 가능성이 CURRENT_TIMESTAMP
있습니까?
답변:
당으로 문서 ,의 정밀도는 CURRENT_TIMESTAMP
마이크로입니다. 따라서 충돌 확률은 낮지 만 가능합니다.
이제 아주 드물게 발생하고 데이터베이스 오류 가 발생하는 버그를 상상해보십시오 . 디버깅하기가 얼마나 어렵습니까? 적어도 결정론적인 버그보다 훨씬 나쁜 버그입니다.
더 넓은 맥락 : 아마도 시퀀스에 이러한 작은 뉘앙스를 피하고 싶을 것입니다. 이것은 MySQL에 익숙하다면 특히 성가시다.
또한 트랜잭션 (대부분의 웹 프레임 워크, 특히 Java 프레임 워크)을 사용하는 경우 트랜잭션 내에서 타임 스탬프가 동일합니다! 데모 :
postgres=# begin;
BEGIN
postgres=# select current_timestamp;
current_timestamp
-------------------------------
2018-08-06 02:41:42.472163+02
(1 Zeile)
postgres=# select current_timestamp;
current_timestamp
-------------------------------
2018-08-06 02:41:42.472163+02
(1 Zeile)
만나요? 두 가지 선택, 정확히 같은 결과. 나는 너무 빨리 입력하지 않습니다. ;-)
-
시퀀스를 사용하지 않고 쉽게 ID를 원하면 레코드의 실제 식별자에서 일부 해시 값을 생성하십시오. 예를 들어, 데이터베이스에 사람이 있고 생년월일, 어머니의 성함 및 실명이 고유하게 식별된다는 것을 알고 있다면
md5(mother_name || '-' || given_name || '-' birthday);
id로. 그 외에도 CreationDate
테이블을 색인화 한 후에 열을 사용할 수 있지만 키 (ID)는 아닙니다.
시는 일반적으로,이다 매우 좋은 연습 이 가능한 한, 당신의 DB 그렇게 결정하게. 즉 , 동일한 작업이 DB에서 정확히 동일한 변경 사항을 생성해야합니다 . 타임 스탬프 기반 ID가이 중요한 기능에 실패합니다. 디버그하거나 시뮬레이션하려면 어떻게해야합니까? 작업을 재생하면 동일한 ID로 다른 ID로 생성됩니다 ... 실제로 따르기가 어렵지 않으며 많은 작업 시간이 필요합니다.
Ps2 앞으로 코드를 확인하는 사람은 위의 이유로 타임 스탬프 생성 ID를 보는 가장 좋은 의견을 얻지 못할 것입니다.
INSERT
여러 행 을 수행하면 모두 동일 current_timestamp
합니다. 그리고 당신은 방아쇠가 있습니다 ...
CURRENT_TIMESTAMP가 두 개의 후속 INSERT (또는 여러 행이있는 단일 INSERT)에 대해 동일한 두 개의 값을 제공 할 수 있기 때문에 실제로는 아닙니다.
대신 시간 기반 UUID를 사용하십시오 ( uuid_generate_v1mc ()) .
엄밀히 말하면 : 아니요CURRENT_TIMESTAMP
. 함수 이기 때문에 하나 이상의 테이블 열만PRIMARY KEY
제약 조건을 형성 할 수 있습니다 .
PRIMARY KEY
기본값으로 열에 제약 조건 을 만들려는 CURRENT_TIMESTAMP
경우 대답은 다음과 같습니다. 예, 가능 합니다. 아들의 머리에서 사과를 쏘지 못하게하는 것처럼 아무것도하지 않습니다. 질문의 목적을 정의하지 않으면 질문은 여전히 타당하지 않습니다. 열과 테이블에는 어떤 종류의 데이터가 있어야합니까? 어떤 규칙을 구현하려고합니까?
일반적으로 동일한 트랜잭션 (트랜잭션의 시작 시간)에 대해 동일한 값을 반환 CURRENT_TIMESTAMP
하는 STABLE
함수 이므로 아이디어는 중복 키 오류가 발생합니다 . 동일한 트랜잭션의 여러 INSERT는 이미 설명 된 다른 답변과 마찬가지로 충돌 할 수밖에 없습니다. 매뉴얼 :
이러한 함수는 현재 트랜잭션의 시작 시간을 반환하므로 해당 값은 트랜잭션 중에 변경되지 않습니다. 이는 하나의 기능으로 간주됩니다. 의도는 단일 트랜잭션이 "현재"시간에 대해 일관된 개념을 갖도록하여 동일한 트랜잭션 내에서 여러 수정이 동일한 타임 스탬프를 갖도록하는 것입니다.
Postgres 타임 스탬프는 최대 6 개의 소수 자릿수 (마이크로 초 해상도)를 나타내는 8 바이트 정수로 구현됩니다.
경우 (이름이 뭔가를 당신이 마이크로 당 하나 이하의 행을 보유하도록되어 테이블을 구축하고 해당 조건이 변화하지 않을 sensor_reading_per_microsecond
), 다음 이 적합 할 수 있습니다. 중복 행이되는 가정 중복 키 위반 오류가 발생 할 수 있습니다. 그러나 이것은 이국적인 예외입니다. 그리고 데이터 유형 timestamptz
(not timestamp
)이 바람직 할 것입니다. 보다:
대신 여전히 대리 직렬 기본 키를 사용하고 싶습니다. UNIQUE
타임 스탬프 열에 제약 조건을 추가하십시오 . RDBMS의 구현 세부 사항에 의존하지 않고 가능한 복잡성 감소.
sensor_reading_per_microsecond
각 판독 값의 타이밍이 이전 판독 값과 완벽하게 동기화되었다고 절대 보장 할 수없는 경우 에도 충돌 할 수 있습니다. 1 마이크로 초 미만의 편차 (종종 불가능하지는 않음)는 구성표를 위반합니다. 일반적으로 나는 여전히 이것을 완전히 피할 것입니다. (당신이 지적했듯이, 그런 경우, 결과적인 충돌이 바람직 할 수 있습니다!)