[postgresql] PostgreSQL에서 상속 된 테이블을 언제 사용합니까?

어떤 상황에서 상속 된 테이블을 사용해야합니까? 나는 그것들을 아주 짧게 사용하려고했고 상속은 OOP 세계 에서처럼 보이지 않았습니다.

다음과 같이 작동한다고 생각했습니다.

users모든 사용자 레벨에 필요한 모든 필드가있는 테이블 . 테이블 좋아 moderators, admins, bloggers, 등하지만 필드가되어 있지 부모로부터 확인. 예를 들어 users이메일 필드가 상속 bloggers도 지금 가지고 있지만 모두 고유 아니에요 usersbloggers동시에. 즉. 두 테이블에 이메일 필드를 추가하는 것과 동일합니다.

내가 생각할 수있는 유일한 사용법은 row_is_deleted , created_at , modified_at 와 같이 일반적으로 사용되는 필드입니다 . 상속 된 테이블에 대한 유일한 사용법입니까?



답변

postgres에서 테이블 상속을 사용하는 몇 가지 주요 이유가 있습니다.

매월 생성되고 채워지는 통계에 필요한 몇 가지 테이블이 있다고 가정 해 보겠습니다.

statistics
    - statistics_2010_04 (inherits statistics)
    - statistics_2010_05 (inherits statistics)

이 샘플에서는 각 테이블에 2.000.000 개의 행이 있습니다. 각 테이블에는 일치하는 월의 데이터 만 저장되도록하는 CHECK 제약 조건이 있습니다.

그렇다면 상속을 멋진 기능으로 만드는 것은 무엇입니까? 데이터를 분할하는 것이 멋진 이유는 무엇입니까?

  • 성능 : 데이터를 선택할 때 x와 Y 사이의 날짜에서 * 통계를 선택하고 Postgres는 테이블 만 사용합니다. 예 : SELECT * FROM statistics WHERE date BETWEEN ‘2010-04-01’및 ‘2010-04-15’는 statistics_2010_04 테이블 만 스캔하며 다른 모든 테이블은 처리되지 않습니다.
  • 인덱스 크기 : 날짜 열에 큰 팻 인덱스가있는 큰 팻 테이블이 없습니다. 우리는 매월 작은 인덱스를 가진 작은 테이블을 가지고 있습니다-더 빠른 읽기.
  • 유지 관리 : 다른 모든 데이터를 잠그지 않고 매달 테이블에서 vacuum full, reindex, cluster를 실행할 수 있습니다.

성능 향상을 위해 테이블 ​​상속을 올바르게 사용하려면 postgresql 매뉴얼을 참조하십시오. 데이터베이스에 데이터가 분할 (파티션)되는 키를 알리려면 각 테이블에 CHECK 제약 조건을 설정해야합니다.

특히 월별로 그룹화 된 로그 데이터를 저장할 때 테이블 상속을 많이 사용합니다. 힌트 : 변경되지 않는 데이터 (로그 데이터)를 저장하는 경우 CREATE INDEX ON () WITH (fillfactor = 100); 이는 업데이트를위한 공간이 인덱스에 예약되지 않음을 의미합니다. 인덱스는 디스크에서 더 작습니다.

업데이트 : fillfactor 기본값은 http://www.postgresql.org/docs/9.1/static/sql-createtable.html 에서 100입니다 .

테이블의 채우기 비율은 10에서 100 사이의 백분율입니다. 100 (완전 패킹)이 기본값입니다.


답변

“테이블 상속” “클래스 상속”과 다른 것을 의미 하며 다른 용도로 사용됩니다.

Postgres는 데이터 정의에 관한 것입니다. 때때로 정말 복잡한 데이터 정의. OOP (일반적인 Java 색상 의미에서)는 단일 원자 구조의 데이터 정의에 동작을 종속시키는 것입니다. 여기서 “상속”이라는 단어의 목적과 의미는 크게 다릅니다.

OOP 영역에서 정의 할 수 있습니다 (여기서 구문과 의미론이 매우 느슨 함).

import life

class Animal(life.Autonomous):
  metabolism = biofunc(alive=True)

  def die(self):
    self.metabolism = False

class Mammal(Animal):
  hair_color = color(foo=bar)

  def gray(self, mate):
    self.hair_color = age_effect('hair', self.age)

class Human(Mammal):
  alcoholic = vice_boolean(baz=balls)

이에 대한 표는 다음과 같습니다.

CREATE TABLE animal
  (name       varchar(20) PRIMARY KEY,
   metabolism boolean NOT NULL);

CREATE TABLE mammal
  (hair_color  varchar(20) REFERENCES hair_color(code) NOT NULL,
   PRIMARY KEY (name))
  INHERITS (animal);

CREATE TABLE human
  (alcoholic  boolean NOT NULL,
   FOREIGN KEY (hair_color) REFERENCES hair_color(code),
   PRIMARY KEY (name))
  INHERITS (mammal);

그러나 행동은 어디에 있습니까? 그들은 어디에도 맞지 않습니다. 데이터베이스는 절차 적 코드가 아니라 데이터와 관련되기 때문에 이것은 데이터베이스 세계에서 논의되는 “객체”의 목적이 아닙니다. 계산을 수행하기 위해 데이터베이스에 함수를 작성할 수 있지만 (종종 아주 좋은 생각이지만이 경우에 맞는 것은 아닙니다) 함수는 메서드와 동일하지 않습니다. 즉, 말하는 OOP의 형태로 이해되는 메서드입니다. 의도적으로 유연성이 떨어집니다.

