PostgreSQL : 생성 된 열


16

PostgreSQL은 생성 된 열을 지원합니까 ? 가상 열 이라고도합니다 . 나는 열에 대해 이야기하고 있지 않다 .IDENTITY

이 놀라운 기능에 대한 정보를 찾을 수 없지만 SQL Server와 최신 버전의 MariaDB 및 MySQL에서 사용할 수 있음을 알고 있습니다.

이 기능은 SQL : 2003 표준에 언급되어 있으며 2006 년경 PostgreSQL 포럼에 대한 토론이 있었지만 그 문제에 대해 중요한 것을 찾을 수는 없습니다.

SO에 대한 토론이 있지만 지금은 오래되어 오래되었을 수도 있습니다.


2
SO에 대한 2012 년의 관련 답변은 도움이 될 수 있습니다. stackoverflow.com/questions/11165450/… 여전히 유효합니다.
Erwin Brandstetter

@ErwinBrandstetter 죄송합니다이 의견을 놓쳤습니다. 유용한 트릭입니다. 감사.
Manngo

답변:


17

이것이 원하는 것인지 확실하지 않지만 속성 표기법 row.full_name과 함수 표기법 full_name(row)은 postgresql에서 동일합니다.

그것은 당신이 테이블을 가지고 의미

CREATE TABLE people (
  first_name text,
  last_name text
);

그리고 기능 :

CREATE FUNCTION full_name(people) RETURNS text AS $$
  SELECT $1.first_name || ' ' || $1.last_name;
$$ LANGUAGE SQL;

다음과 같이 호출하십시오.

select full_name from people

그게 필요한가요?

작업 속도를 높이려면 식 색인을 만들 수 있습니다.

CREATE INDEX people_full_name_idx ON people
USING GIN (to_tsvector('english', full_name(people)));

또는 모든 것을 구체화 된보기로 저장하십시오.

여기에서 가져온 예 : http://bernardoamc.github.io/sql/2015/05/11/postgres-virtual-columns/


2
이것이 정답입니다. 예를 들어 Postgrest 가이 동작을 "계산 열"이라고 하는 방법을 참조하십시오 .
fiatjaf

오타, 선택- select people.full_name from people또는 선택해야 select full_name(people) from people합니까?
Barguast

아니 그런 식으로 작동합니다. "select people.full_name from people"의 접두어는 일반 SQL에서와 같이 생략 할 수 있습니다.
Fabian Zeindl

내가 포기한지 얼마 안되어이 답을 놓쳤다. 제안 해 주셔서 감사합니다.
Manngo

1
그런 다음 수락 된 답변을 변경할 수 있습니까?
Fabian Zeindl

6

아니요, 현재 (Postgres 9.6 현재) 지원되지 않습니다.

유일한 해결 방법은 인덱싱 할 필요가없는 간단한 계산 인 경우 트리거 또는 뷰를 사용하는 것입니다.


쥐. 성능이 필요한 경우 구체화 된 뷰를 사용할 수 있다고 가정합니다. 이미 경쟁에서 사용 가능한 기능에 대한 요청을 추가했습니다.
Manngo

1
MVIEW가 필요 없습니다. 트리거와 열은 또한 인덱스에게 칼럼의 내용하게됩니다
a_horse_with_no_name

기본적으로 다른 데이터의 반복 인 추가 실제 열을 저장하는 데 철학적 인 문제가 있습니다. 테이블을 비정규 화합니다.
Manngo

5
계산 열은 정확히 다음과 같습니다. 비정규 화 된 데이터 저장. 계산 열 값이 생성되는 방식은 중요하지 않습니다. "실제"계산 열과 트리거를 통해 생성 된 열 사이에는 개념적 차이가 없습니다.
a_horse_with_no_name

다른 해결 방법 (일부 경우)은 표현식을 색인화하는 것입니다.
ypercubeᵀᴹ

5

예: GENERATED ALWAYS AS … STORED

Postgres 12SQL : 2003 표준에 언급 된대로 생성 된 열에 대한 기능을 추가합니다 .

값은 INSERT또는 시간에 생성 된 UPDATE다음 다른 값과 마찬가지로 행과 함께 저장됩니다.

생성 된 테이블은 동일한 테이블의 기본 열 또는 변경 불가능한 함수를 기반으로해야합니다 .

문법은 간단하다 CREATE TABLE:

GENERATED ALWAYS AS ( generation_expr ) STORED 

예:

CREATE TABLE people (
    ...,
    height_cm NUMERIC,
    height_in NUMERIC GENERATED ALWAYS AS ( height_cm / 2.54 ) STORED
);

풍모:

  • 색인을 생성 할 수 있습니다.
  • SQL 표준의 일부입니다.

주의 사항 :

  • 동일한 테이블의 열을 기반으로 (관련 테이블이 아님)
  • 파티셔닝이 허용되지 않음 (파티션 키의 일부가 될 수 없음)
  • 스토리지에 공간을 차지하여 항상 행에 기록되는 데이터
    • 향후 기능은 스토리지없이 즉시 계산 된 값에 가상을 제공 할 수 있습니다.
  • 단일 세대 깊이 (다른 생성 된 열이 아닌 기본 열 사용)
  • GENERATED BY DEFAULT가 없습니다 (값을 무시할 수 없음)
  • BEFORE 트리거에서 gen-col에 액세스 할 수 없음 (값이 아직 결정되지 않음)
  • 함수는 변경 불가능해야합니다

보다:


그 정보에 감사드립니다. 버전 12가 아직 완전히 릴리스되지는 않았지만 기대하고 있습니다. PostgreSQL은 더 표준적인 구문을 사용하지만 MSSQL과 동일합니다. sigmodrecord.org/publications/sigmodRecord/0403/…에서 SQL2003 사양을 찾았 습니다 . 나는 항상 SQL이 매우 느리게 움직이는 표준이며 DBMS 구현은 느리다고 말했다 .
Manngo

0

사용 사례에 따라 새 열을 선언하고 삽입 / 업데이트시 트리거로 채워서 이런 종류의 동작을 수행 할 수 있습니다.

가능한 경우 위의 답변을 사용하여 이미 가지고있는 것에서 파생 될 수있는 데이터 복제를 피할 수 있지만 트릭을 수행하고 한 번 계산하고 저장하려는 계산 집약적 파생 필드에 유용 할 수 있습니다.

나는 때때로 18 자리 키의 15 자리 (마지막 3 자리는 체크섬) 만 가지고 있지만 외래 키 관계를 시행하고 싶었던 문제를 다루기 위해이 접근법을 고려했습니다.

트리거에 대한 PG 문서 : https://www.postgresql.org/docs/9.6/sql-createtrigger.html

W3 예 : https://www.w3resource.com/PostgreSQL/postgresql-triggers.php

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.