SQL 뷰를 사용하여 그래프를 만드는 방법을 알아봅니다. 이 문서에서는 뷰를 정의하고 이를 사용하여 노드 및 에지 테이블을 정의하는 단계별 안내와 코드 예시를 제공합니다. 뷰로 그래프를 만드는 사용 사례를 보여주는 샘플 코드가 포함된 예를 살펴봅니다. 뷰를 사용하여 속성 그래프를 만드는 방법(이점 및 고려사항 포함)을 자세히 알아보려면 SQL 뷰에서 생성된 그래프 개요를 참고하세요.
시작하기 전에
그래프를 만들려면 다음을 충족해야 합니다.
Spanner Graph 환경이 설정되어 있는지 확인합니다.
Spanner Graph 스키마의 작동 방식을 숙지합니다.
뷰를 사용하여 그래프 만들기
뷰를 사용하여 그래프를 만들려면 다음 단계를 따르세요.
그래프의 뷰를 정의합니다. 뷰가 필수 뷰 패턴 중 하나를 따르는지 확인합니다. 자세한 내용은 뷰 만들기를 참고하세요.
CREATE PROPERTY GRAPH문의NODE TABLES및EDGE TABLES절에서 뷰를 사용하여 그래프를 만듭니다.CREATE PROPERTY GRAPH문에KEY절을 포함합니다.KEY절은 각 그래프 요소를 고유하게 식별하는 소스 뷰의 열을 지정합니다.
예: 뷰를 사용하여 그래프 만들기
이 예시에서는 Customer 및 Account 테이블에 AsiaCustomer, AsiaBankAccount, AsiaAccountsOwnership 뷰를 만듭니다. 그런 다음 예시에서는 이러한 뷰를 사용하여 그래프에서 다음을 만듭니다.
AsiaCustomer뷰를 사용하여Customer노드 테이블을 만듭니다.AsiaBankAccount뷰를 사용하여Account노드 테이블을 만듭니다.AsiaAccountsOwnership뷰를 사용하여Owns에지 테이블을 만듭니다. 이 에지는Customer노드를Account노드와 연결합니다.
1단계: 표 만들기
먼저 데이터 테이블을 만듭니다. 다음 코드에서는 Customer 및 Account 테이블을 만듭니다.
CREATE TABLE Customer (
customer_id INT64 NOT NULL,
name STRING(MAX),
address_continent STRING(MAX),
address_country STRING(MAX),
) PRIMARY KEY(customer_id);
CREATE TABLE Account (
account_id INT64 NOT NULL,
customer_id INT64 NOT NULL,
account_type STRING(MAX),
balance INT64,
create_time TIMESTAMP,
address_continent STRING(MAX),
address_country STRING(MAX),
CONSTRAINT FK_CustomerId FOREIGN KEY (customer_id)
REFERENCES Customer (customer_id)
) PRIMARY KEY(account_id);
2단계: 뷰 만들기
그런 다음 테이블의 데이터를 변환하거나 필터링하는 뷰를 만듭니다. 이러한 뷰는 아시아의 고객과 계정만 포함하도록 표를 필터링합니다. 그래프 요소를 만드는 데 사용되는 뷰는 뷰의 행이 고유한지 확인해야 합니다.
-- View for 'Customer' nodes, filtered for Asia
CREATE VIEW AsiaCustomer
SQL SECURITY INVOKER AS
SELECT customer.customer_id, customer.name
FROM Customer customer
WHERE LOWER(customer.address_continent) = "asia";
-- View for 'Account' nodes, filtered for Asia.
CREATE VIEW AsiaBankAccount
SQL SECURITY INVOKER AS
SELECT account.account_id, account.balance, account.account_type, account.create_time
FROM Account account
WHERE LOWER(account.address_continent) = "asia";
-- View for 'Owns' edges, connecting customers to accounts in Asia.
CREATE VIEW AsiaAccountsOwnership
SQL SECURITY INVOKER AS
SELECT account.customer_id, account.account_id
FROM Account account
WHERE LOWER(account.address_continent) = "asia";
3단계: 속성 그래프 만들기
이제 만든 뷰를 사용하여 AsiaFinGraph를 만듭니다. CREATE PROPERTY GRAPH 문에는 각 그래프 요소 정의의 KEY 절이 포함되어 그래프 요소를 고유하게 식별하는 열을 지정합니다.
CREATE PROPERTY GRAPH AsiaFinGraph
NODE TABLES (
AsiaCustomer AS Customer KEY(customer_id),
AsiaBankAccount AS Account KEY(account_id)
)
EDGE TABLES (
AsiaAccountsOwnership AS Owns
KEY(customer_id, account_id)
SOURCE KEY (customer_id) REFERENCES Customer (customer_id)
DESTINATION KEY (account_id) REFERENCES Account (account_id)
);
사용 사례 예시
SQL 뷰는 속성 그래프 요소에 테이블을 사용하는 것보다 이점이 있습니다. 다음 예에서는 테이블 대신 뷰를 사용하여 그래프 요소를 정의하는 몇 가지 사용 사례를 보여줍니다.
예: 세분화된 그래프 데이터 액세스 제어 적용
그래프 데이터에 행 수준 보안을 적용하려면 정의자 권한 뷰를 사용하여 노드 또는 에지 테이블을 정의하세요. 뷰는 그래프에 기본 데이터의 허용된 하위 집합을 노출합니다.
예를 들어 엔지니어링 비용 센터의 직원만 그래프에 액세스할 수 있도록 제한하려면 EngineerEmployeeView 보기를 만들고 GRANT 절을 사용하여 engineering_data_reader 역할에 보기의 SELECT 권한을 부여하면 됩니다.
이 뷰를 사용하여 그래프 노드 테이블을 정의하면 engineering_data_reader 역할이 있는 사용자가 엔지니어링 직원을 포함하여 뷰로 필터링된 행만 볼 수 있습니다.
-- The table containing all employee data.
CREATE TABLE Employee (
id INT64 NOT NULL,
cost_center STRING(MAX),
job_title STRING(MAX),
office STRING(MAX)
) PRIMARY KEY (id);
-- The definer's rights view that filters for engineering employees.
CREATE VIEW EngineerEmployeeView SQL SECURITY DEFINER AS
SELECT e.id, e.cost_center, e.job_title, e.office
FROM Employee e
WHERE LOWER(e.cost_center) = "engineering";
-- The role that is granted to read the view.
CREATE ROLE engineering_data_reader;
GRANT SELECT ON VIEW EngineerEmployeeView TO ROLE engineering_data_reader;
-- The graph that uses definer's rights view.
CREATE PROPERTY GRAPH EngineeringGraph
NODE TABLES (
EngineerEmployeeView KEY(id)
);
예: 모델에서 파생된 그래프 요소
뷰를 사용하여 데이터 변환이 필요한 그래프 요소를 정의할 수 있습니다. 주요 이점은 뷰가 변환을 정의하므로 파생된 데이터에 대해 별도의 테이블을 유지할 필요가 없다는 것입니다.
예를 들어 ARRAY 열 (또는 JSON 열 내의 배열 필드)의 데이터를 UNNEST하여 단일 행에서 여러 에지 관계를 모델링할 수 있습니다.
다음 공급망 스키마 예시에서 Parts 테이블은 dependent_parts 배열에 하위 구성요소 목록을 저장합니다. 뷰는 UNNEST 연산자를 사용하여 배열의 각 요소를 개별 행으로 변환할 수 있습니다. 이 뷰는 에지 테이블 역할을 하여 PartDependsOnPart 에지를 모델링하여 파트 간의 종속 관계를 나타낼 수 있습니다.
-- Parts table with an ARRAY of dependent parts.
CREATE TABLE Parts (
part_id INT64 NOT NULL,
dependent_parts ARRAY<INT64>
) PRIMARY KEY (part_id);
-- A view that unnests the dependent_parts array.
-- GROUP BY ensures uniqueness for the graph element KEY.
CREATE VIEW PartDependsOnPart SQL SECURITY INVOKER AS
SELECT p.part_id, dependent_part_id
FROM Parts AS p,
UNNEST(p.dependent_parts) AS dependent_part_id
GROUP BY p.part_id, dependent_part_id;
-- Graph modeling the part dependency relationship.
CREATE PROPERTY GRAPH SupplyChainGraph
NODE TABLES (
Parts
)
EDGE TABLES (
PartDependsOnPart KEY (part_id, dependent_part_id)
SOURCE KEY (part_id) REFERENCES Parts(part_id)
DESTINATION KEY (dependent_part_id) REFERENCES Parts(part_id)
);
예: 스키마 없는 데이터 전환
스키마 없는 데이터 관리를 사용하면 사전 정의된 노드 및 에지 유형 없이 유연한 그래프 정의를 만들 수 있습니다. 스키마 없는 데이터 관리는 유연성을 제공하지만 데이터가 더 명확해지면 더 공식적인 구조로 전환해야 할 수 있습니다. 더 공식적인 구조는 스키마에 그래프의 노드 및 에지 관계, 라벨, 속성을 노출하므로 그래프 스키마를 이해하기 위해 수동으로 데이터를 탐색할 필요가 없습니다.
뷰를 사용하여 기본 데이터를 마이그레이션하지 않고 노드 및 에지 유형을 공식화할 수 있습니다. 예를 들어 표준 GraphNode 및 GraphEdge 테이블을 사용하는 일반적인 스키마 없는 모델에서 전환할 수 있습니다. 이렇게 하려면 스키마가 없는 테이블에서 데이터를 추출하는 뷰를 만듭니다.
형식화할 각 노드 및 에지 유형 (예:
Person또는WorksFor)에 대한 뷰를 정의합니다. 뷰에서 라벨(예:WHERE n_label = "person")별로 데이터를 필터링하고 JSON 열의 속성을 특정 데이터 유형 (예:STRING(prop.name) AS name)으로 변환합니다.NODE TABLES및EDGE TABLES이 방금 만든 유형이 지정된 뷰를 참조하는 새 속성 그래프를 정의합니다.
스키마가 없는 그래프는 일부 쿼리 (예: 여러 에지 유형이 있는 정량화된 경로 패턴)에서 공식화된 그래프보다 성능이 더 뛰어납니다. 사용 사례에 공식화된 메타데이터가 중요한 경우 뷰를 사용하여 스키마가 없는 그래프에서 유형이 지정된 스키마로 전환할 수 있습니다. 일부 사용 사례에는 스키마가 없는 그래프를 사용하고 다른 사용 사례에는 유형이 지정된 스키마 그래프를 사용할 수도 있습니다. 자세한 내용은 그래프 쿼리를 기반으로 스키마 설계 선택을 참고하세요.
다음 예에서는 4단계로 스키마가 없는 그래프에서 공식화된 그래프로 전환하는 워크플로를 보여줍니다.
스키마가 없는 모델의 표준
GraphNode및GraphEdge테이블을 정의합니다.스키마가 없는 테이블에 초기 유연한 그래프를 만듭니다.
스키마가 없는 테이블에서 데이터를 추출하고 공식화하는 유형이 지정된 뷰 (
Person,Company,WorksFor)를 정의합니다.이러한 뷰를 노드 및 가장자리 테이블로 사용하는 최종적인 강력한 유형의 그래프를 만듭니다.
-- 1. Create the canonical tables for a schemaless model.
CREATE TABLE GraphNode (
id INT64 NOT NULL,
label STRING(MAX) NOT NULL,
properties JSON
) PRIMARY KEY (id);
CREATE TABLE GraphEdge (
id INT64 NOT NULL,
dest_id INT64 NOT NULL,
edge_id INT64 NOT NULL,
label STRING(MAX) NOT NULL,
properties JSON
) PRIMARY KEY (id, dest_id, edge_id),
INTERLEAVE IN PARENT GraphNode;
-- 2. Define a schemaless graph.
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
GraphNode
DYNAMIC LABEL (label)
DYNAMIC PROPERTIES (properties)
)
EDGE TABLES (
GraphEdge
SOURCE KEY (id) REFERENCES GraphNode(id)
DESTINATION KEY (dest_id) REFERENCES GraphNode(id)
DYNAMIC LABEL (label)
DYNAMIC PROPERTIES (properties)
);
-- 3. Define typed views that extract and formalize the data.
-- Convert JSON fields to primitive types (for example, INT64, STRING) to
-- ensure type safety.
CREATE VIEW Person SQL SECURITY INVOKER AS
SELECT n.id, STRING(n.properties.name) AS name, INT64(n.properties.age) AS age
FROM GraphNode n WHERE n.label = "person";
CREATE VIEW Company SQL SECURITY INVOKER AS
SELECT n.id, STRING(n.properties.name) AS company_name, BOOL(n.properties.is_public) AS is_public
FROM GraphNode n WHERE n.label = "company";
CREATE VIEW WorksFor SQL SECURITY INVOKER AS
SELECT e.id AS person_id, e.dest_id AS company_id, e.edge_id AS edge_id, STRING(e.properties.since) AS since
FROM GraphEdge e
WHERE e.label = "worksfor";
-- 4. Create the final, formalized graph from the typed views.
CREATE PROPERTY GRAPH typed_formalized_graph
NODE TABLES (
Person KEY(id)
PROPERTIES (name, age),
Company KEY(id)
PROPERTIES (company_name, is_public)
)
EDGE TABLES(
WorksFor KEY(person_id, company_id, edge_id)
SOURCE KEY (person_id) REFERENCES Person(id)
DESTINATION KEY (company_id) REFERENCES Company(id)
PROPERTIES (since)
);
다음 단계
Spanner Graph 스키마 알아보기
Spanner Graph 스키마 설계 권장사항에 대해 알아봅니다.