יצירת תרשים מתצוגת SQL

איך יוצרים תרשים באמצעות תצוגות SQL מסמך זה מספק הוראות מפורטות ודוגמאות קוד להגדרת תצוגות ושימוש בהן להגדרת טבלאות צמתים וקצוות. דוגמאות עם קוד לדוגמה שממחישות תרחישים לדוגמה ליצירת תרשימים עם תצוגות. במאמר סקירה כללית של תרשימים שנוצרו מתצוגות SQL מוסבר איך משתמשים בתצוגות כדי ליצור תרשים מאפיינים, כולל היתרונות והשיקולים.

לפני שמתחילים

כדי ליצור תרשים, צריך:

  1. מוודאים שסביבת Spanner Graph מוגדרת.

  2. איך פועלות הסכימות של Spanner Graph

יצירת תרשים באמצעות תצוגות

כדי ליצור תרשים באמצעות תצוגות:

  1. הגדרת תצוגות לתרשים. כברירת מחדל, התצוגות צריכות להיות באחד מהפורמטים הנתמכים כדי להבטיח שהרכיבים יהיו ייחודיים. אם התצוגות שלכם משתמשות בשאילתות שלא תואמות לדפוסים האלה, אתם יכולים להשבית את אימות הייחודיות של המפתח בשלב 4. מידע נוסף זמין במאמר יצירת תצוגה (View).

  2. כדי ליצור גרף, משתמשים בתצוגות בסעיפים NODE TABLES ו-EDGE TABLES של ההצהרה CREATE PROPERTY GRAPH.

  3. מוסיפים את הסעיף KEY להצהרה CREATE PROPERTY GRAPH. הסעיף KEY מציין את העמודות בתצוגת המקור שמזהות באופן ייחודי כל רכיב בתרשים.

  4. אופציונלי: אם התצוגות משתמשות בשאילתות 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).

  5. אופציונלי: אם התצוגות קוראות לפונקציה מרוחקת או שיש להן עמודות תנודתיות אחרות, מוסיפים את הסעיף OPTIONS (allow_view_with_volatile_column = true) להצהרה CREATE PROPERTY GRAPH:

    CREATE PROPERTY GRAPH MyGraph
      NODE TABLES (
        AccountRemoteUdfView KEY(account_id)
      ) OPTIONS (allow_view_with_volatile_column = true);
    

    מידע נוסף זמין במאמר הפעלת עמודות נדיפות כשתצוגות משתמשות בפונקציות מרוחקות.

דוגמה: יצירת תרשים באמצעות תצוגות

בדוגמה הזו נוצרות התצוגות הבאות מעל הטבלאות Customer ו-Account: AsiaCustomer, AsiaBankAccount ו-AsiaAccountsOwnership. לאחר מכן, בדוגמה נעשה שימוש בתצוגות האלה כדי ליצור את הדברים הבאים בתרשים:

  • יוצרים את טבלת הצמתים Customer באמצעות התצוגה AsiaCustomer.

  • יוצרים את טבלת הצמתים Account באמצעות התצוגה AsiaBankAccount.

  • יוצרים את טבלת הקצוות Owns באמצעות התצוגה AsiaAccountsOwnership. הקשת הזו מחברת בין צמתים מסוג 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 ולהעניק הרשאות SELECT בתצוגה לתפקיד engineering_data_reader באמצעות הסעיף GRANT.

כשמגדירים טבלת צומתי תרשים באמצעות התצוגה הזו, משתמשים שמריצים שאילתות תרשים עם התפקיד 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)
  );

דוגמה: רכיבי תרשים שנגזרו ממודל

אתם יכולים להשתמש בתצוגות כדי להגדיר רכיבי תרשים שדורשים טרנספורמציות של נתונים. יתרון מרכזי הוא שהתצוגה מגדירה את הטרנספורמציה, כך שאין צורך לתחזק טבלה נפרדת לנתונים הנגזרים.

ביטול ההתאמה של מערכים לקצוות של מודלים

לדוגמה, אפשר UNNEST נתונים מעמודת ARRAY (או משדה מערך בתוך עמודת JSON) כדי ליצור מודל של כמה קשרי קצוות משורה אחת.

בדוגמה הבאה של סכימת שרשרת אספקה, בטבלה 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)
  );

חישוב מאפיינים באמצעות פונקציות מרוחקות

