Postgres는 레코드의 삽입 순서를 유지합니까?


19

예를 들어 레코드 ID를 반환하는 쿼리를 사용하는 경우

INSERT INTO projects(name)
VALUES (name1), (name2), (name3) returning id;

어느 생산물을 생산 :

1
2
3

이 ID가 삽입 된 해당 값을 가리 킵니까?

1 -> name1
2 -> name2
3 -> name3

4
실제 답변은 제쳐두고 (아니오라고 생각합니다) 쿼리에서 지정한 것과 다른 순서에 의존해서는 안됩니다.
dezso

답변:


17

이 간단한 경우에 대한 대답은 입니다. VALUES표현식 에서 제공된 순서대로 행이 삽입됩니다 . 그리고 id열이 serial유형 인 경우 기본 순서의 값이 순서대로 페치됩니다.

그러나 이것은 구현 세부 사항이며 보장은 없습니다. 특히, 순서는 WHERE조건이나 조인이 있는 더 복잡한 쿼리에서 반드시 유지되지는 않습니다 .

동시에 같은 테이블에 동시 트랜잭션을 쓰는 경우 간격이나 다른 행이 혼합 될 수 있습니다. 가능하지는 않지만 가능합니다.

데이터베이스 테이블에는 "자연"순서가 없습니다. 실제 열 순서 ( 시스템 열에ctid 반영됨 )는 처음에 삽입 된 순서와 일치하지만 언제든지 변경 될 수 있습니다. UPDATE, DELETE, VACUUM및 다른 명령 행의 물리적 순서를 변경할 수 있습니다. 그러나 생성 된 값 id은 안정적이며 어떤 식으로도 연결되지 않습니다.


Sergey는 첫 번째 행이 항상 id = 1, 두 번째 id = 2 및 세 번째 id = 3-실제 "순서"또는 행이 아닌지 여부에 대한 질문을 더 많이 언급했다고 생각합니다.
a_horse_with_no_name

@a_horse_with_no_name : 대답하기 위해 : 그것은 갓 생성의 경우가 될 것이다 serial열 - 이상적으로 동일한 트랜잭션에서.
Erwin Brandstetter

질문이 "name3의 ID가 항상 name1의 것보다 큽니까?"라면 항상 맞습니까? (두 번째 단락과 관련하여)
lulalala

@lulalala : 조인 및 WHERE조건이있는 보다 복잡한 쿼리에는 해당되지 않습니다 . WHERE행 순서를 변경하는 일반 조건은 생각할 수 없지만 조인은 확실히 그렇게 할 수 있습니다.
Erwin Brandstetter

3

어떤 경우에는 Erwin Brandstetter의 답변 이 정확하지 않을 수 있습니다.

우리는 짓을했는지 INSERT INTO ... SELECT bar,baz FROM foo ORDER BY bar 우리는 볼 SELECT ctid,* FROM foo 테이블에있는 행의 실제 순서가 정확히 삽입 순서와 일치하지 않음을 보여줍니다, 그것은 조금을 스크램블 보인다. 테이블에는 데이터 크기가 매우 큰 jsonb 열이 있습니다. 삽입 중에 실험적으로 jsonb 데이터를 절단하면 삽입 순서가 정확했습니다.


3
으로 @Erwin 지적첫 문장 , 그는 단지 "예"라는 질문에 언급 된 특정 단일 인스턴스에서 말하는. 으로 @deszo 그의 주석에서 말했다 , 이제까지 "삽입"순서에 의존하지; 어떤 목적 으로든 해당 순서에 의존하는 경우 항상 select 문에서 순서를 지정해야합니다.
Max Vernon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.