SQL 뷰를 사용하여 그래프를 만드는 방법을 알아보세요. 이 문서에서는 뷰를 정의하고 이를 사용하여 노드 및 에지 테이블을 정의하는 단계별 안내와 코드 예시를 제공합니다. 뷰로 그래프를 만드는 사용 사례를 보여주는 샘플 코드가 포함된 예시를 살펴보세요. 이점과 고려사항을 비롯하여 뷰를 사용하여 속성 그래프를 만드는 방법을 자세히 알아보려면 SQL 뷰에서 만든 그래프 개요를 참조하세요.
시작하기 전에
그래프를 만들려면 다음 작업을 실행해야 합니다.
Spanner Graph 환경이 설정되어 있는지 확인합니다.
뷰를 사용하여 그래프 만들기
뷰를 사용하여 그래프를 만들려면 다음 단계를 따르세요.
그래프의 뷰를 정의합니다. 기본적으로 뷰는 요소 고유성을 보장하기 위해 지원되는 뷰 패턴 중 하나를 따라야 합니다. 뷰에서 이러한 패턴을 따르지 않는 쿼리를 사용하는 경우 4단계에서 키 고유성 유효성 검사를 사용 중지할 수 있습니다. 자세한 내용은 뷰 만들기를 참조하세요.
CREATE PROPERTY GRAPH문의NODE TABLES및EDGE TABLES절에서 뷰를 사용하여 그래프를 만듭니다.CREATE PROPERTY GRAPH문에KEY절을 포함합니다.KEY절은 각 그래프 요소를 고유하게 식별하는 소스 뷰의 열을 지정합니다.선택사항: 뷰에서 지원되는 고유성 패턴을 따르지 않는 임의의 SQL 쿼리를 사용하는 경우
OPTIONS (validate_element_key_uniqueness = false)절을CREATE PROPERTY GRAPH문에 추가합니다.KEY절 열이 모든 노드 또는 에지 행에 고유한 값을 생성하는지 확인합니다.CREATE PROPERTY GRAPH MyGraph NODE TABLES ( CustomerViewTrusted KEY(id) ) OPTIONS (validate_element_key_uniqueness = false);자세한 내용은 사용 중지된 키 유효성 검사 (SQL 쿼리)를 참조하세요.
예: 뷰를 사용하여 그래프 만들기
이 예에서는 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단계: 뷰 만들기
다음으로 테이블의 데이터를 변환하거나 필터링하는 뷰를 만듭니다. 이러한 뷰는 테이블을 필터링하여 아시아의 고객과 계정만 포함합니다.
validate_element_key_uniqueness가 false로 설정되지 않은 경우 그래프
요소를 만드는 데 사용되는 뷰는 뷰의 행이 고유하도록 지원되는 패턴을 따라야 합니다.
-- 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)
);