이 문서를 사용하여 SQL 뷰를 사용하여 그래프를 만들 때의 이점을 알아보세요. 이 문서에는 테이블 또는 뷰를 사용하여 그래프를 만들어야 하는지 결정하는 데 도움이 되는 뷰를 사용하여 그래프를 만들 때의 이점, 요구사항, 고려사항이 포함되어 있습니다.
뷰에서 그래프를 만드는 방법에 대한 자세한 내용은 SQL 뷰에서 속성 그래프 만들기를 참조하세요.
테이블 대신 뷰를 사용하여 그래프를 만들 때의 이점
SQL 뷰는 SQL 쿼리로 정의하는 가상 테이블입니다. Spanner에서 뷰를 정의하는 쿼리는 뷰를 참조하는 쿼리가 실행될 때마다 실행됩니다. Spanner 뷰는 뷰를 정의하는 쿼리 결과를 데이터 스토리지의 실제 테이블로 저장하지 않으므로 구체화된 뷰가 아닙니다. 자세한 내용은 뷰 개요를 참조하세요. SQL 뷰에서 그래프 요소를 만들 수 있지만 그래프를 쿼리하는 뷰를 만들 수는 없습니다.
뷰는 테이블을 사용하여 그래프를 만들 때 사용할 수 없는 테이블과 그래프 스키마 간의 추상화 레이어로 여러 이점을 제공합니다.
행 수준 액세스 제어. 정의자의 권한 뷰의 보안 권한을 사용하여 그래프 데이터에 행 수준에서 세분화된 액세스 제어를 적용합니다. 이렇게 하면 사용자가 볼 수 있는 노드와 에지만 쿼리할 수 있습니다.
유연한 데이터 모델링. 쿼리가 있는 뷰를 사용하여 그래프 요소를 만들기 전에 관계형 데이터를 형성하고 변환합니다. 뷰의 쿼리를 사용하면 행을 필터링하고, 열을 결합하고,
ARRAY에서와 같이 반복되는 필드를 중첩 해제하거나, 원격 함수를 사용하여 속성을 계산할 수 있습니다.스키마 없는 데이터에서 정형 데이터로 전환 스키마 없는 데이터에서 뷰를 만들어 노드 및 에지 유형을 명시적으로 정의합니다. 이렇게 하면 데이터의 관계를 공식화하는 데 도움이 됩니다.
뷰를 사용하여 그래프를 만들기 위한 요구사항
뷰를 사용하여 그래프 요소를 만들 때는 다음 요구사항을 따라야 합니다.
그래프 요소를 지정할 때 KEY 절 사용
뷰를 사용하여 노드 또는 에지 요소를 만들 때는 그래프 요소를 고유하게 식별하는 열을 명시적으로 정의해야 합니다. 이렇게 하려면 노드 또는 에지 요소 정의에서 KEY 절을 사용합니다. 그래프 요소를 만들 때 KEY 절을 사용하는 방법을 알아보려면 이 문서와 SQL 뷰에서 Spanner Graph 만들기의 코드 예시를 참조하세요.
노드 및 에지 키 고유성 보장
속성 그래프의 모든 노드와 에지에는 고유한 키가 있어야 합니다. 뷰를 사용하여 그래프 요소를 정의할 때 요소 키 고유성을 확인하는 방법을 선택할 수 있습니다.
- 엄격한 키 검증 (기본값): Spanner는 뷰가 지원되는 쿼리 패턴을 따르는지 확인하여 키 고유성을 보장합니다.
- 키 검증 사용 중지 (모든 SQL 쿼리):
validate_element_key_uniqueness = false그래프 옵션을 설정하면 모든 SQL 쿼리를 사용할 수 있습니다. 이 모드에서는 요소 키가 고유한지 확인해야 합니다.
엄격한 키 검증 (기본값)
기본적으로 Spanner는 노드 또는 에지 테이블을 정의하는 뷰가 다음 패턴 중 하나를 따르는지 확인하여 각 노드 또는 에지가 고유한지 확인합니다.
WHERE, HAVING, ORDER BY,LIMIT, TABLESAMPLE과 같은 다른 SQL 연산자를 이러한 패턴과 함께 사용할 수 있습니다. 이러한 연산자는 결과를 필터링하거나 정렬하지만 패턴이 제공하는 기본 고유성 보장을 변경하지는 않습니다.
패턴 1: 단일 테이블의 기본 키 사용
이 패턴에서 뷰는 단일 테이블에서 선택하고 그래프 정의의 KEY 절은 기본 테이블의 기본 키 열과 일치합니다. 따라서 뷰에서 생성된 각 노드 또는 에지 행은 고유합니다.
예를 들어 다음은 Account 테이블에서 행의 하위 집합을 선택합니다.
KEY(account_id) 그래프는 Account 테이블의 기본 키와 일치하므로 뷰에서 생성된 각 행이 고유합니다.
-- Table has PRIMARY KEY(account_id).
CREATE TABLE Account (
account_id INT64 NOT NULL,
customer_id INT64 NOT NULL,
account_type STRING(MAX),
balance INT64
) PRIMARY KEY(account_id);
-- Pattern 1: View uses the primary key from a single table.
CREATE VIEW SavingAccount
SQL SECURITY INVOKER AS
SELECT accnt.account_id, accnt.customer_id, accnt.balance
FROM Account accnt
WHERE accnt.account_type = 'saving';
CREATE PROPERTY GRAPH SavingAccountGraph
NODE TABLES (
-- The element KEY(account_id) matches the table's primary key.
SavingAccount KEY(account_id)
);
패턴 2: GROUP BY 또는 SELECT DISTINCT 절 사용
이 패턴에서 뷰의 쿼리는 GROUP BY 또는 SELECT DISTINCT 절을 사용합니다. KEY 절의 열은 다음 절에서 고유성을 정의하는 데 사용하는 열과 일치해야 합니다.
GROUP BY의 경우:KEY절 열은GROUP BY절의 모든 열과 일치해야 합니다.SELECT DISTINCT의 경우:KEY절 열은SELECT DISTINCT목록의 열과 일치해야 합니다.
GROUP BY를 사용한 예시:
CREATE TABLE Customer (
customer_id INT64,
name STRING(MAX)
) PRIMARY KEY (customer_id);
CREATE TABLE SaleOrder (
order_id INT64,
customer_id INT64,
amount INT64
) PRIMARY KEY (order_id);
CREATE VIEW CustomerOrder
SQL SECURITY INVOKER AS
SELECT
s.order_id,
ANY_VALUE(c.customer_id) AS customer_id,
ANY_VALUE(c.name) AS customer_name
FROM Customer c JOIN SaleOrder s ON c.customer_id = s.customer_id
GROUP BY s.order_id;
CREATE PROPERTY GRAPH OrderGraph
NODE TABLES (
-- The KEY(order_id) matches the GROUP BY column in view definition.
CustomerOrder KEY(order_id)
);
SELECT DISTINCT를 사용한 예시:
CREATE TABLE SaleOrder (
order_id INT64,
customer_id INT64,
amount INT64
) PRIMARY KEY (order_id);
CREATE VIEW KeyCustomer SQL SECURITY INVOKER AS
SELECT DISTINCT s.customer_id, s.amount
FROM SaleOrder s
WHERE s.amount > 1000;
CREATE PROPERTY GRAPH KeyCustomersGraph
NODE TABLES (
-- The KEY(customer_id, amount) matches the DISTINCT columns.
KeyCustomer KEY(customer_id, amount)
);
키 검증 사용 중지됨 (모든 SQL 쿼리)
뷰에서 패턴 1 또는 패턴 2를 따르지 않는 쿼리(예: GROUP BY 또는 SELECT DISTINCT 절 없이 테이블을 조인하는 쿼리)를 사용하는 경우 그래프 옵션 validate_element_key_uniqueness = false를 설정하여 요소 키 검증을 사용 중지할 수 있습니다.
validate_element_key_uniqueness의 기본값은 true입니다. false로 설정하면 Spanner는 스키마 생성 시 뷰의 쿼리 정의를 검증하지 않습니다. 뷰에서 모든 SQL 쿼리를 사용할 수 있지만 KEY 절에 지정된 열에 모든 노드 또는 에지 행에 대한 고유 값이 포함되어야 합니다.
다음 예시에서는 GROUP BY 절 없이 Customer 및 SaleOrder 테이블을 조인하는 CustomerOrderTrusted이라는 뷰를 정의합니다. 각 판매 주문은 고유하므로 SaleOrder를 Customer와 조인하면 뷰 결과에서 order_id의 고유성이 유지됩니다. 하지만 쿼리가 JOIN를 사용하고 패턴 1 또는 패턴 2를 따르지 않으므로 Spanner는 구문적으로 고유성을 확인할 수 없습니다.
OPTIONS 절에서 KEY(order_id)를 지정하고 validate_element_key_uniqueness = false를 설정하면 뷰 쿼리를 수정하지 않고도 속성 그래프를 정의할 수 있습니다.
-- View uses a JOIN without GROUP BY or DISTINCT.
CREATE VIEW CustomerOrderTrusted
SQL SECURITY INVOKER AS
SELECT
s.order_id,
c.customer_id,
c.name AS customer_name
FROM Customer c JOIN SaleOrder s ON c.customer_id = s.customer_id;
-- Property graph disables element key uniqueness validation.
CREATE PROPERTY GRAPH OrderGraphTrusted
NODE TABLES (
CustomerOrderTrusted
KEY(order_id)
LABEL CustomerOrder PROPERTIES(
order_id,
customer_id,
customer_name)
) OPTIONS (validate_element_key_uniqueness = false);
뷰에서 원격 함수를 사용할 때 휘발성 열 사용 설정
CREATE PROPERTY GRAPH 문의 OPTIONS 절에서 allow_view_with_volatile_column = true를 설정하여 원격 함수 (LANGUAGE REMOTE)를 호출하는 뷰에서 속성 그래프를 정의할 수 있습니다.
기본적으로 Spanner에서는 휘발성 열 (allow_view_with_volatile_column = false)이 있는 뷰에 속성 그래프를 정의할 수 없습니다. 표현식이 휘발성 함수를 호출하는 경우 뷰 열은 휘발성입니다. 원격 함수 (NOT DETERMINISTIC)와 같이 동일한 인수를 사용하는 단일 문 실행 내에서도 반환 값이 변경될 수 있는 경우 함수는 휘발성입니다. JOIN 조건 또는 WHERE 절과 같이 뷰 정의 본문의 휘발성으로 인해 뷰의 모든 프로젝션된 열도 휘발성이 됩니다. 코드 예시는 원격 함수를 사용하여 속성 계산을 참조하세요.
뷰 사용 시 고려사항
뷰를 사용하여 그래프 요소를 정의할 때 다음 사항은 효과적인 그래프를 설계하고 구현하는 데 도움이 될 수 있습니다.
속성 그래프 쿼리 성능
데이터 변환을 수행하는 뷰 (예: GROUP BY, UNNEST 또는 JOIN 작업)에서 그래프 요소를 정의할 때는 사용 사례의 쿼리 성능을 신중하게 평가하세요. 쿼리가 요소 패턴 일치를 수행할 때마다 Spanner가 뷰의 쿼리 정의를 실행한다는 점에 유의하세요.
그래프 스키마 최적화
뷰를 사용하여 그래프 요소를 정의하는 경우 일부 그래프 스키마 최적화는 테이블을 사용하여 그래프 요소를 정의하는 경우보다 효과가 떨어질 수 있습니다.
단일 테이블의 기본 키를 프로젝션하는 뷰
뷰가 단일 기본 테이블의 프로젝션인 경우 해당 기본 테이블의 최적화는 그래프 쿼리에 계속 적용됩니다. 예를 들어 기본 테이블에 다음 기법을 적용하면 이러한 뷰에 정의된 그래프 요소에 유사한 성능 이점이 제공됩니다.
GROUP BY 또는 DISTINCT 절로 정의된 뷰
GROUP BY, SELECT DISTINCT 또는 기타 복잡한 변환과 같은 집계를 수행하는 뷰는 기본 테이블 구조와의 직접적인 관계를 잃게 됩니다. 따라서 기본 테이블의 스키마 최적화가 뷰에서 작동하는 그래프 쿼리에 동일한 성능 이점을 제공하지 않을 수 있습니다. 뷰에서 복잡한 집계를 수행하는 경우 사용 사례의 쿼리 성능을 신중하게 평가하세요.
뷰 기반 그래프를 사용한 데이터 수정
뷰는 구체화되지 않습니다. 즉, 뷰를 정의하는 쿼리 결과를 데이터 스토리지에 테이블로 저장하지 않으며 읽기 전용입니다. 따라서 뷰에서 생성된 그래프에서 노드 또는 에지를 삽입, 업데이트 또는 삭제하려면 뷰를 만드는 데 사용된 테이블의 데이터를 수정해야 합니다.
데이터 무결성을 적용하기 위한 그래프 오류 처리
뷰를 사용하여 그래프 요소를 정의할 때는 기본 테이블에 데이터 무결성 (예: 데이터 유형 적용)을 적용합니다. 그렇지 않으면 기본 테이블의 데이터가 유효하지 않아 런타임 시 뷰 기반 그래프에 대한 쿼리가 실패할 수 있습니다.
예를 들어 스키마가 없는 그래프에서 정형 그래프로 전환할 때 CHECK 제약 조건을 사용하여 기본 테이블 (GraphNode 및 GraphEdge)의 데이터를 검증합니다. 다음 코드는 JSON 속성 내에서 이러한 제약 조건을 적용하여 소스에서 데이터 무결성을 보장하고 런타임 쿼리 오류를 방지합니다.
-- Enforce that the 'name' property exists for nodes with the 'person' label.
ALTER TABLE GraphNode
ADD CONSTRAINT NameMustExistForPersonConstraint
CHECK (IF(label = 'person', properties.name IS NOT NULL, TRUE));
-- Enforce that the 'name' property is a string for nodes with the 'person' label.
ALTER TABLE GraphNode
ADD CONSTRAINT PersonNameMustBeStringTypeConstraint
CHECK (IF(label = 'person', JSON_TYPE(properties.name) = 'string', TRUE));
다음 단계
SQL 뷰에서 속성 그래프를 만드는 방법 알아보기
Spanner Graph 스키마 알아보기