제한#

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

속성이 jsonb 필드 하나이므로, 정점이나 간선 하나의 속성 맵 전체입니다. 긴 값은 먼저 압축되어 줄 밖으로 옮겨집니다.

릴레이션당 컬럼 수

1600

속성을 컬럼으로 승격할 때에만 닿습니다. 정점 레이블은 컬럼 둘로, 간선 레이블은 넷으로 시작합니다.

식별자 길이

63바이트

레이블 이름·그래프 이름·속성 인덱스 이름·변수 이름입니다. 속성 키는 식별자가 아니므로 여기에 매이지 않습니다.

테이블당 행 수

릴레이션 크기에 매입니다

48비트 로컬 id가 훨씬 크므로 저장 공간 제한에 먼저 닿습니다.

테이블당 인덱스 수

제한 없음

레이블 하나에 대한 속성 인덱스입니다.

참고

1 GB 필드 크기 말고는 요소 하나가 속성을 몇 개 지닐 수 있는지도, 속성이 얼마나 깊이 중첩될 수 있는지도 제한하지 않습니다. 다만 속성 읽기에는 맵 크기에 따라 커지는 비용이 있습니다. 키 하나에 닿으려고 맵 전체를 가져오기 때문입니다. 그 비용을 벗어나는 길은 ALTER VLABEL로 그 키를 컬럼으로 승격하는 것입니다.

관련 항목#