제한#
AgensGraph의 제한 중 둘은 모든 정점과 간선에 주는 식별자에서 나옵니다. 나머지는 PostgreSQL의 것입니다. 그래프는 스키마이고 레이블은 테이블이기 때문입니다.
그래프의 제한#
모든 정점과 간선은 graphid 타입의 식별자를 지니며, 그 배치가 그래프가 닿을 수 있는 두 제한을
정합니다. graphid는 둘로 나뉜 64비트 부호 없는 정수입니다. 상위 16비트가 레이블 id이고, 하위
48비트가 그 레이블 안에서 행의 일련번호인 로컬 id입니다. 그래서 식별자는 숫자 두 개로
찍힙니다. movie[3.7]은 레이블 3의 7번 행입니다.
제한 |
값 |
유래 |
|---|---|---|
그래프당 레이블 수 |
65,535 |
16비트 레이블 id입니다. 0은 무효 레이블 id로 예약돼 있어 쓸 수 있는 범위는 1부터 65,535까지입니다. |
레이블당 행 수 |
281,474,976,710,655 |
48비트 로컬 id, 즉 248 − 1입니다. |
레이블 이름 길이 |
63바이트 |
PostgreSQL의 식별자 길이입니다. |
그래프 자체에는 따로 제한이 없습니다. 그래프는 스키마이고 PostgreSQL은 데이터베이스당 스키마 수에 제한을 두지 않습니다. 다만 그래프가 많으면 릴레이션을 소모합니다. 그래프마다 자기 시퀀스 하나와 루트 레이블 둘을 만들기 때문입니다.
graphid의 두 부분은 모두 범위 검사를 받습니다. 어느 쪽이든 범위를 벗어나면 생성자가
거부합니다:
SELECT graphid(65536, 1);
ERROR: labid out of range: 65536
SELECT graphid(1, 281474976710656);
ERROR: locid out of range: 281474976710656
graphid 리터럴을 파싱할 때도 문제가 된 값만 빠진 같은 메시지 둘이 돌아옵니다.
SELECT '65536.1'::graphid 는 labid out of range를 냅니다.
이 번호를 나눠 주는 계수기는 평범한 시퀀스이므로 들여다볼 수 있습니다. 그래프마다 레이블 id를 위한
ag_label_seq가 하나씩, 레이블마다 로컬 id를 위한 <label>_id_seq가 하나씩 있습니다:
SELECT sequencename, max_value FROM pg_sequences
WHERE schemaname = 'moviekb' AND sequencename IN ('ag_label_seq', 'movie_id_seq');
sequencename | max_value
--------------+-----------------
ag_label_seq | 65535
movie_id_seq | 281474976710655
ag_label_seq는 순환하고 레이블 생성은 이미 쓰이는 번호를 건너뛰므로, 레이블을 지우면 그 id가
다시 쓸 수 있게 풀립니다. 남은 id가 없으면 레이블 생성이 실패합니다:
ERROR: no more new labels are available
새 그래프마다 레이블 둘이 함께 생깁니다. 레이블 id 1인 ag_vertex와 id 2인 ag_edge입니다. 모든
정점·간선 레이블이 상속하는 두 뿌리입니다. 그래서 직접 만드는 레이블에는 65,533개의 id를 쓸 수
있습니다.
63바이트를 넘는 레이블 이름은 잘린다#
식별자는 63바이트입니다. 그보다 긴 레이블 이름은 notice와 함께 63바이트로 잘립니다. 그러므로
앞 63바이트가 같은 레이블 이름 둘은 한 레이블입니다. 두 번째 CREATE VLABEL이 첫 번째 것을
봅니다:
CREATE VLABEL a_label_name_that_is_deliberately_longer_than_sixty_three_bytes_aaa;
CREATE VLABEL a_label_name_that_is_deliberately_longer_than_sixty_three_bytes_bbb;
NOTICE: identifier "a_label_name_that_is_deliberately_longer_than_sixty_three_bytes_aaa" will be truncated to "a_label_name_that_is_deliberately_longer_than_sixty_three_bytes"
CREATE VLABEL
NOTICE: identifier "a_label_name_that_is_deliberately_longer_than_sixty_three_bytes_bbb" will be truncated to "a_label_name_that_is_deliberately_longer_than_sixty_three_bytes"
ERROR: label "a_label_name_that_is_deliberately_longer_than_sixty_three_bytes" already exists
패턴에서 이것이 발목을 잡습니다. 패턴은 찾지 못한 레이블을 만들고 아무것도 실패하지 않기 때문입니다. 위의 두 이름에 쓰면 두 행이 같은 레이블에 들어갑니다:
CREATE (:a_label_name_that_is_deliberately_longer_than_sixty_three_bytes_aaa {via:'aaa'});
CREATE (:a_label_name_that_is_deliberately_longer_than_sixty_three_bytes_bbb {via:'bbb'});
MATCH (n) RETURN label(n) AS lab, n.via ORDER BY n.via;
lab | via
-------------------------------------------------------------------+-------
"a_label_name_that_is_deliberately_longer_than_sixty_three_bytes" | "aaa"
"a_label_name_that_is_deliberately_longer_than_sixty_three_bytes" | "bbb"
레이블 이름은 63바이트 안에 두고, 앞 63바이트가 서로 다르게 하십시오. 제한은 글자 수가 아니라 바이트 수이므로, 여러 바이트를 쓰는 문자로 된 이름은 더 빨리 그 제한에 닿습니다.
그래프가 부딪히는 PostgreSQL의 제한#
레이블은 테이블이므로 그래프도 데이터베이스의 나머지와 같은 제한을 받습니다. 아래는 그래프 작업이 닿는 것들입니다. 전체 목록은 PostgreSQL의 Limits 부록에 있습니다.
제한 |
값 |
그래프에 뜻하는 것 |
|---|---|---|
릴레이션 크기 |
32 TB |
기본 8 kB 블록 크기에서 레이블 하나의 저장 공간입니다. 이를 넘는 레이블은 파티셔닝하거나 자식 레이블로 나눠야 합니다. |
필드 크기 |
1 GB |
속성이 |
릴레이션당 컬럼 수 |
1600 |
속성을 컬럼으로 승격할 때에만 닿습니다. 정점 레이블은 컬럼 둘로, 간선 레이블은 넷으로 시작합니다. |
식별자 길이 |
63바이트 |
레이블 이름·그래프 이름·속성 인덱스 이름·변수 이름입니다. 속성 키는 식별자가 아니므로 여기에 매이지 않습니다. |
테이블당 행 수 |
릴레이션 크기에 매입니다 |
48비트 로컬 id가 훨씬 크므로 저장 공간 제한에 먼저 닿습니다. |
테이블당 인덱스 수 |
제한 없음 |
레이블 하나에 대한 속성 인덱스입니다. |
참고
1 GB 필드 크기 말고는 요소 하나가 속성을 몇 개 지닐 수 있는지도, 속성이 얼마나 깊이 중첩될 수
있는지도 제한하지 않습니다. 다만 속성 읽기에는 맵 크기에 따라 커지는 비용이 있습니다. 키 하나에
닿으려고 맵 전체를 가져오기 때문입니다. 그 비용을 벗어나는 길은
ALTER VLABEL로 그 키를 컬럼으로 승격하는 것입니다.
관련 항목#
그래프가 어떻게 저장되는가 — 이 제한들이 설명하는 저장 배치
레이블 상속 — 큰 레이블 하나를 여럿으로 나누기
데이터 정의 — 레이블과 인덱스를 만드는 문장