PostgreSQL 파 티 션 시트(partitioning)응용 인 스 턴 스 상세 설명
9366 단어 PostgreSQL구분 표partitioning
프로젝트 에 필요 한 것 은 수직 으로 표를 나 누 는 것 입 니 다.즉,시간 구간 에 따라 데 이 터 를 n 개의 표 로 나 누 는 것 입 니 다.PostgreSQL 은 파 티 션 표 기능 을 제공 합 니 다.분 구 표 는 실제 적 으로 논리 적 인 큰 표를 물리 적 인 몇 개의 작은 조각 으로 나 누 어 많은 장점 을 제공 했다.예 를 들 어:
1.조회 성능 대폭 향상
2.과거 기록 데이터 삭제 가 빠 름
3.자주 사용 하지 않 는 역사 데이터 사용 표 공간 기술 을 낮은 비용 의 저장 매체 로 이전 할 수 있 습 니 다.
그럼 파 티 션 시트 는 언제 사용 해 야 합 니까?공식 적 으로 제시 한 지도 의견 은 표 의 크기 가 데이터베이스 서버 의 물리 적 메모리 크기 를 초과 하면 파 티 션 표를 사용 해 야 한 다 는 것 이다.다음 에 하나의 예 를 결합 하여 파 티 션 표를 만 드 는 상세 한 과정 을 구체 적 으로 기록 해 야 한다.
파 티 션 테이블 만 들 기
우선 수 요 를 살 펴 보 겠 습 니 다.현재 로그 시트 가 있 습 니 다.표 의 조작 시간 필드(operationtime)파 티 션,다음 그림:
이 수 요 는 전형 적 인 시간 에 따라 구역 표를 만 드 는 것 이다.먼저 절 차 를 살 펴 보 자.
1.부모 테이블 만 들 기
2.n 키 시트 를 만 들 고 모든 하위 표 는 부모 표 에 계승 합 니 다.
3.규칙(Rule)이나 트리거(Trigger)를 정의 하고 메 인 시트 의 데 이 터 를 적당 한 파 티 션 시트 에 삽입 합 니 다.
위 에서 보 듯 이 전체적인 큰 절 차 는 상기 세 가지 로 나 눌 수 있다.물론 작은 최적화 조치 도 있 을 수 있다.예 를 들 어 각 구역 에 대해 키워드 필드 에 색인 을 만 드 는 등 이다.우선 첫 번 째 단 계 를 살 펴 보 자.
파 티 션 표를 만 들 기 전에'부모 표'를 만들어 야 합 니 다.모든 파 티 션 표 는 이 표 에서 계승 되 어야 합 니 다.이 표 에는 데이터 가 없고 이 표 에 검사 제약 과 색인 을 정의 하지 마 십시오.지금 우 리 는 먼저 이 표를 만 들 지만 그 전에 서열 을 만 듭 니 다.
CREATE SEQUENCE "public"."t_sys_log_main_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 99999999
START 1
CACHE 1;
ALTER TABLE "public"."t_sys_log_main_id_seq" OWNER TO "postgres";
다음은'부모 표'를 만 듭 니 다.로그 표 이기 때문에 표 이름 은't'입 니 다.sys_log_main”:
CREATE TABLE "public"."t_sys_log_main" (
"id" int4 DEFAULT nextval('t_sys_log_main_id_seq'::regclass) NOT NULL,
"account_affiliation_code" varchar(100) COLLATE "default" NOT NULL,
"account_affiliation" varchar(50) COLLATE "default" NOT NULL,
"operation_time" timestamp(6) NOT NULL,
"operation_key" varchar(2) COLLATE "default" NOT NULL,
"operation_value" varchar(30) COLLATE "default" NOT NULL,
"operation_loginid" varchar(100) COLLATE "default" NOT NULL,
"operation_message" varchar(300) COLLATE "default" NOT NULL,
"operation_ip" varchar(30) COLLATE "default" NOT NULL
)
WITH (OIDS=FALSE)
;
COMMENT ON TABLE "public"."t_sys_log_main" IS ' ';
COMMENT ON COLUMN "public"."t_sys_log_main"."account_affiliation_code" IS ' ';
COMMENT ON COLUMN "public"."t_sys_log_main"."account_affiliation" IS ' ';
COMMENT ON COLUMN "public"."t_sys_log_main"."operation_time" IS ' ';
COMMENT ON COLUMN "public"."t_sys_log_main"."operation_key" IS ' (key)';
COMMENT ON COLUMN "public"."t_sys_log_main"."operation_value" IS ' (value)';
COMMENT ON COLUMN "public"."t_sys_log_main"."operation_loginid" IS ' ';
COMMENT ON COLUMN "public"."t_sys_log_main"."operation_message" IS ' ';
COMMENT ON COLUMN "public"."t_sys_log_main"."operation_ip" IS ' ';
ALTER TABLE "public"."t_sys_log_main" ADD PRIMARY KEY ("id");
상기 DDL 문 구 를 실행 하여 부모 표를 만 듭 니 다.만 든 후에 각각 파 티 션 표를 만 들 수 있 습 니 다.모든 파 티 션 표 는 부모 표 에서 계승 되 기 때문에 파 티 션 표 는 필드 를 추가 하지 않 습 니 다.다음은 필요 에 따라 4 개의 파 티 션 서브 표를 만 들 고 각각 9 월,10 월,11 월 과 12 월 의 로그 데 이 터 를 저장 하 는 데 사 용 됩 니 다.
create table t_sys_log_y2016m09
(CHECK (operation_time >= DATE '2016-09-01' AND operation_time< DATE '2016-10-01'))
INHERITS (t_sys_log_main);
create table t_sys_log_y2016m10
(CHECK (operation_time >= DATE '2016-10-01' AND operation_time< DATE '2016-11-01'))
INHERITS (t_sys_log_main);
create table t_sys_log_y2016m11
(CHECK (operation_time >= DATE '2016-11-01' AND operation_time< DATE '2016-12-01'))
INHERITS (t_sys_log_main);
create table t_sys_log_y2016m12
(CHECK (operation_time >= DATE '2016-12-01' AND operation_time< DATE '2017-01-01'))
INHERITS (t_sys_log_main);
위 에서 보 듯 이 실행 이 끝 난 후에 4 개의 파 티 션 서브 표를 만 들 수 있 습 니 다.위의 문장 에 우 리 는 이 달의 데이터 만 삽입 할 수 있다 는 제약 을 추가 하 였 습 니 다.그 다음 에 이 4 개의 파 티 션 시트 의 각 파 티 션 키 에 색인 을 만 듭 니 다.
create index t_sys_log_y2016m09_operation_time ON t_sys_log_y2016m09(operation_time);
create index t_sys_log_y2016m10_operation_time ON t_sys_log_y2016m10(operation_time);
create index t_sys_log_y2016m11_operation_time ON t_sys_log_y2016m11(operation_time);
create index t_sys_log_y2016m12_operation_time ON t_sys_log_y2016m12(operation_time);
여기까지 우리 의 파 티 션 시트 가 만 들 어 졌 습 니 다.그 다음 에 데이터 삽입 문 제 를 고려 해 야 합 니 다.어떻게 해 야 서로 다른 날짜 의 데 이 터 를 해당 하 는 파 티 션 서브 시트 에 자동 으로 삽입 할 수 있 습 니까?두 가지 해결 방안 이 있 는데 그것 이 바로 규칙(Rule)과 트리거(Trigger)이다.트리거 보다 Rule 의 비용 이 더 많이 들 기 때문에 저 는 여기 서 너무 많은 소 개 를 하지 않 겠 습 니 다.다음은 Trigger 의 방식 을 직접 소개 하 겠 습 니 다.Trigger 는 보통 사용자 정의 함수(Function)와 결합 하여 파 티 션 삽입 을 실현 하고 Function 은 조건 에 따라 삽입 을 선택 하 며 Trigger 는 Function 의 자동 호출 을 책임 집 니 다.먼저 Function 을 정의 합 니 다.기능 은 간단 합 니 다.즉,날짜 구간 insert 데이터 에 따라 가능 합 니 다.
CREATE
OR REPLACE FUNCTION sys_log_insert_trigger () RETURNS TRIGGER AS $$
BEGIN
IF (
NEW .operation_time >= DATE '2016-09-01'
AND NEW .operation_time < DATE '2016-10-01'
) THEN
INSERT INTO t_sys_log_y2016m09
VALUES
(NEW .*) ;
ELSEIF (
NEW .operation_time >= DATE '2016-10-01'
AND NEW .operation_time < DATE '2016-11-01'
) THEN
INSERT INTO t_sys_log_y2016m10
VALUES
(NEW .*) ;
ELSEIF (
NEW .operation_time >= DATE '2016-11-01'
AND NEW .operation_time < DATE '2016-12-01'
) THEN
INSERT INTO t_sys_log_y2016m11
VALUES
(NEW .*) ;
ELSEIF (
NEW .operation_time >= DATE '2016-12-01'
AND NEW .operation_time < DATE '2017-01-01'
) THEN
INSERT INTO t_sys_log_y2016m12
VALUES
(NEW .*) ;
ELSE
RAISE EXCEPTION 'Date out of range!' ;
END
IF ; RETURN NULL ;
END ; $$ LANGUAGE plpgsql;
마지막 으로 트리거 를 만들어 서 아까 의 Function 을 실행 합 니 다:
CREATE TRIGGER sys_log_insert_trigger BEFORE INSERT ON t_sys_log_main
FOR EACH ROW
EXECUTE PROCEDURE sys_log_insert_trigger();
여기까지 만 들 었 습 니 다.마지막 으로 테스트 를 해 보 겠 습 니 다.우리 의 트리거 가 확실히 작 동 했 는 지 확인 하기 위해 서,우 리 는 저장 과정의 통계 스위치 를 열 고,postgresql.conf 에서 track 을 찾 습 니 다.functions,all 로 변경:다음 에 몇 개의 테스트 insert 문 구 를 실행 하여 지정 한 시간 기록 을 각각 해당 하 는 파 티 션 서브 시트 에 삽입 할 수 있 는 지 확인 할 수 있 습 니 다.삽입 하기 전에 sys 를 보 세 요.log_insert_trigger()의 통계 정보:
현재 통계 기록 이 없 는 것 을 볼 수 있 습 니 다.다음은 몇 개의 테스트 데 이 터 를 삽입 합 니 다.
INSERT INTO t_sys_log_main VALUES
(1,'200022', ' ', '2016-9-8 18:49:26.004', '01', 'xx', 'zhsz_t', 'test!', '127.0.0.1');
INSERT INTO t_sys_log_main VALUES
(1,'200023', ' ', '2016-9-12 18:49:26.004', '01', 'xx', 'zhsz_t', 'test!', '127.0.0.1');
INSERT INTO t_sys_log_main VALUES
(1,'200024', ' ', '2016-10-8 18:49:26.004', '01', 'xx', 'zhsz_t', 'test!', '127.0.0.1');
INSERT INTO t_sys_log_main VALUES
(1,'200025', ' ', '2016-11-8 18:49:26.004', '01', 'xx', 'zhsz_t', 'test!', '127.0.0.1');
INSERT INTO t_sys_log_main VALUES
(1,'200026', ' ', '2016-12-8 18:49:26.004', '01', 'xx', 'zhsz_t', 'test!', '127.0.0.1');
INSERT INTO t_sys_log_main VALUES
(1,'200027', ' ', '2016-12-25 18:49:26.004', '01', 'xx', 'zhsz_t', 'test!', '127.0.0.1');
이어서 다시 한 번 syslog_insert_trigger()의 통계 정보:위의 그림 에서 보 듯 이 6 번 의 함 수 를 호출 한 것 을 알 수 있 습 니 다.우 리 는 6 개의 데 이 터 를 삽 입 했 기 때문에 파 티 션 표 는 생 성 에서 테스트 까지 의 전체 과정 이 성공 적 으로 완성 되 었 습 니 다.
총결산
PostgreSQL 이 파 티 션 표를 만 드 는 전체 절차 와 주의사항 을 간단하게 기록 하고 같은 문제 에 부 딪 힌 친구 에 게 도움 이 되 기 를 바 랍 니 다.The End.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redmine 데이터베이스를 MySQL에서 PostgreSQL로 마이그레이션 (보충)Redmine 의 Database 를 MySQL 로 운용하고 있었습니다만, MySQL 5.6 이상이나 MariaDB 에는 , , 이러한 티켓이 수년 동안 방치된 상황을 감안하여, PostgreSQL로 마이그레이션하기...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.