데이터 타입#
AgensGraph는 PostgreSQL의 타입 집합에 다섯 개를 더합니다. graphid, vertex, edge, graphpath,
rowid입니다. 그래프가 저장하는 그 밖의 모든 것은 레이블의 properties 컬럼에 담긴 jsonb입니다.
PostgreSQL의 모든 타입은 여전히 쓸 수 있고 PostgreSQL이 문서화한 대로 동작합니다.
이 다섯은 고정된 OID로 pg_type에 정의돼 있으므로 모든 데이터베이스에서 같고 확장이 필요하지
않습니다.
타입 |
저장 방식 |
담는 것 |
|---|---|---|
|
8바이트, 값으로 |
정점 하나 또는 간선 하나의 식별자입니다. |
|
복합, 가변 |
id, 속성 맵, 그리고 그 행의 물리적 위치입니다. |
|
복합, 가변 |
id, 끝점 id 둘, 속성 맵, 그리고 그 행의 위치입니다. |
|
복합, 가변 |
정점의 배열과 간선의 배열입니다. |
|
10바이트, 참조로 |
테이블 OID와 행 포인터입니다. 내부용입니다. |
graphid#
graphid는 정점이나 간선의 식별자입니다. 간선은 자기 끝점을 지목하려고 그것을 저장합니다. 두
부분으로 된 64비트 값입니다. 상위 16비트가 레이블 id, 하위 48비트가 레이블마다 매겨지는
시퀀스인 로컬 id입니다. 출력 형태는 labid.locid입니다.
그 배치가 왜 플래너에게 중요한지는 그래프가 어떻게 저장되는가가 설명합니다. 이 절은 그 정식 세부 내용입니다.
두 함수가 그 부분들을 다시 분해합니다:
SELECT id, graphid_labid(id) AS labid, graphid_locid(id) AS locid
FROM moviekb.person WHERE properties->>'name' = 'Keanu Reeves';
id | labid | locid
-----+-------+-------
4.1 | 4 | 1
graphid(labid, locid)가 그 부분들로 하나를 만듭니다. 레이블의 id 컬럼이 기본값
표현식에서 호출하는 것과 같은 함수입니다.
범위#
레이블 id는 16비트, 로컬 id는 48비트이므로 가장 큰 graphid는 이렇습니다:
SELECT graphid(65535, 281474976710655) AS highest;
highest
-----------------------
65535.281474976710655
어느 부분이든 범위를 벗어나면 잘리는 것이 아니라 거부됩니다:
SELECT graphid(65536, 1);
ERROR: labid out of range: 65536
SELECT graphid(3, 281474976710656);
ERROR: locid out of range: 281474976710656
0은 레이블 없음으로 예약돼 있으므로, 데이터베이스는 최대 65,535개의 레이블을, 레이블은 최대
248 − 1개의 요소를 가집니다. 이 예약은 검사가 아니라 관례이므로 graphid(0, 1)은 0.1을
만듭니다. 다만 레이블 id 0을 배정하는 것은 아무것도 없습니다. 이런 수치는 PostgreSQL 자신의 것과
함께 제한이 모아 두었습니다.
형 변환#
graphid로 들어가는 형 변환은 numeric에서 오는 것 하나뿐이고, 그것은 암시적입니다. integer에서
오는 것은 없으므로, 소수점 없이 적은 정수는 변환되지 않습니다:
SELECT 1::graphid;
ERROR: cannot cast type integer to graphid
LINE 1: SELECT 1::graphid;
^
두 부분을 적으십시오. 소수점이 있는 수치 리터럴은 형 변환되고, labid.locid 형태의 문자열은
파싱됩니다:
SELECT 1.1::graphid AS from_numeric, '3.1'::graphid AS from_text;
from_numeric | from_text
--------------+-----------
1.1 | 3.1
numeric 형 변환은 그 타입이 출력하는 방식으로 숫자를 읽습니다. 그래서 1.1은 1.1이라는 수가
아니라 레이블 1의 요소 1입니다. 소수 자리가 없는 numeric에는 로컬 id가 없어서 거부됩니다.
1::numeric::graphid는 invalid input syntax for type graphid: "1"을 냅니다.
graphid에서 나가는 형 변환은 없습니다. 부분이 필요하면 graphid_labid()와 graphid_locid()를
쓰거나, 그냥 출력되게 두십시오.
vertex와 edge#
vertex는 필드 세 개로 된 복합 값입니다. id graphid, properties jsonb, 그리고 그 행의 물리적
위치를 담은 tid입니다. 쓰기는 그 tid로 그 행을 다시 찾습니다. edge는 같은 세 필드에
start graphid와 end graphid가 더해진 것입니다.
레이블과 id, 속성을 보여 주는 형태로 출력됩니다:
MATCH (p:person {name: 'Keanu Reeves'}) RETURN p;
p
---------------------------------------------------
person[4.1]{"born": 1964, "name": "Keanu Reeves"}
간선은 자기 id와 속성 사이에 양 끝점을 출력하며, 시작점이 먼저 옵니다:
MATCH (:person {name: 'Keanu Reeves'})-[r:acted_in]->(:movie {title: 'The Matrix'}) RETURN r;
r
---------------------------------------
acted_in[5.1][4.1,3.1]{"role": "Neo"}
그래서 모양은 정점이 label[id]{properties}, 간선이 label[id][start,end]{properties}입니다.
속성이 없는 요소는 빈 맵을 출력합니다. directed[6.8][4.8,3.5]{}입니다.
tid 필드는 두 출력 형태 어디에도 들어 있지 않고, 의존할 만한 것도 아닙니다. 그 행이 갱신되면
값이 바뀝니다.
그것으로 할 수 있는 일#
vertex와 edge에는 각각 비교 연산자 여섯 개가 있고, 그 밖에는 아무것도 없습니다:
타입 |
연산자 |
|---|---|
|
|
|
|
|
|
|
|
|
없음 |
비교는 식별자만으로 합니다. vertex_eq와 그 형제 함수들은 id 필드를 비교하고 속성은 전혀
보지 않습니다. 속성이 똑같고 id가 다른 두 정점은 같지 않습니다:
CREATE GRAPH twins;
SET graph_path = twins;
CREATE VLABEL pair;
CREATE (:pair {k: 1}), (:pair {k: 1});
MATCH (a:pair), (b:pair) WHERE id(a) < id(b)
RETURN a, b, a = b AS equal, properties(a) = properties(b) AS same_properties;
a | b | equal | same_properties
-------------------+-------------------+-------+-----------------
pair[3.1]{"k": 1} | pair[3.2]{"k": 1} | f | t
순서도 같은 규칙에서 따라옵니다. a < b는 graphid 값을 비교하므로, 먼저 레이블 순서이고 그다음
레이블 안에서는 삽입 순서입니다. 이 순서는 전순서이고 안정적이어서 ORDER BY의 동률 해소에
좋습니다. 데이터를 뜻 있게 정렬해 주는 것은 아닙니다.
MATCH (a:person {name: 'Keanu Reeves'}), (b:person {name: 'Carrie-Anne Moss'})
RETURN a = b AS equal, a < b AS less, id(a) AS id_a, id(b) AS id_b;
equal | less | id_a | id_b
-------+------+------+------
f | t | 4.1 | 4.3
대신 속성을 비교하려면 속성을 비교하십시오. properties(a) = properties(b)처럼 쓰거나, 뜻하는
키를 이름으로 부르십시오.
두 타입 모두 암시적으로 jsonb로 형 변환됩니다. 그 변환은 속성 맵을 남기고 식별자는 버립니다.
pg_cast의 vertex_to_jsonb와 edge_to_jsonb입니다. 그래서 m::jsonb는 properties(m)입니다.
반대 방향의 형 변환은 없습니다.
graphpath#
graphpath는 배열 두 개로 된 복합 타입입니다. vertices vertex[]와 edges edge[]입니다. 간선
n개인 경로는 정점 n + 1개를 담으므로, 정점 하나에 바인딩된 경로는 정점 하나에 간선이
없습니다:
MATCH p = (a:person {name: 'Keanu Reeves'}) RETURN p;
p
-----------------------------------------------------
[person[4.1]{"born": 1964, "name": "Keanu Reeves"}]
보행 순서대로 정점·간선·정점이 번갈아 오는 구성원 목록을 대괄호로 감싸고 쉼표로 구분해 출력합니다. 두 배열이 두 개의 배열로 출력되는 것이 아니라 서로 엇갈려 놓입니다. 그래서 간선 하나인 경로는 구성원 세 개를, 간선 n개인 경로는 2n + 1개를 출력합니다.
구성원에는 nodes()와 edges()로 닿습니다. 그 두 함수가 두 배열을 돌려줍니다. length()는 간선
개수입니다:
MATCH p = (:person {name: 'Keanu Reeves'})-[:acted_in]->(:movie {title: 'The Matrix'})
RETURN length(p) AS hops, nodes(p)[0] AS first_vertex, edges(p)[0] AS only_edge;
hops | first_vertex | only_edge
------+---------------------------------------------------+---------------------------------------
1 | person[4.1]{"born": 1964, "name": "Keanu Reeves"} | acted_in[5.1][4.1,3.1]{"role": "Neo"}
graphpath에는 자기 연산자가 없습니다. 같음도, 순서도 없습니다. Cypher에서 경로 둘을 비교하는
것은 거부됩니다. 호출할 연산자가 없으니 그 표현식은 jsonb로 되돌아가는데, 경로는 jsonb 값이
아닙니다:
MATCH p1 = (:person {name:'Keanu Reeves'})-[:acted_in]->(:movie {title:'The Matrix'}),
p2 = (:person {name:'Keanu Reeves'})-[:acted_in]->(:movie {title:'The Matrix'})
RETURN p1 = p2;
ERROR: graph object cannot be jsonb
LINE 3: RETURN p1 = p2;
^
SQL에서는 비교가 됩니다. 복합 값에 대한 PostgreSQL의 일반 연산자를 통해서이고, 그것은 두 배열을 필드 단위로 훑습니다:
SELECT a = b AS equal, a < b AS less
FROM (MATCH p = (:person {name:'Keanu Reeves'})-[:acted_in]->(:movie {title:'The Matrix'})
RETURN p AS a) x,
(MATCH p = (:person {name:'Keanu Reeves'})-[:acted_in]->(:movie {title:'The Matrix Reloaded'})
RETURN p AS b) y;
equal | less
-------+------
f | t
그 비교에는 tid 필드도 들어가므로, 그 경로가 뜻하는 것을 비교하는 것이 아니라 보행 전체의
식별자를 비교하는 것입니다. 추론할 수 있는 것을 원하면 nodes(p)나 id를 비교하십시오.
to_jsonb()는 Cypher에서든 SQL에서든 경로를 변환합니다. 그 결과는 내부 구조를 드러냅니다. 두 배열과
모든 구성원의 tid입니다. pg_cast에는 graphpath에서 jsonb로 가는 형 변환이 없습니다. 그래서
p::jsonb는 그것을 컴파일해 주는 Cypher에서는 동작하고, SQL에서는
cannot cast type graphpath to jsonb로 실패합니다.
rowid#
rowid는 테이블 OID와 행 포인터를 한 쌍으로 묶습니다. 최단 경로 실행기가 간선 식별자를 나르려고
내부에서 씁니다. 비교 연산자 여섯 개와 btree 연산자 클래스가 있고, 출력 함수는 없습니다:
SELECT rowid('moviekb.person'::regclass, ctid) FROM moviekb.person LIMIT 1;
ERROR: "rowid" type does not support output function
rowid_tableoid()와 rowid_ctid()가 두 절반을 읽으며, 그 값을 볼 수 있는 방법은 그것뿐입니다:
SELECT rowid_tableoid(rowid('moviekb.person'::regclass, '(0,1)')) AS tableoid,
rowid_ctid(rowid('moviekb.person'::regclass, '(0,1)')) AS ctid;
tableoid | ctid
----------+-------
16482 | (0,1)
그 OID는 해당 데이터베이스에서 moviekb.person이 우연히 갖게 된 값이므로, 설치할 때마다 다릅니다.
Cypher에서 rowid를 만들어 내는 것은 없고, 애플리케이션 코드에서 그것을 쓸 이유도 없습니다.
pg_type과 \dT에 나타나기 때문에 여기 문서화해 둔 것입니다.
그래프 타입의 배열#
vertex[], edge[], graphpath[]는 자기 출력 함수를 가진 평범한 PostgreSQL 배열 타입이므로, 그
요소와 같은 대괄호 방식으로 출력됩니다.
정점·간선·경로에 대한 collect()는 이런 네이티브 배열 중 하나를 반환합니다. 그 밖의 것에 대한
collect()는 jsonb를 반환합니다:
MATCH (:person {name: 'Keanu Reeves'})-[:acted_in]->(m:movie)
RETURN pg_typeof(collect(m)) AS collect_vertex, pg_typeof(collect(m.title)) AS collect_property;
collect_vertex | collect_property
----------------+------------------
"vertex[]" | "jsonb"
네이티브 배열은 각 요소의 jsonb 사본이 아니라 요소 자체를 담으므로, 그 구성원이 자기 식별자를
유지합니다. films[0]은 vertex이고, 거기서 속성을 읽거나 뒤따르는 절에서 그것을 따라갈 수
있습니다.
리스트 함수 몇 개는 jsonb용 오버로드와 네이티브 배열용 오버로드를 함께 갖고 있습니다. 어느 것을
받는지는 인자에서 따라옵니다. Cypher에서 인자는 보통 jsonb이므로 결과도 jsonb입니다. SQL에서
같은 함수에 실제 배열을 주면 실제 배열이 돌아옵니다. 시그니처는
타입 변환 함수에 있습니다.
배열 첨자의 시작#
Cypher는 리스트의 첨자를 0부터 세고 음수 첨자를 받으며, 그 규칙을 네이티브 배열에도 적용합니다:
MATCH (:person {name: 'Keanu Reeves'})-[:acted_in]->(m:movie)
WITH collect(m) AS films
RETURN films[0].title AS cypher_index_0, films[1].title AS cypher_index_1, size(films) AS n;
cypher_index_0 | cypher_index_1 | n
----------------+-----------------------+---
"The Matrix" | "The Matrix Reloaded" | 4
SQL에서 닿은 같은 배열은 PostgreSQL의 규칙을 따라 1부터 시작하고, 첨자 0은 범위를 벗어납니다:
SELECT (films[1]).properties ->> 'title' AS sql_index_1,
(films[0]).properties ->> 'title' AS sql_index_0
FROM (MATCH (:person {name: 'Keanu Reeves'})-[:acted_in]->(m:movie)
RETURN collect(m) AS films) q;
sql_index_1 | sql_index_0
-------------+-------------
The Matrix | null
unnest()가 그것을 다시 행으로 바꾸며, SQL에서는 보통 그것이 원하는 것입니다:
SELECT (v).id AS id, (v).properties ->> 'title' AS title
FROM (MATCH (:person {name: 'Keanu Reeves'})-[:acted_in]->(m:movie)
RETURN collect(m) AS films) q,
unnest(q.films) AS v ORDER BY id;
id | title
-----+--------------------------
3.1 | The Matrix
3.2 | The Matrix Reloaded
3.3 | The Matrix Revolutions
3.4 | The Matrix Resurrections
속성: jsonb#
레이블에는 jsonb 타입의 properties 컬럼이 하나 있고, 그 레이블의 모든 정점과 간선의 모든 속성이
그 안에 있습니다. 그래서 속성에는 선언된 타입이 없습니다. 그 타입은 값이 지닌 JSON 타입이 무엇이든
그것입니다.
속성 값이 될 수 있는 것#
JSON의 여섯 타입 모두입니다:
JSON 타입 |
Cypher 표기 |
비고 |
|---|---|---|
문자열 |
|
작은따옴표입니다. 이스케이프는 JSON의 규칙을 따릅니다. |
숫자 |
|
JSON 숫자 타입 하나뿐이고, 정수와 실수가 따로 없습니다. |
불리언 |
|
|
배열 |
|
타입을 섞을 수 있고 중첩됩니다. |
객체 |
|
키는 따옴표를 붙이지 않으면 소문자로 접힙니다. |
null |
|
null을 할당하면 그 속성이 지워집니다. |
MATCH (m:movie {title: 'The Matrix'})-[r:related_to]->()
RETURN jsonb_typeof(m.title) AS title, jsonb_typeof(m.embedding) AS embedding,
jsonb_typeof(r.weight) AS weight, jsonb_typeof(m.no_such_key) AS absent
LIMIT 1;
title | embedding | weight | absent
----------+-----------+----------+--------
"string" | "array" | "number" | null
없는 속성과 null인 속성은 같은 것입니다. 그래서 없는 키에 대한 jsonb_typeof는 "null"이 아니라
null입니다.
숫자 타입은 하나이지만 적은 소수 자릿수가 저장되고, 그것이 나눗셈에서 버림이 일어나는지를 결정합니다:
CREATE GRAPH demo;
SET graph_path = demo;
CREATE VLABEL t;
CREATE (:t {a: 7, b: 7.0});
MATCH (n:t) RETURN n.a AS a, n.b AS b, n.a / 2 AS a_div, n.b / 2 AS b_div;
a | b | a_div | b_div
---+-----+-------+--------------------
7 | 7.0 | 3 | 3.5000000000000000
n.a와 n.b는 둘 다 jsonb_typeof가 number이고 같다고 비교되므로, 이것은 두 개의 타입이
아닙니다. 소수 자릿수를 몇 개 받았는지 기억하는 하나의 타입입니다.
선언된 타입이 없으므로, 타입이 서로 다른 값의 순서는 jsonb 비교가 결정합니다. null, 그다음
문자열, 그다음 숫자, 그다음 불리언, 그다음 배열, 그다음 객체입니다. 그 순서는 PostgreSQL의
것입니다. 타입 컬럼으로 승격한 속성이 같은 속성을 properties에서 읽은 것과 다르게 정렬될 수 있는 이유가
그것입니다.
RETURN이 돌려주는 것#
Cypher의 RETURN은 각 스칼라 출력 컬럼을 jsonb로 감쌉니다. boolean은 불리언으로 남고, 그래프
타입은 자기 자신으로 남습니다:
SELECT pg_typeof(a) AS property, pg_typeof(b) AS property_cast_to_text,
pg_typeof(c) AS string_literal, pg_typeof(d) AS number_literal,
pg_typeof(e) AS boolean, pg_typeof(f) AS id, pg_typeof(g) AS vertex,
pg_typeof(h) AS path
FROM (MATCH p = (:person {name: 'Keanu Reeves'})-[:acted_in]->(m:movie {title: 'The Matrix'})
RETURN m.title AS a, m.title::text AS b, 'x' AS c, 1 AS d, true AS e,
id(m) AS f, m AS g, p AS h) q;
property | property_cast_to_text | string_literal | number_literal | boolean | id | vertex | path
----------+-----------------------+----------------+----------------+---------+---------+--------+-----------
jsonb | jsonb | jsonb | jsonb | boolean | graphid | vertex | graphpath
두 번째 컬럼을 보십시오. RETURN 안의 ::text 형 변환은 그 감싸기에 의해 무효가 되므로 아무것도
바꾸지 않습니다. 그래서 문자열은 JSON 따옴표와 함께 출력됩니다:
MATCH (m:movie {title: 'The Matrix'}) RETURN m.title AS title;
title
--------------
"The Matrix"
평범한 스칼라를 얻으려면 SQL에서 그 값을 jsonb에서 꺼내십시오. #>> '{}'이 문서 전체를 텍스트로
꺼냅니다:
SELECT title #>> '{}' AS title
FROM (MATCH (m:movie {title: 'The Matrix'}) RETURN m.title AS title) q;
title
------------
The Matrix
감싸는 방법은 SQL과 Cypher 섞기가 온전히 다룹니다. 이
감싸기는 속성에서 끌어낸 컬럼에만 적용됩니다. 불리언 표현식은 boolean으로, id(n)은 graphid로,
그래프 요소는 vertex·edge·graphpath로 남습니다. 타입 컬럼으로 승격된 속성도 예외입니다. 그
읽기는 그 컬럼에서 답하고 그 컬럼 자신의 타입으로 돌아옵니다.
:: 형 변환#
Cypher의 ::은 SQL의 것보다 적은 타입 이름 집합을 받습니다. text, date, uuid, jsonb,
inet 같은 맨 타입 이름이나 함수 이름을 받습니다. SQL 문법이 특별하게 다루는 묶음 표기도 받습니다.
수치 이름(int, integer, smallint, bigint, real, float, double precision, decimal,
numeric, boolean)과 문자 이름(char, varchar, character varying), 그리고 bit,
bit varying, json, interval입니다.
RETURN '42'::int AS i, '4.2'::numeric AS n, 'x'::text AS t, '101'::bit(3) AS b,
'1 day'::interval AS iv, 'true'::boolean AS bo, '2020-01-01'::date AS d;
i | n | t | b | iv | bo | d
----+-----+-----+-------+---------+----+--------------
42 | 4.2 | "x" | "101" | "1 day" | t | "2020-01-01"
이유는 형 변환이 타입을 어떻게 지칭하는가에 있습니다. Cypher의 형 변환은 평범한 타입 이름을
받습니다. 그리고 언어가 특별하게 다루는 수치·문자·비트·json·interval 표기도 받습니다. TIMESTAMP와
TIME도 특별한 표기인데, 빠진 것이 바로 그 둘입니다. 그래서 둘 다 거부됩니다:
RETURN '2020-01-01 10:00'::timestamp;
ERROR: syntax error at or near "timestamp"
LINE 1: RETURN '2020-01-01 10:00'::timestamp;
^
RETURN '10:00'::time;
ERROR: syntax error at or near "time"
LINE 1: RETURN '10:00'::time;
^
그 타입 이름에 따옴표를 붙이십시오. 인용된 이름은 키워드가 아니라 식별자이므로, 동작하는 규칙을 타고 갑니다. 같은 타입을 가리킵니다:
RETURN '2020-01-01 10:00'::"timestamp" AS ts, '10:00'::"time" AS t;
ts | t
-----------------------+------------
"2020-01-01T10:00:00" | "10:00:00"
그 밖의 시간 관련 타입은 모두 평범한 이름이라 따옴표가 필요하지 않으며, date와 timestamptz도
그렇습니다:
RETURN pg_typeof('2020-01-01'::date) AS d, pg_typeof('2020-01-01'::timestamptz) AS tz;
d | tz
--------+----------------------------
"date" | "timestamp with time zone"
다른 길은 Cypher 밖에서 형 변환하는 것이며, 거기서는 SQL 문법 전체를 쓸 수 있습니다:
SELECT (t #>> '{}')::timestamp AS released FROM (RETURN '2020-01-01 10:00' AS t) q;
released
---------------------
2020-01-01 10:00:00
두 결과의 차이를 보십시오. Cypher 안에서는 값이 다시 jsonb로 감싸이므로 JSON의 ISO 형태로 따옴표와
함께 출력됩니다. SQL 형 변환은 실제 timestamp를 주고, 그 타입의 출력 함수가 그것을 출력합니다.
알아 둘 비대칭이 하나 더 있습니다. 문자열 리터럴에 쓴 '…'::jsonb는 파싱된 문서가 아니라 jsonb
문자열을 만듭니다. 그 리터럴이 이미 JSON 문자열이기 때문입니다. Cypher에서 jsonb 객체를
만들려면 맵 리터럴을 쓰십시오:
RETURN '{"a": 1}'::jsonb AS as_string, {a: 1} AS as_map;
as_string | as_map
--------------+----------
"{\"a\": 1}" | {"a": 1}
쓸 수 있는 PostgreSQL 타입#
전부입니다. 그래프는 여러분의 테이블과 같은 데이터베이스에 있으므로, PostgreSQL 데이터 타입 장의 모든 타입을 그대로 쓸 수 있습니다. 수치, 문자, 날짜·시각, 불리언, 열거, 기하, 네트워크 주소, 비트 문자열, 텍스트 검색, UUID, XML, JSON, 배열, 복합, 범위, 도메인, 객체 식별자가 그렇습니다. 확장이 더한 타입도 쓸 수 있습니다.
PostgreSQL 타입이 그래프와 만나는 자리가 세 곳입니다:
그래프 옆의 보통 테이블이며, 한 문장에서 그래프와 조인합니다.
timestamptz,numeric(10,2),tsvector의 의미와 연산자가 필요할 때 그것들이 있어야 할 자리가 여기입니다.레이블의 승격된 컬럼입니다. 속성 하나를 실제 타입의 실제 컬럼으로 구체화하므로, 그 속성이 그 타입의 순서·비교·인덱스 지원을 얻습니다.
속성이나 승격된 컬럼에 저장한 확장 타입입니다.
pgvector의vector가 벡터 검색이 기반으로 삼는 경우입니다.
속성 자체는 그 타입들 중 어느 것도 될 수 없습니다. 속성은 jsonb이고, 그 안에 넣은 값은 들어가는
길에 JSON 타입으로 변환됩니다.
호환성#
openCypher#
vertex, edge, graphpath가 openCypher 타입 체계의 node·relationship·path에 해당합니다. 여기서 스칼라
타입은 따로 있지 않습니다. 문자열·숫자·불리언·리스트·맵이 모두 jsonb입니다. 그래서 어떤 숫자가
정수인지 소수인지는 선언된 타입이 아니라 그 값에서 옵니다.
시간 값은 그래프 타입이 아닙니다. date, timestamptz, interval은 PostgreSQL의 것이고, 형 변환·
보통 컬럼·승격된 컬럼을 통해 닿습니다. 그래프 수준의 datetime이나 duration은 없습니다. 차이의
전체 목록은 Cypher 호환성입니다.
ISO/IEC 39075#
표준의 속성 그래프 타입도 같은 방식으로 vertex·edge·graphpath에 대응됩니다. 속성이 선언된
타입을 지니는 표준의 타입 있는 값 모형은 승격된 컬럼이 제공합니다.
GQL 적합성을 참고하십시오.
관련 항목#
구문 — 리터럴, 연산자, 그리고 값을 적는 방법
서버 설정 —
allow_null_properties와enable_property_promotion그래프가 어떻게 저장되는가 — 레이블 테이블은 무엇으로 되어 있는가
SQL과 Cypher 섞기 — 경계를 넘어 값을 옮기기
시스템 카탈로그 —
ag_graph,ag_label등PostgreSQL: 데이터 타입 — 그 밖에 쓸 수 있는 모든 타입