이 문서를 사용하여 SQL 뷰를 사용하여 그래프를 만드는 이점을 알아보세요. 이 문서에는 뷰로 그래프를 만드는 이점, 요구사항, 및 고려사항이 포함되어 있어 테이블 또는 뷰를 사용하여 테이블 그래프를 만들지 결정하는 데 도움이 됩니다.
뷰에서 그래프를 만드는 방법에 대한 자세한 내용은 SQL 뷰에서 속성 그래프 만들기를 참조하세요.
테이블 대신 뷰로 그래프를 만드는 이점
SQL 뷰 는 SQL 쿼리로 정의하는 가상 테이블입니다. Spanner에서 뷰를 정의하는 쿼리는 뷰를 참조하는 쿼리가 실행될 때마다 실행됩니다. Spanner 뷰는 뷰를 정의하는 쿼리의 결과를 데이터 스토리지의 실제 테이블로 저장하지 않으므로 구체화된 뷰가 아닙니다. 자세한 내용은 뷰 개요를 참조하세요. SQL 뷰에서 그래프 요소를 만들 수 있지만 그래프를 쿼리하는 뷰는 만들 수 없습니다.
뷰는 테이블과 그래프 스키마 간의 추상화 계층으로 여러 가지 이점을 제공하며, 테이블을 사용하여 그래프를 만들 때는 사용할 수 없습니다.
행 수준 액세스 제어. 정의자의 권한 뷰의 보안 권한을 사용하여 행 수준에서 그래프 데이터에 세분화된 액세스 제어를 적용합니다. 이렇게 하면 사용자가 볼 수 있는 노드와 에지만 쿼리할 수 있습니다.
유연한 데이터 모델링. 그래프 요소를 만들기 전에 쿼리가 있는 뷰를 사용하여 관계형 데이터를 구성하고 변환합니다. 뷰의 쿼리를 사용하면 행을 필터링하거나 열을 결합하거나
ARRAY와 같은 반복 필드를 중첩 해제할 수 있습니다.스키마 없는 데이터에서 공식화된 데이터로 전환. 스키마 없는 데이터에서 뷰를 만들어 노드 및 에지 유형을 명시적으로 정의합니다. 이렇게 하면 데이터의 관계를 공식화하는 데 도움이 됩니다.
뷰를 사용하여 그래프를 만들기 위한 요구사항
뷰를 사용하여 그래프 요소를 만들 때는 다음 요구사항을 따라야 합니다.
그래프 요소를 지정할 때는 KEY 절을 사용합니다.
뷰를 사용하여 노드 또는 에지 요소를 만들 때는 그래프 요소를 고유하게 식별하는 열을 명시적으로 정의해야 합니다. 이렇게 하려면 노드 또는 에지 요소 정의에서 KEY 절을 사용합니다. 그래프 요소를 만들 때
KEY 절을 사용하는 방법을 알아보려면 이
문서와
SQL 뷰에서 Spanner Graph 만들기의 코드 예시를 참고하세요.
노드 및 에지 키의 고유성 보장
속성 그래프의 모든 노드와 에지에는 고유한 키가 있어야 합니다. 뷰를 사용하여 그래프 요소를 정의할 때 요소 키의 고유성을 확인하는 방법을 선택할 수 있습니다.
- 엄격한 키 검증 (기본값): Spanner 는 뷰가 지원되는 쿼리 패턴을 따라 키 고유성을 보장하는지 확인합니다.
- 사용 중지된 키 검증 (모든 SQL 쿼리): 그래프 옵션을 설정하면 모든 SQL 쿼리를 사용할 수 있습니다.
validate_element_key_uniqueness = false이 모드에서는 요소 키가 고유한지 확인해야 합니다.
엄격한 키 검증 (기본값)
기본적으로 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 절에 지정된 열에 모든 노드 또는 에지 행의 고유한 값이 포함되어 있는지 확인해야 합니다.
validate_element_key_uniqueness = false
다음 예시에서는 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);
뷰 사용 시 고려사항
뷰를 사용하여 그래프 요소를 정의할 때 다음을 통해 효과적인 그래프를 설계하고 구현할 수 있습니다.
속성 그래프 쿼리 성능
데이터 변환 (예: 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 스키마를 설계하기 위한 권장사항을 알아봅니다.