ALTER VLABEL과 ALTER ELABEL#
레이블의 이름을 바꾸고, 저장 방식을 바꾸고, 부모를 붙이거나 떼고, 인덱스를 끄고, 승격된 타입 컬럼을 추가하거나 제거합니다.
개요#
ALTER VLABEL [ IF EXISTS ] label_name RENAME TO new_label_name
ALTER ELABEL [ IF EXISTS ] label_name action [, ... ]
ALTER ELABEL [ IF EXISTS ] label_name RENAME TO new_label_name
where action is one of:
ADD [ COLUMN ] promoted_property
DROP [ COLUMN ] column_name [ CASCADE | RESTRICT ]
DISABLE INDEX
SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
SET TABLESPACE tablespace_name
SET { LOGGED | UNLOGGED }
CLUSTER ON index_name
SET WITHOUT CLUSTER
INHERIT parent_label
NO INHERIT parent_label
REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }
OWNER TO role_specification
굵게 키워드 · 기울임 직접 채우는 자리 · [ ] 생략 가능 · ... 반복 가능. 구문 표기 규약을 참고하십시오.
설명#
ALTER VLABEL은 정점 레이블에, ALTER ELABEL은 간선 레이블에 작용합니다. 키워드를 빼면 두 문장은
같습니다. 위에 나열한 모든 동작이 두 종류 모두에서 받아들여집니다. 다른 것은 그 동작이 작용할
대상을 각 레이블 종류가 무엇으로 갖고 있는가입니다.
레이블이 만들어질 때 함께 생기는 인덱스가 다릅니다. 정점 레이블에는
id에 대한 기본 키가 생기고, 간선 레이블에는(start, "end")와("end", start)에 걸린 btree 인덱스와id에 걸린 BRIN 인덱스가 생깁니다.DISABLE INDEX는 어느 쪽이든 그 레이블의 모든 인덱스를 무효로 만들므로, 갓 만든 정점 레이블에서는 무효로 만들 것이 하나이고 간선 레이블에서는 셋입니다.CLUSTER ON도 고를 수 있는 이름이 다릅니다.DROP COLUMN이 거부하는 구조 컬럼은 정점 레이블에서id와properties이고, 간선 레이블에는start와end가 더해집니다.INHERIT와NO INHERIT는 그 레이블과 같은 종류이고 같은 그래프에 있는 부모를 요구합니다.
레이블은 graph_path가 지정한 그래프에서 찾습니다. 그 이름은 수식할 수 없습니다.
RENAME TO는 그 자체로 하나의 형태입니다. 다른 어떤 동작과도 함께 쓸 수 없고, 여러 동작을 나열한 목록에 들어갈 수도 없습니다.한 문장의 여러 동작은 쉼표로 구분하며 적은 순서대로 적용됩니다.
기반 레이블인
ag_vertex와ag_edge는 아예 변경할 수 없습니다.ALTER VLABEL은 간선 레이블을 거부하고ALTER ELABEL은 정점 레이블을 거부합니다.
대신 ALTER TABLE로 레이블의 모양을 바꾸는 것은 enable_graph_ddl을 켜 두지 않으면 거부됩니다.
그래프 카탈로그가 레이블의 컬럼을 설명하는데, ALTER TABLE은 그것을 갱신하지 않습니다. 그 관문에
대해서는 그래프가 어떻게 저장되는가가
다룹니다.
매개변수#
- IF EXISTS
그 레이블이 없을 때 오류가 아니라 알림을 냅니다.
- label_name
변경할 레이블이며,
graph_path가 지정한 그래프 안에서 찾습니다.- RENAME TO new_label_name
레이블에 새 이름을 줍니다. 정점과 간선은 자기 id를 유지하므로, 이름을 바꾸기 전에 만든 행에 대해서도
label()이 새 이름을 보고합니다. 그 테이블의 시퀀스와 인덱스는 처음 받은 이름을 유지하므로,CLUSTER ON을 쓰기 전에 그것을 확인하십시오.- ADD [ COLUMN ] promoted_property
승격된 타입 컬럼을 추가하고 이미 있는 행에서 그것을 채웁니다.
promoted_property는CREATE VLABEL과 같은 세 형태를 받고 제한도 같습니다. 그 레이블에서 이미 승격된 속성은 거부되며, 한 문장에서 같은 키를 두 번 승격하는 것도 거부됩니다.- DROP [ COLUMN ] column_name [ CASCADE | RESTRICT ]
컬럼을 지우고, 승격된 속성이라면 그 대응 관계도 잊습니다. 레이블의 구조 컬럼은 거부됩니다. 지운 컬럼에 걸려 있던 인덱스도 함께 사라집니다.
- DISABLE INDEX
그 레이블의 모든 인덱스를 무효로 표시해, 대량 적재가 그것을 유지하지 않게 합니다. 읽기와 쓰기는 계속 동작하고 플래너는 무효 인덱스를 무시합니다.
ENABLE INDEX는 없습니다. 되돌아가는 길은REINDEX VLABEL입니다.- SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
레이블의
properties컬럼의 저장 방식을 정합니다. 이 방식이 큰 속성 맵을 인라인으로 둘지 그 테이블의 TOAST 관계에 둘지, 그리고 압축할지를 결정합니다. 레이블은EXTENDED로 시작하며, 그것은 인라인이 아니면서 압축하는 방식입니다. 이 문장은 이후 쓰기에 대한 전략을 바꿀 뿐, 이미 저장된 것을 다시 쓰지는 않습니다.- SET TABLESPACE tablespace_name
레이블의 테이블을 다른 테이블스페이스로 옮깁니다. 그 인덱스는 있던 자리에 남습니다.
- SET { LOGGED | UNLOGGED }
레이블 테이블의 미리 쓰기 로깅을 켜거나 끕니다. 그 레이블의 id 시퀀스도 함께 영속성이 바뀝니다.
- CLUSTER ON index_name
나중의
CLUSTER가 쓸 인덱스로 어떤 인덱스를 기록해 둡니다. 지금 무언가를 재배열하지는 않습니다.- SET WITHOUT CLUSTER
그 기록을 잊습니다.
- INHERIT parent_label
그 레이블을 같은 그래프의 같은 종류 레이블의 자식으로 붙여, 부모에 대한 패턴이 이 레이블의 행에도 일치하기 시작하게 합니다.
- NO INHERIT parent_label
그 관계를 제거합니다.
- REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }
논리 복제를 위해, 쓰기가 행을 식별하려고 WAL에 기록하는 이전 값을 무엇으로 할지 고릅니다.
- OWNER TO role_specification
그 레이블을 다른 롤에게 넘깁니다. 롤 이름,
CURRENT_ROLE,CURRENT_USER,SESSION_USER중 하나를 씁니다.
예제#
예제는 예제 데이터셋을 쓰지 않고 자체 그래프인
catalogue를 만들고, 끝에서 그것을 지웁니다.
CREATE GRAPH catalogue;
SET graph_path = catalogue;
CREATE VLABEL film;
CREATE (:film {title: 'Arrival', year: 2016}), (:film {title: 'Dune', year: 2021});
레이블 이름 바꾸기#
ALTER VLABEL film RENAME TO movie;
\dGl catalogue.mov*
List of labels
Graph | Name | Type | Owner
-----------+-------+--------+-------
catalogue | movie | vertex | agens
(1 row)
행도 함께 따라왔습니다:
MATCH (m:movie) RETURN count(m) AS movies;
movies
--------
2
(1 row)
시퀀스와 기본 키는 여전히 옛 이름을 지니고 있습니다:
\d catalogue.movie
Table "catalogue.movie"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+----------------------------------------------------------------------------------------------
id | graphid | | not null | graphid(graph_labid('catalogue.movie'::cstring), nextval('catalogue.film_id_seq'::regclass))
properties | jsonb | | not null | jsonb_build_object()
Indexes:
"film_pkey" PRIMARY KEY, btree (id)
Inherits: catalogue.ag_vertex
그래서 ALTER VLABEL movie CLUSTER ON movie_pkey는
index "movie_pkey" for table "movie" does not exist로 실패하고, 써야 할 이름은 film_pkey입니다.
대량 적재를 위해 레이블의 인덱스 끄기#
ALTER VLABEL movie DISABLE INDEX;
\d catalogue.movie
Table "catalogue.movie"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+----------------------------------------------------------------------------------------------
id | graphid | | not null | graphid(graph_labid('catalogue.movie'::cstring), nextval('catalogue.film_id_seq'::regclass))
properties | jsonb | | not null | jsonb_build_object()
Indexes:
"film_pkey" PRIMARY KEY, btree (id) INVALID
Inherits: catalogue.ag_vertex
행을 적재하고, 그다음 인덱스를 다시 만듭니다:
REINDEX VLABEL movie;
REINDEX
행이 이미 있는 레이블에서 속성 승격하기#
ALTER VLABEL movie ADD COLUMN year int GENERATED;
\d catalogue.movie
Table "catalogue.movie"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+-----------------------------------------------------------------------------------------------
id | graphid | | not null | graphid(graph_labid('catalogue.movie'::cstring), nextval('catalogue.film_id_seq'::regclass))
properties | jsonb | | not null | jsonb_build_object()
year | integer | | | generated always as (ag_property_text(properties, 'year'::text, 'n'::"char")::integer) stored
Indexes:
"film_pkey" PRIMARY KEY, btree (id)
Inherits: catalogue.ag_vertex
이미 있는 행이 채워지므로, 그 문장이 돌아오는 순간 컬럼은 이미 완전합니다:
SELECT year FROM catalogue.movie ORDER BY year;
year
------
2016
2021
(2 rows)
레이블이 무엇을 승격했는지 조회하기#
ag_label_property가 속성 키를 그것을 대신해 답하는 컬럼에 대응시킵니다:
ALTER VLABEL movie ADD COLUMN released text GENERATED (releaseDate);
SELECT p.propname, p.attnum FROM pg_catalog.ag_label_property p
JOIN pg_catalog.ag_label l ON l.oid = p.laboid
JOIN pg_catalog.ag_graph g ON g.oid = l.graphid
WHERE g.graphname = 'catalogue' AND l.labname = 'movie' ORDER BY p.attnum;
propname | attnum
-------------+--------
year | 3
releasedate | 4
(2 rows)
attnum은 그 테이블에서 컬럼의 위치입니다. 컬럼 이름까지 원한다면 그것으로 pg_attribute와
조인하십시오. 키를 명시하는 형태를 썼다면 그 둘이 다릅니다.
승격된 컬럼 지우기#
ALTER VLABEL movie DROP COLUMN released;
그 대응 관계도 컬럼과 함께 사라집니다:
SELECT p.propname, p.attnum FROM pg_catalog.ag_label_property p
JOIN pg_catalog.ag_label l ON l.oid = p.laboid
JOIN pg_catalog.ag_graph g ON g.oid = l.graphid
WHERE g.graphname = 'catalogue' AND l.labname = 'movie' ORDER BY p.attnum;
propname | attnum
----------+--------
year | 3
(1 row)
releasedate를 읽으면 properties로 돌아갑니다. properties에서 지워진 것은 없습니다.
속성 맵의 저장 방식 바꾸기#
ALTER VLABEL movie SET STORAGE external;
어느 컬럼을 예상했든, 그 방식은 properties에 설정됩니다:
SELECT attname, attstorage FROM pg_attribute
WHERE attrelid = 'catalogue.movie'::regclass AND attnum > 0 AND NOT attisdropped;
attname | attstorage
------------+------------
id | p
properties | e
year | p
(3 rows)
부모 붙이고 떼기#
CREATE VLABEL work;
ALTER VLABEL movie INHERIT work;
\dGv catalogue.movie
List of labels
Graph | Name | Type | Owner
-----------+-------+--------+-------
catalogue | movie | vertex | agens
(1 row)
Vertex label "catalogue.movie"
--
Inherits: catalogue.ag_vertex,
catalogue.work
이제 movie에는 부모가 둘입니다. 처음부터 있던 기반 레이블과 work입니다. 떼어 내도 기반 레이블은
그대로입니다:
ALTER VLABEL movie NO INHERIT work;
ALTER VLABEL
알아 둘 만한 거부 사례#
구조 컬럼은 지울 수 없습니다:
ALTER VLABEL movie DROP COLUMN properties;
ERROR: cannot drop column "properties" of graph label "movie"
HINT: It is a structural column of the graph label.
추가하는 컬럼은 properties에서 생성되는 것이어야 합니다:
ALTER VLABEL movie ADD COLUMN rank int;
ERROR: a non-generated promoted column is not supported yet
HINT: Use GENERATED to mirror the property from the jsonb bag.
이미 승격된 속성을 두 번 승격할 수는 없습니다:
ALTER VLABEL movie ADD COLUMN yr2 int GENERATED (year);
ERROR: property "year" is already promoted on graph label "movie"
HINT: Drop the existing promoted column first, or promote the property to a different column name.
기반 레이블은 부모로든 대상으로든 손댈 수 없습니다:
ALTER VLABEL movie INHERIT ag_vertex;
ERROR: cannot ALTER inheritance with base label
ALTER VLABEL ag_vertex SET STORAGE main;
ERROR: ALTER base vertex label is prohibited
각 문장은 한 종류의 레이블에만 작용합니다:
CREATE ELABEL directed;
ALTER VLABEL directed RENAME TO helmed;
ERROR: RENAME VLABEL cannot RENAME edge label
그리고 RENAME TO는 홀로 섭니다:
ALTER VLABEL movie RENAME TO film, SET STORAGE main;
ERROR: syntax error at or near ","
LINE 1: ALTER VLABEL movie RENAME TO film, SET STORAGE main;
^
enable_graph_ddl이 꺼져 있는 동안에는 SQL로 레이블의 테이블 모양을 바꾸는 것이 거부됩니다:
ALTER TABLE catalogue.movie ADD COLUMN rank int;
ERROR: cannot add a column to graph label "movie" with ALTER TABLE
HINT: Use ALTER VLABEL or ALTER ELABEL instead, which keeps the graph catalog in step.
마지막으로 예제가 만든 그래프를 지웁니다:
DROP GRAPH catalogue CASCADE;
참고#
SET STORAGE는 다섯이 아니라 네 개의 키워드를 받습니다. DEFAULT는 예약어이고 여기서는 구문
오류입니다. 레이블이 처음 갖는 방식으로 돌아가려면 SET STORAGE extended로 쓰십시오. 알 수 없는
단어는 invalid storage type "..."으로 보고됩니다.
IF EXISTS 알림은 두 형태에서 다릅니다. RENAME TO는
label "nosuch" does not exist, skipping을, 동작 목록은
graph label "nosuch" does not exist, skipping을 냅니다. 그다음 둘 다 성공을 보고하고 아무것도 하지
않습니다.
호환성#
ISO/IEC 39075 (GQL)#
GQL에는 레이블을 변경하는 문장이 없습니다. 변경할 레이블이 없기 때문입니다. 요소 타입은 그래프
타입에 속하고, 그래프 타입은 통째로 만들어지고 지워집니다(<create graph type statement>, §12.6).
레이블 이름 바꾸기, 속성 승격, 인덱스 끄기에 대응하는 것이 GQL에는 없습니다. 그래프 타입은
GQL 적합성 표에 계획으로 기록돼 있습니다.
PostgreSQL#
여기 있는 모든 동작은 ALTER TABLE의 동작이고, 각각 거기서와 같은 뜻이며 두 가지만 조정됐습니다.
SET STORAGE는 컬럼을 지정하지 않습니다. 저장 방식을 고를 만한 컬럼은 properties 하나뿐이므로 그
컬럼에 적용됩니다. DISABLE INDEX에는 ALTER TABLE 대응물이 아예 없습니다. 그것은 레이블의 인덱스를
무효로 표시하는데, SQL에서는 CREATE INDEX CONCURRENTLY를 중단시키는 것 말고는 그렇게 만들 방법이
없습니다.
반대 방향으로는, 레이블의 테이블에 대한 ALTER TABLE이 그 모양을 바꾸는 동작에 대해서는
enable_graph_ddl을 켜 두지 않으면 거부됩니다. 컬럼을 추가하거나 지우거나 타입을 바꾸는 것이 그런
동작입니다. 위의 예제가 그 거부를 보여 줍니다. 이 페이지의 동작들은 그 설정을 결코 필요로 하지
않습니다. 그래프 카탈로그를 스스로 갱신하기 때문입니다.