עבודה עם מדדים
במאמר הזה מוסבר איך להגדיר מדדים בתרשימים ולשלוח שאילתות לגביהם. אתם יכולים להשתמש במדדים כדי לוודא שצבירות הנתונים מתבצעות בצורה נכונה בין צירופים.
סקירה כללית
מדד הוא מאפיין מצטבר שמוגדר בסעיף PROPERTIES של טבלת צמתים או קצוות. מדדים מוגדרים באמצעות ביטוי מדד, שנוצר באמצעות מילת המפתח MEASURE סביב אחד מהבאים:
- ביטוי צבירה
- ביטוי שמשלב פונקציות צבירה עם פעולות סקלריות
- מדד נגזר, שהוא שילוב של מדדים שעטופים בפונקציה
AGGומוגדרים באותה טבלת רכיבים
מדדים תומכים בפונקציות הצבירה הבאות:
SUMAVGCOUNTMINMAX-
AGG(למדדים נגזרים)
כל פונקציות הצבירה, חוץ מ-AGG, תומכות במילת המפתח DISTINCT. למידע נוסף על ביטויי המידה הנתמכים, קראו על סוג המידה.
המדדים מגדירים את הצבירה שלהם בהתייחס ל-KEY של הצומת או טבלת הקצוות שבה הם מוגדרים. כלומר, כששולחים שאילתה לגבי מדד, הצבירה מתבצעת בצורה נכונה גם אם הטבלה הבסיסית מצורפת באופן שגורם לשכפול שורות.
אי אפשר להפנות למאפיין שמוגדר על ידי מדד בשאילתת GQL. במקום זאת, אתם ניגשים למדדים על ידי קריאה ל-GRAPH_EXPAND TVF כדי לשלוח שאילתה לייצוג יחסי של התרשים. כברירת מחדל, GRAPH_EXPAND מחזירה ייצוג טבלה שטוח של התרשים, עם עמודה אחת לכל מאפיין. אפשר גם לציין את הערך flatten_results => FALSE כדי להחזיר טבלה היררכית עם עמודות STRUCT בתצוגת עץ. אם התרשים מכיל כמה טבלאות של צומתי שורש, אפשר לציין את הארגומנט start_node כדי לבחור באיזו טבלת שורש לעבור.
הפונקציה הזו לא מקבלת את כל סוגי התרשימים. במגבלות הקלט מוסבר אילו גרפים יוצרים קלט תקין.
כדי להריץ שאילתות GQL, צריך הזמנה שמשתמשת במהדורת Enterprise או Enterprise Plus.
אם אתם משתמשים בתמחור על פי דרישה, אתם יכולים להפעיל את הפונקציה GRAPH_EXPAND כדי להריץ שאילתות SQL על התרשים.
אפשר להפעיל את הפונקציה AGG על הפלט של ה-TVF GRAPH_EXPAND כדי לצבור את המאפיינים לפי הצבירה שמוגדרת במדד.
הגדרת מדדים
כדי להגדיר מדדים בסעיף PROPERTIES של הגדרת טבלת צומת או קשת, משתמשים במילת המפתח MEASURE() סביב ביטוי המדד.
בדוגמה הבאה נוצר מערך נתונים בשם university וטבלאות למכללות, למחלקות ולקורסים:
CREATE SCHEMA IF NOT EXISTS university;
CREATE OR REPLACE TABLE university.College (
college_id INT64 PRIMARY KEY NOT ENFORCED,
college_name STRING
);
CREATE OR REPLACE TABLE university.Department (
dept_id INT64 PRIMARY KEY NOT ENFORCED,
dept_name STRING,
college_id INT64,
budget FLOAT64,
FOREIGN KEY (college_id) REFERENCES university.College(college_id) NOT ENFORCED
);
CREATE OR REPLACE TABLE university.Course (
course_id INT64 PRIMARY KEY NOT ENFORCED,
course_name STRING,
dept_id INT64,
credits INT64,
FOREIGN KEY (dept_id) REFERENCES university.Department(dept_id) NOT ENFORCED
);
INSERT INTO university.College (college_id, college_name)
VALUES (101, 'College of Engineering'),
(102, 'College of Arts');
INSERT INTO university.Department (dept_id, dept_name, college_id, budget)
VALUES (1001, 'Computer Science', 101, 500000),
(1002, 'Mechanical Engineering', 101, 400000),
(1003, 'Fine Arts', 102, 200000),
(1004, 'Research', 101, 50000);
INSERT INTO university.Course (course_id, course_name, dept_id, credits)
VALUES (1, 'Intro to CS', 1001, 3),
(2, 'Data Structures', 1001, 4),
(3, 'Thermodynamics', 1002, 3),
(4, 'Oil Painting', 1003, 2);
ההצהרה הבאה יוצרת תרשים בשם SchoolGraph שמגדיר מדדים במאפיינים בצמתים Department ו-Course.
צריך לספק כינוי למאפיינים שמוגדרים על ידי מדד.
CREATE OR REPLACE PROPERTY GRAPH university.SchoolGraph
NODE TABLES (
university.College
KEY(college_id)
PROPERTIES(college_id, college_name),
university.Department
KEY(dept_id)
PROPERTIES(dept_id, dept_name, college_id,
budget OPTIONS(description="Department budget in USD"),
MEASURE(SUM(budget)) AS total_budget,
MEASURE(SUM(budget) * 1.10) AS budget_with_overhead OPTIONS(
description="Total department budget including 10% overhead",
extensions=[("unit", "USD"), ("tier", "planning")]
)),
university.Course
KEY(course_id)
PROPERTIES(
course_id,
course_name,
credits,
dept_id,
MEASURE(AVG(credits)) AS avg_credits,
MEASURE(SUM(credits)) AS total_credits,
MEASURE(COUNT(course_id)) AS course_count,
MEASURE(COUNT(DISTINCT CASE WHEN credits >= 3 THEN course_id ELSE NULL END)) AS major_course_count,
MEASURE(SAFE_DIVIDE(AGG(total_credits), NULLIF(AGG(course_count), 0))) AS computed_avg_credits)
)
EDGE TABLES (
university.Department AS CollegeDept
SOURCE KEY (college_id) REFERENCES College (college_id)
DESTINATION KEY (dept_id) REFERENCES Department (dept_id),
university.Course AS DeptCourse
SOURCE KEY (dept_id) REFERENCES Department (dept_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id)
);