אתם יכולים גם להשתמש בפונקציה מרוחקת בתצוגה כדי לחשב נכסים נגזרים של רכיבי תרשים, על ידי הגדרת allow_view_with_volatile_column = true בסעיף OPTIONS של ההצהרה CREATE PROPERTY GRAPH. מידע נוסף זמין במאמר הפעלת עמודות נדיפות כשתצוגות משתמשות בפונקציות מרוחקות.

-- Define a remote function.
CREATE FUNCTION rudf_identity_func(x INT64)
  RETURNS INT64 NOT DETERMINISTIC LANGUAGE REMOTE
  OPTIONS (
    endpoint = 'https://us-central1-project-id.cloudfunctions.net/my-func'
  );

-- Base table for accounts.
CREATE TABLE Account (
  account_id INT64 NOT NULL,
  balance INT64
) PRIMARY KEY (account_id);

-- View that computes a property using the remote function.
CREATE VIEW AccountRemoteUdfView SQL SECURITY INVOKER AS
  SELECT
    t.account_id,
    t.balance,
    rudf_identity_func(t.account_id) AS view_computed_prop
  FROM Account AS t;

-- Graph using the view requires allow_view_with_volatile_column = true.
CREATE PROPERTY GRAPH AccountViewRemoteUdfGraph
  NODE TABLES (
    AccountRemoteUdfView KEY (account_id)
      PROPERTIES (account_id, balance, view_computed_prop)
  )
  OPTIONS (allow_view_with_volatile_column = true);

דוגמה: העברת נתונים ללא סכימה

ניהול נתונים ללא סכימה מאפשר ליצור הגדרת גרף גמישה ללא סוגי צמתים וקצוות מוגדרים מראש. ניהול נתונים ללא סכימה מספק גמישות, אבל יכול להיות שתצטרכו לעבור למבנה רשמי יותר ככל שהנתונים שלכם יהיו מוגדרים יותר. מבנה רשמי יותר חושף את הקשרים, התוויות והמאפיינים של הצמתים והקצוות של התרשים בסכימה, וכך מפחית את הצורך בחקירת נתונים ידנית כדי להבין את סכימת התרשים.

אתם יכולים להשתמש בתצוגות כדי להגדיר את סוגי הצמתים והקצוות בלי להעביר את הנתונים הבסיסיים. לדוגמה, אתם יכולים לעבור ממודל טיפוסי ללא סכימה שמשתמש בטבלאות קנוניות של GraphNode ו-GraphEdge. כדי לעשות את זה, יוצרים תצוגות (views) שמחלצות את הנתונים מהטבלאות ללא הסכימה:

  1. מגדירים תצוגה לכל סוג של צומת וקשת שרוצים להגדיר באופן רשמי (לדוגמה, Person או WorksFor). בתצוגה, מסננים את הנתונים לפי התווית שלהם (לדוגמה, WHERE n_label = "person") וממירים את המאפיינים מעמודת ה-JSON לסוגי נתונים ספציפיים (לדוגמה, STRING(prop.name) AS name).

  2. מגדירים תרשים מאפיינים חדש שבו NODE TABLES ו-EDGE TABLES מפנים לתצוגות המוקלדות שיצרתם.

תרשים ללא סכימה מספק ביצועים טובים יותר מתרשים רשמי עבור שאילתות מסוימות (לדוגמה, תבנית נתיב מכומתת עם כמה סוגי קצוות). אם מטא-נתונים רשמיים חשובים לתרחיש לדוגמה שלכם, אתם יכולים להשתמש בתצוגות כדי לעבור מתרשים ללא סכימה לסכימה עם סוגים. אתם יכולים גם להשתמש בתרשים ללא סכימה בתרחישים מסוימים, ובתרשים עם סכימה מוקלדת בתרחישים אחרים. מידע נוסף זמין במאמר בחירת עיצוב סכימה על סמך שאילתות גרפיות.

בדוגמה הבאה מוצג תהליך העבודה למעבר מגרף ללא סכימה לגרף פורמלי בארבעה שלבים:

  1. מגדירים את הטבלאות הקנוניות GraphNode ו-GraphEdge למודל ללא סכימה.

  2. ליצור תרשים ראשוני וגמיש בטבלאות האלה, שאין להן סכימה.

  3. מגדירים תצוגות מוקלדות (Person,‏ Company,‏ WorksFor) שמחלצות את הנתונים מהטבלאות ללא הסכימה ומעצבות אותם.

  4. יוצרים את התרשים הסופי עם סוגים מוגדרים, שמשתמש בתצוגות האלה כטבלאות הצמתים והקצוות שלו.

-- 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)
  );

המאמרים הבאים