이 문서에서는 효율적인 쿼리, 최적화된 에지 순회, 효과적인 데이터 관리 기법에 중점을 두고 Spanner Graph 스키마 설계 권장사항을 설명합니다.
Spanner 스키마 (Spanner Graph 스키마 아님) 설계에 관한 자세한 내용은 스키마 설계 권장사항을 참고하세요.
스키마 디자인 선택
스키마 설계는 그래프 성능에 영향을 미칩니다. 다음 주제에서는 효과적인 전략을 선택하는 방법을 안내합니다.
스키마가 있는 설계와 스키마가 없는 설계
스키마화된 설계는 그래프 정의를 Spanner Graph 스키마에 저장하므로 정의 변경이 드문 안정적인 그래프에 적합합니다. 스키마는 그래프 정의를 적용하고 속성은 모든 Spanner 데이터 유형을 지원합니다.
스키마 없음 설계는 데이터에서 그래프 정의를 추론하므로 스키마 변경 없이 더 많은 유연성을 제공합니다. 동적 라벨과 속성은 기본적으로 적용되지 않습니다. 속성은 유효한 JSON 값이어야 합니다.
다음은 스키마와 스키마 없는 데이터 관리의 주요 차이점을 요약한 것입니다. 또한 그래프 쿼리를 고려하여 사용할 스키마 유형을 결정하세요.
기능 | 스키마가 적용된 데이터 관리 | 스키마 없는 데이터 관리 |
---|---|---|
그래프 정의 저장 | 그래프 정의는 Spanner Graph 스키마에 저장됩니다. | 그래프 정의는 데이터에서 명확하게 드러납니다. 하지만 Spanner Graph는 정의를 추론하기 위해 데이터를 검사하지 않습니다. |
그래프 정의 업데이트 | Spanner Graph 스키마 변경이 필요합니다. 정의가 잘 정의되어 있고 자주 변경되지 않는 경우에 적합합니다. | Spanner Graph 스키마를 변경할 필요가 없습니다. |
그래프 정의 적용 | 속성 그래프 스키마는 허용된 노드 유형을 간선에 적용합니다. 또한 그래프 노드 또는 에지 유형의 허용된 속성 및 속성 유형을 적용합니다. | 기본적으로는 적용되지 않습니다. 확인 제약 조건을 사용하여 라벨 및 속성 데이터 무결성을 적용할 수 있습니다. |
속성 데이터 유형 | timestamp 와 같은 Spanner 데이터 유형을 지원합니다. |
동적 속성은 유효한 JSON 값이어야 합니다. |
그래프 쿼리를 기반으로 스키마 설계 선택
스키마가 있는 설계와 스키마가 없는 설계는 성능이 비슷한 경우가 많습니다. 하지만 쿼리에서 여러 노드 또는 에지 유형에 걸쳐 있는 정량화된 경로 패턴을 사용하는 경우 스키마가 없는 설계가 더 나은 성능을 제공합니다.
기본 데이터 모델이 그 이유입니다. 스키마 없는 설계는 DYNAMIC LABEL
에서 강제하는 단일 노드 및 에지 테이블에 모든 데이터를 저장합니다.
여러 유형을 순회하는 쿼리는 테이블 스캔을 최소화하여 실행됩니다.
반면 스키마화된 설계에서는 일반적으로 각 노드 및 에지 유형에 별도의 테이블을 사용하므로 여러 유형에 걸친 쿼리는 해당 테이블의 데이터를 모두 스캔하고 결합해야 합니다.
다음은 스키마가 없는 설계에 적합한 샘플 쿼리와 두 설계 모두에 적합한 샘플 쿼리입니다.
스키마 없는 설계
다음 쿼리는 여러 유형의 노드와 에지를 일치시킬 수 있는 정량화된 경로 패턴을 사용하므로 스키마 없는 설계에서 성능이 더 뛰어납니다.
이 쿼리의 수량화된 경로 패턴은 여러 에지 유형 (
Transfer
또는Withdraw
)을 사용하며 홉이 하나보다 긴 경로의 중간 노드 유형을 지정하지 않습니다.GRAPH FinGraph MATCH p = (:Account {id:1})-[:Transfer|Withdraw]->{1,3}(:Account) RETURN TO_JSON(p) AS p;
이 쿼리의 수량화된 경로 패턴은 긴 경로의 중간 노드 유형을 지정하지 않고 여러 에지 유형 (
Owns
또는Transfers
)을 사용하여Person
및Account
노드 간의 홉이 1~3개인 경로를 찾습니다. 이를 통해 경로가 다양한 유형의 중간 노드를 통과할 수 있습니다. 예를 들면(:Person)-[:Owns]->(:Account)-[:Transfers]->(:Account)
입니다.GRAPH FinGraph MATCH p = (:Person {id:1})-[:Owns|Transfers]->{1,3}(:Account) RETURN TO_JSON(p) AS p;
이 쿼리의 수치화된 경로 패턴은 에지 라벨을 지정하지 않고
Person
노드와Account
노드 사이의 홉이 1~3개인 경로를 찾습니다. 이전 쿼리와 마찬가지로 다양한 유형의 중간 노드를 통과하는 경로를 허용합니다.GRAPH FinGraph MATCH p = (:Person {id:1})-[]->{1,3}(:Account) RETURN TO_JSON(p) AS p;
이 쿼리는 모든 방향 (
-[:Owns]-
)에서Owns
유형의 에지를 사용하여Account
노드 사이의 1~3홉 경로를 찾습니다. 경로는 어느 방향으로든 에지를 통과할 수 있고 중간 노드가 지정되지 않으므로 2홉 경로는 서로 다른 유형의 노드를 통과할 수 있습니다. 예를 들면(:Account)-[:Owns]-(:Person)-[:Owns]-(:Account)
입니다.GRAPH FinGraph MATCH p = (:Account {id:1})-[:Owns]-{1,3}(:Account) RETURN TO_JSON(p) AS p;
두 디자인 모두
다음 쿼리는 스키마가 있는 설계와 스키마가 없는 설계 모두에서 유사하게 실행됩니다. 정량화된 경로 (:Account)-[:Transfer]->{1,3}(:Account)
에는 노드 유형 Account
하나와 에지 유형 Transfer
하나가 포함됩니다. 경로에 하나의 노드 유형과 하나의 에지 유형만 포함되므로 두 설계의 성능은 비슷합니다. 중간 노드에 명시적으로 라벨이 지정되어 있지 않더라도 패턴은 중간 노드가 Account
노드여야 한다고 제한합니다. Person
노드가 정량화된 경로 외부에 표시됩니다.
GRAPH FinGraph
MATCH p = (:Person {id:1})-[:Owns]->(:Account)-[:Transfer]->{1,3}(:Account)
RETURN TO_JSON(p) AS p;
Spanner Graph 스키마 성능 최적화
스키마가 있는 또는 스키마가 없는 Spanner Graph 스키마를 선택한 후 다음과 같은 방법으로 성능을 최적화할 수 있습니다.
에지 순회 최적화
에지 순회는 특정 노드에서 시작하여 다른 노드에 도달하기 위해 연결된 에지를 따라 이동하는 방식으로 에지를 따라 그래프를 이동하는 프로세스입니다. 스키마는 가장자리의 방향을 정의합니다. 에지 순회는 Spanner Graph의 기본적인 작업이므로 에지 순회의 효율성을 높이면 애플리케이션의 성능을 크게 개선할 수 있습니다.
두 가지 방향으로 에지를 순회할 수 있습니다.
- 정방향 에지 순회는 소스 노드의 발신 에지를 따릅니다.
- 역방향 에지 순회는 대상 노드의 수신 에지를 따릅니다.
정방향 및 역방향 에지 순회 쿼리 예시
다음 예시 쿼리에서는 지정된 사용자를 기준으로 Owns
에지의 정방향 에지 순회를 수행합니다.
GRAPH FinGraph
MATCH (person:Person {id: 1})-[owns:Owns]->(accnt:Account)
RETURN accnt.id;
다음 예시 쿼리에서는 지정된 계정에 대해 Owns
에지의 역방향 에지 순회를 수행합니다.
GRAPH FinGraph
MATCH (accnt:Account {id: 1})<-[owns:Owns]-(person:Person)
RETURN person.name;
정방향 에지 순회 최적화
정방향 에지 순회 성능을 개선하려면 소스에서 에지로, 에지에서 대상으로의 순회를 최적화하세요.
소스에서 에지로의 순회를 최적화하려면
INTERLEAVE IN PARENT
절을 사용하여 에지 입력 테이블을 소스 노드 입력 테이블에 인터리브 처리합니다. 인터리브 처리는 Spanner에서 하위 테이블 행을 스토리지에 있는 해당 상위 행과 함께 공동 배치하는 스토리지 최적화 기법입니다. 인터리브 처리에 대한 자세한 내용은 스키마 개요를 참고하세요.에지에서 대상까지의 순회를 최적화하려면 에지와 대상
노드 사이에 외래 키 제약 조건을 만듭니다. 이렇게 하면 대상 테이블 검색을 없애 성능을 개선할 수 있는 에지-대상 제약 조건이 적용됩니다. 강제 외래 키로 인해 쓰기 성능 병목 현상이 발생하는 경우 (예: 허브 노드 업데이트 시) 대신 정보 외래 키를 사용하세요.
다음 예시에서는 강제 및 정보 외래 키 제약 조건과 함께 인터리브를 사용하는 방법을 보여줍니다.
강제 외래 키
이 에지 테이블 예시에서 PersonOwnAccount
는 다음을 수행합니다.
소스 노드 테이블
Person
에 인터리브 처리합니다.대상 노드 테이블
Account
에 강제 외래 키를 만듭니다.
CREATE TABLE Person (
id INT64 NOT NULL,
name STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
close_time TIMESTAMP,
) PRIMARY KEY (id)
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id)
REFERENCES Account (id)
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
정보 외래 키
이 에지 테이블 예시에서 PersonOwnAccount
는 다음을 수행합니다.
소스 노드 테이블
Person
에 인터리브 처리합니다.대상 노드 테이블
Account
에 정보 외래 키를 만듭니다.
CREATE TABLE Person (
id INT64 NOT NULL,
name STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
close_time TIMESTAMP,
) PRIMARY KEY (id)
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id)
REFERENCES Account (id) NOT ENFORCED
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
역방향 에지 순회 최적화
역방향 또는 양방향 순회가 포함된 쿼리가 일반적이므로 쿼리에서 정방향 순회만 사용하지 않는 한 역방향 에지 순회를 최적화하세요.
역방향 에지 순회를 최적화하려면 다음을 실행하세요.
에지 테이블에 보조 색인을 만듭니다.
인덱스를 대상 노드 입력 테이블에 인터리브하여 에지를 대상 노드와 공동 배치합니다.
색인에 가장자리 속성을 저장합니다.
이 예시에서는 PersonOwnAccount
에지 테이블의 역방향 에지 순회를 최적화하는 보조 색인을 보여줍니다.
INTERLEAVE IN
절은 색인 데이터를 대상 노드 테이블Account
와 함께 배치합니다.STORING
절은 색인에 에지 속성을 저장합니다.
색인 인터리브 처리에 대한 자세한 내용은 색인 및 인터리브 처리를 참고하세요.
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
CREATE INDEX AccountOwnedByPerson
ON PersonOwnAccount (account_id)
STORING (create_time),
INTERLEAVE IN Account;
보조 색인을 사용하여 속성 필터링
보조 색인을 사용하면 특정 속성 값을 기반으로 노드와 가장자리를 효율적으로 조회할 수 있습니다. 색인을 사용하면 전체 테이블 스캔을 방지할 수 있으며 특히 큰 그래프에 유용합니다.
속성별 노드 필터링 속도 향상
다음 쿼리는 지정된 닉네임의 계정을 찾습니다. 보조 색인을 사용하지 않으므로 일치하는 결과를 찾기 위해 모든 Account
노드를 스캔해야 합니다.
GRAPH FinGraph
MATCH (acct:Account)
WHERE acct.nick_name = "abcd"
RETURN acct.id;
스키마에서 필터링된 속성에 보조 색인을 만들어 필터링 프로세스를 가속화합니다.
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
is_blocked BOOL,
nick_name STRING(MAX),
) PRIMARY KEY (id);
CREATE INDEX AccountByNickName
ON Account (nick_name);
속성별 에지 필터링 속도 향상
보조 색인을 사용하여 속성 값을 기반으로 하는 에지 필터링 성능을 개선할 수 있습니다.
정방향 에지 순회
보조 색인이 없으면 이 쿼리는 create_time
필터와 일치하는 에지를 찾기 위해 한 사람의 모든 에지를 스캔해야 합니다.
GRAPH FinGraph
MATCH (person:Person)-[owns:Owns]->(acct:Account)
WHERE person.id = 1
AND owns.create_time >= PARSE_TIMESTAMP("%c", "Thu Dec 25 07:30:00 2008")
RETURN acct.id;
다음 코드는 에지 소스 노드 참조 (id
) 및 에지 속성 (create_time
)에 보조 색인을 만들어 쿼리 효율성을 향상시킵니다. 또한 쿼리는 색인을 소스 노드 입력 테이블의 인터리브 처리된 하위 요소로 정의하여 색인을 소스 노드와 함께 배치합니다.
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
CREATE INDEX PersonOwnAccountByCreateTime
ON PersonOwnAccount (id, create_time)
INTERLEAVE IN Person;
역방향 에지 순회
보조 색인이 없으면 다음 역방향 에지 순회 쿼리는 지정된 create_time
이후에 지정된 계정을 소유한 사용자를 찾기 전에 모든 에지를 읽어야 합니다.
GRAPH FinGraph
MATCH (acct:Account)<-[owns:Owns]-(person:Person)
WHERE acct.id = 1
AND owns.create_time >= PARSE_TIMESTAMP("%c", "Thu Dec 25 07:30:00 2008")
RETURN person.id;
다음 코드는 에지 대상 노드 참조 (account_id
) 및 에지 속성(create_time
)에 보조 색인을 만들어 쿼리 효율성을 향상시킵니다. 또한 쿼리는 색인을 대상 노드 테이블의 인터리브된 하위 요소로 정의하여 색인을 대상 노드와 함께 배치합니다.
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
CREATE INDEX AccountOwnedByPersonByCreateTime
ON PersonOwnAccount (account_id, create_time),
INTERLEAVE IN Account;
댕글링 에지 방지
노드 0개 또는 1개를 연결하는 에지(매달린 에지)는 Spanner Graph 쿼리 효율성과 그래프 구조 무결성을 저해할 수 있습니다. 연결된 에지를 삭제하지 않고 노드를 삭제하면 댕글링 에지가 발생할 수 있습니다. 에지를 만들었지만 소스 또는 대상 노드가 존재하지 않는 경우에도 댕글링 에지가 발생할 수 있습니다. 고립된 가장자리를 방지하려면 Spanner Graph 스키마에 다음을 통합하세요.
- 참조 제약 조건 사용
- 선택사항: 아직 연결되어 있는 에지가 포함된 노드를 삭제할 때
ON DELETE CASCADE
절을 사용합니다.ON DELETE CASCADE
를 사용하지 않으면 해당 가장자리를 삭제하지 않고 노드를 삭제하려고 하면 실패합니다.
참조 제약 조건 사용
다음 단계를 따라 두 엔드포인트 모두에서 인터리빙과 강제 외래 키를 사용하여 연결되지 않은 에지를 방지할 수 있습니다.
에지의 소스 노드가 항상 존재하도록 에지 입력 테이블을 소스 노드 입력 테이블에 인터리브 처리합니다.
에지의 대상 노드가 항상 존재하도록 에지에 강제 외래 키 제약 조건을 만듭니다. 적용된 외래 키는 댕글링 에지를 방지하지만 에지 삽입 및 삭제 비용이 더 많이 듭니다.
다음 예에서는 강제 외래 키를 사용하고 INTERLEAVE IN PARENT
절을 사용하여 에지 입력 테이블을 소스 노드 입력 테이블에 인터리브 처리합니다. 강제 외래 키와 인터리브 처리를 함께 사용하면 정방향 에지 순회를 최적화할 수도 있습니다.
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id) ON DELETE CASCADE,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
ON DELETE CASCADE
로 에지 삭제
인터리브 처리 또는 강제 외래 키를 사용하여 댕글링 에지를 방지할 때는 Spanner 그래프 스키마에서 ON DELETE CASCADE
절을 사용하여 노드를 삭제하는 동일한 트랜잭션에서 노드의 연결된 에지를 삭제합니다.
자세한 내용은 인터리브 처리된 테이블의 연결 삭제 및 외래 키 작업을 참조하세요.
서로 다른 유형의 노드를 연결하는 에지의 연결 삭제
다음 예에서는 Spanner Graph 스키마에서 ON DELETE CASCADE
를 사용하여 소스 또는 대상 노드를 삭제할 때 연결이 끊긴 가장자리를 삭제하는 방법을 보여줍니다. 두 경우 모두 삭제된 노드의 유형과 에지로 연결된 노드의 유형이 다릅니다.
소스 노드
인터리브를 사용하여 소스 노드가 삭제될 때 댕글링 에지를 삭제합니다. 다음은 인터리브를 사용하여 소스 노드 (Person
)가 삭제될 때 나가는 에지를 삭제하는 방법을 보여줍니다. 자세한 내용은 인터리브 처리된 테이블 만들기를 참고하세요.
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id) ON DELETE CASCADE,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE
대상 노드
대상 노드가 삭제될 때 댕글링 에지를 삭제하려면 외래 키 제약 조건을 사용하세요. 다음 예시에서는 대상 노드 (Account
)가 삭제될 때 에지 테이블에서 ON
DELETE CASCADE
와 함께 외래 키를 사용하여 수신 에지를 삭제하는 방법을 보여줍니다.
CONSTRAINT FK_Account FOREIGN KEY(account_id)
REFERENCES Account(id) ON DELETE CASCADE
동일 유형의 노드를 연결하는 에지의 연결 삭제
에지의 소스 및 대상 노드가 유형이 동일하고 에지가 소스 노드에 인터리브 처리된 경우 소스 또는 대상 노드 중 하나에 대해서만 ON DELETE CASCADE
를 정의할 수 있습니다(두 노드가 아니라).
이러한 시나리오에서 매달린 에지를 방지하려면 소스 노드 입력 테이블에 인터리브하지 마세요. 대신 소스 및 대상 노드 참조에 강제 외래 키 두 개를 만듭니다.
다음 예시에서는 AccountTransferAccount
를 에지 입력 테이블로 사용합니다. 전송 에지의 각 끝 노드에 ON DELETE CASCADE
작업이 있는 외래 키 두 개를 정의합니다.
CREATE TABLE AccountTransferAccount (
id INT64 NOT NULL,
to_id INT64 NOT NULL,
amount FLOAT64,
create_time TIMESTAMP NOT NULL,
order_number STRING(MAX),
CONSTRAINT FK_FromAccount FOREIGN KEY (id) REFERENCES Account (id) ON DELETE CASCADE,
CONSTRAINT FK_ToAccount FOREIGN KEY (to_id) REFERENCES Account (id) ON DELETE CASCADE,
) PRIMARY KEY (id, to_id);
노드 및 에지에서 TTL (수명) 구성
TTL을 사용하면 지정된 기간이 지난 후 데이터를 만료하고 삭제할 수 있습니다. 스키마에서 TTL을 사용하여 수명이 제한되거나 관련성이 없는 데이터를 삭제하여 데이터베이스 크기와 성능을 유지할 수 있습니다. 예를 들어 세션 정보, 임시 캐시 또는 이벤트 로그를 삭제하도록 구성할 수 있습니다.
다음 예시에서는 TTL을 사용하여 마감 후 90일이 지나면 계정을 삭제합니다.
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
close_time TIMESTAMP,
) PRIMARY KEY (id),
ROW DELETION POLICY (OLDER_THAN(close_time, INTERVAL 90 DAY));
노드 테이블에서 TTL 정책을 정의할 때는 의도하지 않은 매달린 에지를 방지하기 위해 관련 에지가 처리되는 방식을 구성해야 합니다.
인터리브 처리된 에지 테이블: 에지 테이블이 노드 테이블에 인터리브 처리된 경우
ON DELETE CASCADE
를 사용하여 인터리브 관계를 정의할 수 있습니다. 이렇게 하면 TTL이 노드를 삭제할 때 연결된 인터리브 에지도 삭제됩니다.외래 키가 있는 에지 테이블: 에지 테이블이 외래 키로 노드 테이블을 참조하는 경우 다음 두 가지 옵션이 있습니다.
- 참조된 노드가 TTL에 의해 삭제될 때 에지를 자동으로 삭제하려면 외래 키에
ON DELETE CASCADE
를 사용하세요. 이렇게 하면 참조 무결성이 유지됩니다. - 참조된 노드가 삭제된 후에도 에지가 남아 있도록 하려면 (댕글링 에지 생성) 외래 키를 정보 외래 키로 정의하세요.
- 참조된 노드가 TTL에 의해 삭제될 때 에지를 자동으로 삭제하려면 외래 키에
다음 예시에서 AccountTransferAccount
에지 테이블에는 두 가지 데이터 삭제 정책이 적용됩니다.
- TTL 정책은 10년이 지난 전송 기록을 삭제합니다.
ON DELETE CASCADE
절은 계정이 삭제될 때 소스와 연결된 모든 전송 기록을 삭제합니다.
CREATE TABLE AccountTransferAccount (
id INT64 NOT NULL,
to_id INT64 NOT NULL,
amount FLOAT64,
create_time TIMESTAMP NOT NULL,
order_number STRING(MAX),
) PRIMARY KEY (id, to_id),
INTERLEAVE IN PARENT Account ON DELETE CASCADE,
ROW DELETION POLICY (OLDER_THAN(create_time, INTERVAL 3650 DAY));
노드 및 에지 입력 테이블 병합
스키마를 최적화하려면 단일 테이블 내에서 노드와 수신 또는 발신 에지를 정의하세요. 이 접근 방식에는 다음과 같은 이점이 있습니다.
테이블 수 감소: 스키마의 테이블 수를 줄여 데이터 관리를 간소화합니다.
쿼리 성능 개선: 별도의 에지 테이블에 조인을 사용하는 순회를 삭제합니다.
이 기법은 테이블의 기본 키가 다른 테이블과의 관계도 정의하는 경우에 적합합니다. 예를 들어 Account
테이블에 복합 기본 키 (owner_id, account_id)
가 있는 경우 owner_id
부분은 Person
테이블을 참조하는 외래 키일 수 있습니다. 이 구조를 사용하면 Account
테이블이 Account
노드와 Person
노드에서 들어오는 에지를 모두 나타낼 수 있습니다.
CREATE TABLE Person (
id INT64 NOT NULL,
) PRIMARY KEY (id);
-- Assume each account has exactly one owner.
CREATE TABLE Account (
owner_id INT64 NOT NULL,
account_id INT64 NOT NULL,
) PRIMARY KEY (owner_id, account_id);
Account
테이블을 사용하여 Account
노드와 수신 Owns
에지를 모두 정의할 수 있습니다. 이는 다음 CREATE PROPERTY GRAPH
문에 표시됩니다. EDGE TABLES
절에서 Account
테이블에 Owns
라는 별칭을 지정합니다. 그래프 스키마의 각 요소에는 고유한 이름이 있어야 하기 때문입니다.
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
Person,
Account
)
EDGE TABLES (
Account AS Owns
SOURCE KEY (owner_id) REFERENCES Person
DESTINATION KEY (owner_id, account_id) REFERENCES Account
);