계통도 장치로서 상속에 대해 지적해야 할 사항이 한 가지 더 있습니다. Postgres 9.2부터는 모든 파티션 / 테이블 패밀리 구성원에 대해 한 번에 외래 키 제약 조건을 참조 할 수있는 방법이 없습니다. 이를 수행하기 위해 검사를 작성하거나 다른 방법으로 해결할 수 있지만 기본 제공 기능은 아닙니다 (실제로는 복잡한 인덱싱 문제로 귀결되며 아무도 자동으로 만드는 데 필요한 비트를 작성하지 않았습니다). 이러한 목적으로 테이블 상속을 사용하는 대신 개체 상속을 위해 데이터베이스에서 더 나은 일치는 테이블에 대한 도식 확장을 만드는 것입니다. 이 같은:

CREATE TABLE animal
  (name       varchar(20) PRIMARY KEY,
   ilk        varchar(20) REFERENCES animal_ilk NOT NULL,
   metabolism boolean NOT NULL);

CREATE TABLE mammal
  (animal      varchar(20) REFERENCES animal PRIMARY KEY,
   ilk         varchar(20) REFERENCES mammal_ilk NOT NULL,
   hair_color  varchar(20) REFERENCES hair_color(code) NOT NULL);


CREATE TABLE human
  (mammal     varchar(20) REFERENCES mammal PRIMARY KEY,
   alcoholic  boolean NOT NULL);

이제 외래 키 참조로 안정적으로 사용할 수있는 동물의 인스턴스에 대한 표준 참조가 있고 확장 데이터의 “다음”테이블을 가리키는 xxx_ilk 정의 테이블을 참조하는 “ilk”열이 있습니다 ( 또는 ilk가 제네릭 유형 자체 인 경우 없음을 나타냅니다.) 이러한 종류의 스키마에 대해 테이블 ​​함수, 뷰 등을 작성하는 것은 매우 쉬워서 대부분의 ORM 프레임 워크는 OOP 스타일 클래스 상속에 의존하여 개체 유형의 패밀리를 생성 할 때 백그라운드에서 이러한 종류의 작업을 정확하게 수행합니다.


답변

상위 테이블에서 외래 키를 만들 필요가없는 한 상속은 OOP 패러다임에서 사용할 수 있습니다. 예를 들어, 차량 테이블에 저장된 추상 클래스 차량과이를 상속하는 테이블 차량이있는 경우 모든 차량이 차량 테이블에 표시되지만 차량 테이블의 운전자 테이블에있는 외래 키는이 테이블과 일치하지 않습니다. 기록.

상속은 분할 도구 로도 사용할 수 있습니다 . 이것은 영원히 성장할 테이블 (로그 테이블 등)이있을 때 특히 유용합니다.


답변

상속의 주요 용도는 분할에 사용되지만 때로는 다른 상황에서 유용합니다. 내 데이터베이스에는 외래 키만 다른 많은 테이블이 있습니다. 내 “추상 클래스”테이블 “이미지”에는 “ID”(모든 테이블에 기본 키가 있어야 함)와 PostGIS 2.0 래스터가 있습니다. “site_map”또는 “artifact_drawing”과 같은 상속 된 테이블에는 외래 키 열 ( “site_map”의 경우 “site_name”텍스트 열, “artifact_drawing”테이블의 경우 “artifact_id”정수 열 등) 및 기본 및 외래 키 제약 조건이 있습니다. 나머지는 “이미지”테이블에서 상속됩니다. 앞으로 모든 이미지 테이블에 “설명”열을 추가해야 할 수도 있으므로 실제 문제를 만들지 않고도 많은 작업을 절약 할 수 있습니다.

편집 : 또 다른 좋은 사용 : 등록되지 않은 사용자를 두 테이블로 처리하면 다른 RDBMS가 두 테이블을 처리하는 데 문제가 있지만 PostgreSQL에서는 쉽습니다 ONLY. 상속 된 “등록되지 않은 사용자”테이블의 데이터에 개입하지 않을 때 추가하기 만하면 됩니다.


답변

상속 된 테이블에 대한 유일한 경험은 파티셔닝입니다. 잘 작동하지만 PostgreSQL에서 가장 정교하고 사용하기 쉬운 부분은 아닙니다.

지난주에 우리는 동일한 OOP 문제를보고 있었지만 Hibernate에 너무 많은 문제가 있었기 때문에 (설정이 마음에 들지 않았습니다) PostgreSQL에서 상속을 사용하지 않았습니다.


답변

테이블 사이에 일대일 관계가 더 많을 때 상속을 사용합니다.

예 : x, y, 회전, 축척 속성이있는 객체 맵 위치를 저장한다고 가정합니다.

이제지도에 표시 할 여러 종류의 객체가 있고 각 객체에 자체지도 위치 매개 변수가 있고지도 매개 변수는 재사용되지 않는다고 가정합니다.

이러한 경우 테이블 상속은 비정규 화 된 테이블을 유지하거나 위치 ID를 생성하고 다른 테이블에 대한 상호 참조를 피하는 데 매우 유용합니다.


답변

가능한 한 적게 사용하십시오. 그리고 그것은 일반적으로 결코 의미가 없습니다. 예를 들어 정보 원칙을 깨고 관계 대신 가방을 만들어 관계형 모델을 위반하는 구조를 만드는 방식으로 끓어 오릅니다.

대신 추가 정규 형식을 포함하여 적절한 관계형 모델링과 결합 된 테이블 분할을 사용하십시오.