המדד total_budget מוגדר בתור MEASURE(SUM(budget)). המדד נועל את הצבירה ל-KEY, שהוא dept_id.
מדדים נגזרים
מדד נגזר הוא מדד שמפנה למדדים אחרים שמוגדרים באותה טבלת רכיבים באמצעות הפונקציה AGG(). הפונקציונליות הזו מאפשרת לכם ליצור היררכיות של מדדים לשימוש חוזר.
לדוגמה, ב-university.Course, המדד computed_avg_credits מחשב את היחס בין המדדים total_credits ו-course_count:
MEASURE(SAFE_DIVIDE(AGG(total_credits), NULLIF(AGG(course_count), 0))) AS computed_avg_credits
מדדים נגזרים שומרים על מאפיין נעילת הפירוט של מפתח טבלת הרכיבים הבסיסי. יחסי התלות של המדדים נפתרים בזמן הידור התרשים. הפניות מעגליות בין מדדים מחזירות שגיאה.
הסבר על ספירת יתר
כשמצרפים טבלאות, הנתונים חוזרים על עצמם בכל פעם שיש קשר של אחד לרבים בנתונים. לדוגמה, אם מאחדים את הטבלאות Course, Department ו-College, מחלקה עם כמה קורסים תופיע בכמה שורות בפלט:
SELECT
college_name,
dept_name,
course_name,
budget
FROM university.Course
LEFT JOIN university.Department
ON Course.dept_id = Department.dept_id
LEFT JOIN university.College
ON Department.college_id = College.college_id;
/*------------------------+------------------------+-----------------+----------+
| college_name | dept_name | course_name | budget |
+------------------------+------------------------+-----------------+----------+
| College of Engineering | Computer Science | Intro to CS | 500000.0 |
| College of Engineering | Computer Science | Data Structures | 500000.0 |
| College of Engineering | Mechanical Engineering | Thermodynamics | 400000.0 |
| College of Arts | Fine Arts | Oil Painting | 200000.0 |
+------------------------+------------------------+-----------------+----------*/
אם תנסו לחשב את התקציב הכולל של כל מכללה באמצעות SUM(budget), התקציב של המחלקה למדעי המחשב ייספר פעמיים. כדי להימנע מהבעיה הזו, אפשר לשלוח שאילתה ישירות לטבלה Department, אבל הגישה הזו לא עובדת אם רוצים לחשב כמה צבירות מטבלאות שונות שתורמות לנתונים המצורפים. בקטע הבא מוסבר איך מדדים פותרים את הבעיה הזו.
שאילתה על גרף עם מדדים
אפשר לשלוח שאילתה לתרשים עם מדדים באמצעות GQL, אבל השאילתה לא יכולה להפנות ישירות למאפיין שמוגדר על ידי מדד. לדוגמה, השאילתה הבאה מפנה לצמתים שמוגדרים בהם מאפייני מדידה, אבל לא משתמשת באף אחד משדות המדידה ולא מחזירה אותם:
GRAPH university.SchoolGraph
MATCH (c:College)->(d:Department)->(course:Course)
RETURN c.college_name, d.dept_name, course.course_name;
/*------------------------+------------------------+-----------------+
| college_name | dept_name | course_name |
+------------------------+------------------------+-----------------+
| College of Engineering | Computer Science | Intro to CS |
| College of Engineering | Computer Science | Data Structures |
| College of Engineering | Mechanical Engineering | Thermodynamics |
| College of Arts | Fine Arts | Oil Painting |
+------------------------+------------------------+-----------------*/
כדי לעבוד עם מידות, משתמשים בפונקציה עם ערך טבלה (TVF) GRAPH_EXPAND כדי לשלוח שאילתות לתרשים כטבלה יחסית:
GRAPH_EXPAND(
graph_name [, start_node => 'NodeName'] [, flatten_results => TRUE|FALSE]
)
הפונקציה מקבלת את הארגומנטים הבאים:
-
graph_name:STRINGשמכיל את שם התרשים. -
start_node: ערךSTRINGאופציונלי שמציין את טבלת הצומת ההתחלתית למעבר. הארגומנט הזה נדרש אם בתרשים יש כמה טבלאות של צומתי שורש. -
flatten_results:BOOLאופציונלי (ברירת המחדל היאTRUE):-
TRUE: משטיח את כל מאפייני הצמתים והקצוות לעמודות ברמה העליונה עם הקידומות<element>_<property>. -
FALSE: מחזירה את מאפייני צומת הבסיס כעמודות ברמה העליונה ללא קידומת, ואת טבלאות השכנים המצורפות כעמודותSTRUCT.
-
שימוש בפלט שטוח
כשהערך של flatten_results הוא TRUE (מצב ברירת המחדל), העמודות בטבלת הפלט נקראות על ידי שרשור התווית של טבלת הצמתים או הקצוות ושם המאפיין – לדוגמה, Course_course_name או Department_total_budget. השאילתה הבאה מציגה פלט לדוגמה מהפונקציה GRAPH_EXPAND:
SELECT
College_college_name,
Department_dept_name,
Department_budget,
Course_course_name
FROM
GRAPH_EXPAND("university.SchoolGraph");
/*------------------------+------------------------+-------------------+--------------------+
| College_college_name | Department_dept_name | Department_budget | Course_course_name |
+------------------------+------------------------+-------------------+--------------------+
| College of Engineering | Computer Science | 500000.0 | Intro to CS |
| College of Engineering | Computer Science | 500000.0 | Data Structures |
| College of Engineering | Mechanical Engineering | 400000.0 | Thermodynamics |
| College of Arts | Fine Arts | 200000.0 | Oil Painting |
+------------------------+------------------------+-------------------+--------------------*/
הפונקציה GRAPH_EXPAND יוצרת את הטבלה השטוחה על ידי הפעלת סדרה של פעולות LEFT JOIN על טבלאות של צמתים וקצוות. אם לא מציינים צומת התחלה, בתרשים הקלט חייבת להיות טבלת צומת שורש אחת בתרשים קשרי הסכימה.
באופן דומה, לטבלת צומת הבסיס חייב להיות קשר של רבים-לאחד עם כל טבלת צומת אחרת שיש לה קצה משותף איתה.
נתונים שאי אפשר להגיע אליהם מטבלת צומת הבסיס באמצעות סדרה של איחודים לא מופיעים בפלט. בדוגמה הקודמת, Course היא טבלת צומת הבסיס. המחלקה Research הושמטה מהפלט כי אין בה קורסים.
אי אפשר לבחור ישירות עמודה של מאפיין שמוגדר לפי מדד.
במקום זאת, צריך לעטוף אותם בפונקציה AGG().
הפונקציה הזו מבטיחה שהצבירה שמוגדרת במדדים תתבצע בדיוק פעם אחת לכל מפתח.
השאילתה הבאה מחשבת בו-זמנית את התקציב הכולל ואת המספר הכולל של הקורסים בכל מכללה:
SELECT
College_college_name,
AGG(Department_total_budget) AS college_budget,
AGG(Course_course_count) AS total_courses
FROM
GRAPH_EXPAND("university.SchoolGraph")
GROUP BY
College_college_name;
/*------------------------+----------------+---------------+
| College_college_name | college_budget | total_courses |
+------------------------+----------------+---------------+
| College of Engineering | 900000.0 | 3 |
| College of Arts | 200000.0 | 1 |
+------------------------+----------------+---------------*/
שימוש בפלט היררכי
כשמציינים את flatten_results => FALSE, הפונקציה GRAPH_EXPAND מחזירה קשר היררכי במקום עמודות עם קידומת:
- המאפיינים של צומת הבסיס ההתחלתי מופיעים כעמודות ברמה העליונה ללא קידומת (לדוגמה,
course_nameאוcredits). - המאפיינים של טבלאות שכנות שמצורפות, שיכולות להיות טבלאות של צמתים או של קצוות, מופיעים כשדות
STRUCTבתצוגת עץ שנקראים על שם טבלת הרכיבים. לדוגמה, אם הצומת ההתחלתי הואCourse, צריך להשתמש במאפיין DeptCourse.Department.CollegeDept.College.college_nameto access thecollege_name`. - כדי לשלוח שאילתות על מדדים בתוך מבנים מקוננים, משתמשים בסימון נקודה בתוך
AGG()– לדוגמה,AGG(DeptCourse.Department.total_budget). - אם בטבלת רכיבים יש מאפיין עם שם זהה לזה של טבלת רכיבים סמוכה, אי אפשר לשלוח שאילתה לתרשים באמצעות
flatten_results => FALSE. במקום זאת, צריך לשטח את התוצאות.
SELECT
DeptCourse.Department.dept_name AS department_name,
DeptCourse.Department.CollegeDept.College.college_name,
AGG(DeptCourse.Department.total_budget) AS total_budget,
AGG(course_count) AS total_courses
FROM GRAPH_EXPAND(
"university.SchoolGraph",
start_node => "Course",
flatten_results => FALSE)
GROUP BY department_name, college_name;
עבודה עם כמה טבלאות של צומתי שורש
תרשימים מכילים לעיתים קרובות כמה טבלאות של צומתי שורש, שנקראות גם טבלאות עובדות, שחולקות טבלאות מאפיינים. כדי לשלוח שאילתה לתרשים עם כמה טבלאות של צומתי שורש, משתמשים בארגומנט start_node ב-GRAPH_EXPAND. הפונקציה עוברת על תת-הגרף שאפשר להגיע אליו מצומת ההתחלה.
לדוגמה, אפשר להוסיף טבלת Instructor למערך הנתונים university שמקושר גם ל-Department:
CREATE OR REPLACE TABLE university.Instructor (
instructor_id INT64 PRIMARY KEY NOT ENFORCED,
instructor_name STRING,
dept_id INT64,
salary FLOAT64,
FOREIGN KEY (dept_id) REFERENCES university.Department(dept_id) NOT ENFORCED
);
INSERT INTO university.Instructor (instructor_id, instructor_name, dept_id, salary)
VALUES (501, 'Dr. Dana', 1001, 120000),
(502, 'Dr. Lee', 1001, 110000),
(503, 'Dr. Taylor', 1002, 115000),
(504, 'Prof. Izumi', 1003, 90000);
אפשר ליצור תרשים חדש בשם university.SchoolGraphMultiRoot שכולל את טבלת הצמתים Instructor וקשת מ-Instructor אל Department:
CREATE OR REPLACE PROPERTY GRAPH university.SchoolGraphMultiRoot
NODE TABLES (
university.College
KEY(college_id)
PROPERTIES(college_id, college_name),
university.Department
KEY(dept_id)
PROPERTIES(dept_id, dept_name, college_id, budget,
MEASURE(SUM(budget)) AS total_budget),
university.Course
KEY(course_id)
PROPERTIES(
course_id, course_name, credits, dept_id,
MEASURE(COUNT(course_id)) AS course_count),
university.Instructor
KEY(instructor_id)
PROPERTIES(
instructor_id, instructor_name, dept_id, salary,
MEASURE(COUNT(instructor_id)) AS instructor_count,
MEASURE(SUM(salary)) AS total_salary)
)
EDGE TABLES (
university.Department AS CollegeDept
SOURCE KEY (college_id) REFERENCES College (college_id)
DESTINATION KEY (dept_id) REFERENCES Department (dept_id),
university.Course AS DeptCourse
SOURCE KEY (dept_id) REFERENCES Department (dept_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id),
university.Instructor AS DeptInstructor
SOURCE KEY (dept_id) REFERENCES Department (dept_id)
DESTINATION KEY (instructor_id) REFERENCES Instructor (instructor_id)
);
בתרשים הזה, גם Course וגם Instructor משמשות כטבלאות של צומתי שורש שמקושרות ל-Department ול-College. כדי לטרגט כל אחד מתתי-התרשימים, מעבירים את הערך start_node:
-- Expand the Course subgraph (Course -> Department -> College)
SELECT
College_college_name,
AGG(Course_course_count) AS total_courses
FROM GRAPH_EXPAND("university.SchoolGraphMultiRoot", start_node => "Course")
GROUP BY College_college_name;
-- Expand the Instructor subgraph (Instructor -> Department -> College)
SELECT
College_college_name,
AGG(Instructor_total_salary) AS total_faculty_salary
FROM GRAPH_EXPAND("university.SchoolGraphMultiRoot", start_node => "Instructor")
GROUP BY College_college_name;
כדי לנתח מדדים בכמה טבלאות עובדות, שולחים שאילתה לכל תת-תרשים באמצעות GRAPH_EXPAND ומאחדים אותם במאפיינים המשותפים שלהם ב-SQL רגיל:
SELECT
C.College_college_name,
AGG(C.Course_course_count) AS total_courses,
AGG(I.Instructor_total_salary) AS total_faculty_salary
FROM GRAPH_EXPAND("university.SchoolGraphMultiRoot", start_node => "Course") AS C
INNER JOIN GRAPH_EXPAND("university.SchoolGraphMultiRoot", start_node => "Instructor") AS I
ON C.Department_dept_id = I.Department_dept_id
GROUP BY C.College_college_name;
גם AGG(C.Course_course_count) וגם AGG(I.Instructor_total_salary) מחשבים את הצבירות שלהם בצורה מדויקת ברמות הפירוט המתאימות, בלי הפרעה מהצירוף.
שיטות מומלצות
כשאתם מעצבים תרשים עם מדדים, כדאי לפעול לפי השיטות המומלצות הבאות:
הגדרת צמתים וקצוות בטבלה אחת
מומלץ להשתמש באותה טבלה להגדרה של טבלת צמתים ולהגדרות של טבלאות הקשתות שמחברות ביניהם. שימוש חוזר בטבלה מבטיח קשר של אחד לאחד (1:1) בין טבלת הצמתים לטבלת הקצוות, מה שמונע פיצול ומבטיח שהפונקציה GRAPH_EXPAND לא תתעלם מהקצה בגלל חוסר בהירות.
לדוגמה, אם יש לכם טבלת קלט Enrollment שמכילה מפתחות זרים שמפנים לטבלאות Student ו-Course, אתם צריכים להגדיר את הצומת Enrollment ואת הקצוות היוצאים שלו באמצעות טבלת הקלט Enrollment.
הימנעו מהגדרת מאפיינים מיותרים בטבלאות קצה
כשמגדירים טבלת צמתים וטבלת קשתות באמצעות אותה טבלה פיזית, אל תשתמשו בסעיף PROPERTIES בטבלת הקשתות, אלא אם יש מידע חדש שצריך לתעד בקשת. מכיוון שטבלת הצמתים וטבלת הקשתות משתמשות באותה טבלה פיזית, כל המאפיינים האלה כבר נמצאים בטבלת הצמתים.
הגדרת מאפיינים מיותרים בטבלת הקצוות עלולה לגרום לפונקציה GRAPH_EXPAND להתייחס לטבלת הקצוות כישות נפרדת מטבלת הצמתים המשותפת. כדי לשפר את הביצועים, צריך לציין את הערך NO PROPERTIES בהגדרה של טבלת הקצוות כשאין מאפיינים חדשים לתעד בקצה.
מודל של קשרי רבים לרבים כטבלאות צמתים
קשר של רבים לרבים (M:N) מתרחש כששורה בטבלה A יכולה להתאים לכמה שורות בטבלה B, ושורה בטבלה B יכולה להתאים לכמה שורות בטבלה A. לדוגמה, תלמיד אחד יכול להירשם לכמה קורסים, ובקורס אחד יכולים להיות הרבה תלמידים. אפשר להפריד קשר מסוג רבים לרבים לשני קשרים מסוג אחד לרבים באמצעות טבלת צומת ביניים. לדוגמה, אפשר להגדיר טבלת Enrollment שמכילה מפתחות זרים שמצביעים על טבלאות Student ו-Course. אם ממדלים טבלת צומת ביניים כטבלת קצה שמחברת בין שתי טבלאות צומת של מאפיינים בהצהרת CREATE PROPERTY GRAPH, כמו בדוגמה הבאה, הפונקציה GRAPH_EXPAND מתעלמת מהקצוות האלה כי הקשר שלהם לא ברור: לא ברור אם הוא רבים-לאחד או אחד-לאחד.
CREATE PROPERTY GRAPH university.SchoolGraph
NODE TABLES (
university.Student,
university.Course
)
EDGE TABLES (
-- Modeling the junction table as a standalone edge causes ambiguity
university.Enrollment AS StudentEnrollment
SOURCE KEY (student_id) REFERENCES Student (student_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id)
);
אם המערכת מתעלמת מכל הקצוות בתרשים, הקריאות ל-GRAPH_EXPAND או ל-BQ.SHOW_GRAPH_EXPAND_SCHEMA נכשלות ומופיעה הודעת שגיאה.
כדי ליצור מודל נכון של קשר M:N למדדים, צריך לקדם את טבלת הצומת (junction) לטבלת צומת (node). במבנה הזה, טבלת קישורי הצמתים משמשת כטבלת צומת הרמה הבסיסית (root) היחידה (טבלת צומת עם דרגת כניסה אפס). אחר כך מגדירים שתי טבלאות קצוות מסוג רבים-ליחיד (N:1) שחולקות את טבלת הצומת כדי לקשר את N:1 לכל אחת מטבלאות צומתי המאפיינים:
CREATE PROPERTY GRAPH university.SchoolGraph
NODE TABLES (
university.Student KEY (student_id),
university.Course KEY (course_id),
-- Promote the junction table to a node table (acting as the single root node)
university.Enrollment KEY (enrollment_id)
)
EDGE TABLES (
-- Share (reuse) the Enrollment table to define N:1 edges to each dimension
university.Enrollment AS EnrollmentToStudent
SOURCE KEY (enrollment_id) REFERENCES Enrollment (enrollment_id)
DESTINATION KEY (student_id) REFERENCES Student (student_id),
university.Enrollment AS EnrollmentToCourse
SOURCE KEY (enrollment_id) REFERENCES Enrollment (enrollment_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id)
);
במבנה הזה, Enrollment משמשת כטבלת צומת הבסיס היחידה (דרגת כניסה אפס) שמחברת בין N:1 לטבלאות המאפיינים Student ו-Course (דרגת כניסה אחת). הפונקציה GRAPH_EXPAND יכולה לשטח את התרשים הזה על ידי מעבר החוצה מ-Enrollment אל Student ואל Course. אם אתם מגדירים מדדים באחת מהטבלאות האלה, אתם יכולים להפעיל את הפונקציה AGG בעמודות המדדים כדי לחשב בצורה נכונה את הצבירות בלי לספור יותר מדי.
בחירת האופן שבו המדדים מטפלים בשורות שלא תואמות
אם לשורה אין התאמה בטבלה של רכיב מקושר, העמודות של הטבלה הזו הן NULL בפלט של GRAPH_EXPAND. לדוגמה, אם לקורס אין ערך dept_id, העמודות Department של אותה שורה הן NULL. השאלה אם מדד בצומת Department כולל את השורות האלה תלויה במיקום שבו כותבים את הביטוי הסקלרי שהמדד צובר.
אם כותבים את הביטוי בתוך פונקציית הצבירה, הביטוי מוערך לכל שורה בפלט המורחב, כולל שורות ללא התאמה.
כשהביטוי מחזיר ערך שהוא לא NULL לאחת מהשורות האלה, הערך הזה תורם לתוצאה.
אם מגדירים את הביטוי כמאפיין ומפנים למאפיין הזה מהמדד, הביטוי נבדק בשורות של טבלת הצומת, ושורות ללא התאמה לא תורמות לתוצאה.
בדוגמה הבאה מוגדר אותו ביטוי בשתי הדרכים ב-university.Department:
university.Department
KEY(dept_id)
PROPERTIES(dept_id, dept_name, college_id, budget,
COALESCE(budget, 0) AS budget_or_zero,
-- Includes courses that have no department, as a budget of 0.
MEASURE(AVG(COALESCE(budget, 0))) AS avg_budget_inline,
-- Averages only departments that exist.
MEASURE(AVG(budget_or_zero)) AS avg_budget_property)
שני המדדים מחליפים תקציב של NULL בתקציב של 0. הטופס המוטמע גם מחליף את הערכים של NULL שנוצרו לקורס שאין לו מחלקה, כך שהקורס הזה נכלל בממוצע כמחלקה עם תקציב של 0. בוחרים את הטופס שמתאים למה שרוצים למדוד.
הצגת הסכימה של GRAPH_EXPAND
כדי לראות את הסכימה של הטבלה שמוחזרת על ידי הפונקציה GRAPH_EXPAND בלי להפעיל את הפונקציה, משתמשים בפרוצדורת המערכת BQ.SHOW_GRAPH_EXPAND_SCHEMA:
DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('university.SchoolGraph', schema);
SELECT schema;
התהליך הזה מאכלס את המשתנה schema בשם, בסוג ובמצב של כל עמודה. הוא גם מציין אם המאפיין שהעמודה מתייחסת אליו הוא מדד, ומפרט את התיאור או המילים הנרדפות שהגדרתם לו.