שאילתות מתמשכות של תצוגות מהותיות

כדי ליצור תצוגה מהותית מתמשכת של טבלת Bigtable, מריצים שאילתת SQL שמגדירה את התצוגה המהותית המתמשכת.

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

תצוגות חומריות רציפות משתמשות בתחביר SQL מוגבל. בדוגמה הבאה אפשר לראות איך ליצור שאילתת SQL של תצוגה חומרית מתמשכת:

SELECT
  expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
GROUP BY expression [, ...];

from_item:
    {
      table_name [ as_alias ]
      | field_path
      }

as_alias:
    [ AS ] alias

אם רוצים ליצור שאילתת SQL של תצוגה חומרית מתמשכת כאינדקס משני אסינכרוני, משתמשים בפסקה ORDER BY:

SELECT
  expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
ORDER BY expression [, ...];

from_item:
    {
      table_name [ as_alias ]
      | field_path
      }

as_alias:
    [ AS ] alias

מגבלות על שאילתות

הכללים הבאים חלים על שאילתת SQL שמשמשת ליצירת תצוגה מהותית רציפה:

  • חייב להיות משפט SELECT.
  • חייב להיות סעיף GROUP BY או, בשאילתות אסינכרוניות של אינדקס משני, סעיף ORDER BY, אבל לא את שניהם.
  • חובה להשתמש רק בפונקציות צבירה נתמכות.
  • יכולות להיות כמה צבירות בכל קבוצה.

צבירות נתמכות

אפשר להשתמש בפונקציות הצבירה הבאות בשאילתת SQL שמגדירה תצוגה חומרית רציפה:

  • COUNT
  • SUM
  • MIN
  • MAX
  • HLL_COUNT.INIT
  • HLL_COUNT.MERGE
  • HLL_COUNT.MERGE_PARTIAL
  • ANY_VALUE
  • BIT_AND
  • BIT_OR
  • BIT_XOR
  • AVG

אם SELECT COUNT(*), צריך להגדיר מפתח שורה, כמו בדוגמה הבאה:

SELECT
  '*' AS _key,
  COUNT(*) AS count
FROM
  foo
GROUP BY
  _key;

תכונות SQL שלא נתמכות

אי אפשר להשתמש בתכונות ה-SQL הבאות:

  • כל תכונה שלא נתמכת ב-GoogleSQL for Bigtable
  • ARRAY
  • ARRAY_AGG
  • ARRAY_CONCAT_AGG
  • COUNT_IF
  • CURRENT_TIME ופונקציות לא דטרמיניסטיות אחרות
  • DATE, DATETIME כעמודות פלט (אפשר להשתמש ב-TIMESTAMP או לאחסן מחרוזת).
  • DESC מיון בפלט
  • DISTINCT, כמו ב-SUM(*DISTINCT* value))
  • LIMIT/OFFSET
  • SELECT *
  • OVER clause כדי ליצור צבירה של חלונות
  • STRUCT

בנוסף, אי אפשר להשתמש בסעיפים GROUP BY או ORDER BY כסעיפים משנה או ליצור עמודות מיפוי. מידע על מגבלות נוספות זמין במאמר מגבלות.

הימנעות משורות שמוחרגות

שורות קלט לא נכללות בתצוגה חומרית מתמשכת במקרים הבאים:

  • נבחרו יותר מ-1MiB של נתונים מהשורה. לדוגמה, אם השאילתה היא SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY apples, כל שורה שמכילה יותר מ-1MiB של נתונים בעמודות apple ו-banana לא תיכלל בתצוגה המתמשכת של החומרים.
  • יותר מ-1MiB של נתונים מופקים מהשורה. הבעיה הזו יכולה להתרחש כשמשתמשים בשאילתות כמו SELECT REPEAT(apple, 1000) או כשמשתמשים בקבועים גדולים.
  • הפלט מכיל נתונים בכמות גדולה פי 10 או יותר מהכמות שנבחרה.
  • השאילתה לא תואמת לנתונים שלכם. הדוגמאות כוללות ניסיון לחלק באפס, הצפה של מספר שלם או ציפייה לפורמט של מפתח שורה שלא נמצא בכל מפתח שורה.

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

פרטי שאילתה

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

הצהרת SELECT

הצהרת הבחירה מגדירה את העמודות והצבירות שמשמשות בתצוגה המגולמת הרציפה. ההצהרה צריכה להשתמש בסעיף GROUP BY כדי לצבור נתונים בשורות או בסעיף ORDER BY כדי ליצור אינדקס משני אסינכרוני.

אין תמיכה ב-SELECT *, אבל יש תמיכה ב-SELECT COUNT(*).

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

זו דוגמה לשאילתת צבירה רגילה ב-SQL:GROUP BY

SELECT
  myfamily["node"] AS node,
  myfamily["type"] AS type,
  COUNT(clicks) AS clicks_per_key
FROM
  mytable
GROUP BY
  node,
  type

מפתחות שורות ונתונים לא מצטברים

אפשר לציין _key כמפתח השורה לתצוגה חומרית רציפה. אם לא, העמודות בסעיף GROUP BY יוצרות את המפתח בתצוגה.

מפתחות השורות מוגדרים על ידי עמודה _key

אפשר לציין עמודה _key כשמגדירים תצוגה חומרית רציפה. (העמודה הזו שונה מהעמודה _key שמתקבלת כשמריצים שאילתת SQL בטבלת Bigtable). אם מציינים _key, הכללים הבאים חלים:

  • חובה לקבץ לפי _key, ואי אפשר לקבץ לפי שום דבר אחר חוץ מ_timestamp (אופציונלי). מידע נוסף זמין במאמר בנושא חותמות זמן.
  • העמודה _key חייבת להיות מסוג BYTES.

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

מפתחות השורות מוגדרים על ידי פסקה GROUP BY או ORDER BY

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

עמודות הפלט שלא צורף להן ערך מצטבר ברשימה SELECT צריכות להיכלל בסעיף GROUP BY. הסדר שבו העמודות נכתבות בסעיף GROUP BY הוא הסדר שבו הנתונים מאוחסנים במפתח השורה של התצוגה הממומשת הרציפה. לדוגמה, GROUP BY a, b, c הוא באופן מרומז ORDER BY a ASC, b ASC, c ASC.

אם משתמשים בסעיף ORDER BY במקום בסעיף GROUP BY כדי ליצור אינדקס משני אסינכרוני, העמודות ברשימה SELECT שכלולות בסעיף ORDER BY הופכות למפתח השורה בתצוגה. הסדר שבו העמודות נכתבות בפסוקית ORDER BY הוא הסדר שבו הנתונים מאוחסנים במפתח השורה של התצוגה המהותית הרציפה. לדוגמה, ORDER BY a, b, c מאחסן את הנתונים עם מפתחות שורות שממוינים לפי a ASC, ואז לפי b ASC, ואז לפי c ASC.

מסנן ה-SQL צריך להסיר ערכים פוטנציאליים של NULL או ערכים לא תקינים אחרים שיכולים לגרום לשגיאות. שורה לא תקינה, כמו שורה שמכילה עמודת מפתח NULL, מושמטת מהתוצאות ונספרת במדד materialized_view/user_errors. כדי לנפות שגיאות של משתמשים, מומלץ להריץ את שאילתת ה-SQL מחוץ לתצוגה חומרית רציפה.

נתונים מצטברים

עמודות מצטברות בשאילתה מגדירות את החישובים שיוצרים את הנתונים בתצוגה המגובשת המתמשכת.

הכינוי של עמודה מצטברת נחשב כמסווג עמודות בתצוגה הממומשת הרציפה.

דוגמה:

SELECT
  fam["baz"] AS baz,
  SUM(fam["foo"]) AS sum_foo,
  SUM(fam["bar"]) AS sum_bar
FROM
  TABLE

GROUP BY
  baz;

המאפיינים של פלט השאילתה:

  • הפלט של כל baz מופיע בשורה נפרדת בסדר baz ASC.
  • אם ל-baz מסוים יש לפחות foo אחד, אז הערך של sum_foo בשורת הפלט הוא ערך שאינו NULL.
  • אם ל-baz מסוים יש לפחות bar אחד, אז הערך של sum_bar בשורת הפלט הוא ערך שאינו NULL.
  • אם ל-baz מסוים אין ערך באחת מהעמודות, הוא לא ייכלל בתוצאות.

אם תריצו שאילתה על התצוגה עם SELECT *, התוצאה תיראה בערך כך:

baz sum_foo sum_bar
baz1 sum_foo1 sum_bar1
baz2 sum_foo2 sum_bar2

חותמות זמן

חותמת הזמן שמוגדרת כברירת מחדל לתא פלט בתצוגה חומרית רציפה היא 0 (1970-01-01 00:00:00Z). אפשר לראות את זה כשקוראים את התצוגה באמצעות ReadRows, ולא כשמבצעים שאילתה באמצעות SQL.

כדי להשתמש בחותמת זמן אחרת בפלט, אפשר להוסיף עמודה מסוג TIMESTAMP לרשימת SELECT של השאילתה ולתת לה את השם _timestamp. אם שולחים שאילתה לתצוגה חומרית רציפה באמצעות ReadRows,‏ _timestamp הופך לחותמת הזמן של התאים האחרים בשורה.

חותמת הזמן לא יכולה להיות NULL, היא חייבת להיות גדולה מ-0 או שווה ל-0, והיא חייבת להיות כפולה של 1,000 (דיוק של אלפית השנייה). מערכת Bigtable לא תומכת בחותמות זמן של תאים שמוקדמות לראשית זמן יוניקס (1970-01-01T00:00:00Z).

דוגמה: דגימה מחדש של נתונים מצטברים לפי יום. השאילתה משתמשת בפונקציה UNPACK.

SELECT
  _key,
  TIMESTAMP_TRUNC(_timestamp, DAY) AS _timestamp,
  SUM(sum_family["sum_column"]) AS sum_column,
  SUM(sum_family["foo"]) AS second_sum_column
FROM
  UNPACK(
  SELECT
    *
  FROM
    my_table(with_history => TRUE))
GROUP BY
  1,
  2

אם ל-SUM מסוים יש קלט לא ריק ביום מסוים, שורת הפלט מכילה ערך מצטבר עם חותמת זמן שתואמת ליום שקוצץ.

אם מריצים שאילתה על התצוגה עם SELECT *, התוצאה תיראה כך:

_key _timestamp sum_column second_sum_column
1 2024-05-01 00:00:00Z 23 99
2 2024-05-02 00:00:00Z 45 201
3 2024-05-03 00:00:00Z NULL 56
4 2024-05-04 00:00:00Z 8 NULL

קידוד

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

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

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

סוג קידוד
BOOL ערך של בייט אחד, 1 = true, ‏ 0 = false
BYTES ללא קידוד
‫INT64 (או INT, ‏ SMALLINT, ‏ INTEGER, ‏ BIGINT, ‏ TINYINT, ‏ BYTEINT) ‫64 ביט big-endian
FLOAT64 ‫IEEE 754‏ 64 ביט, לא כולל NaN ו-‎+/-inf
מחרוזת UTF-8
TIME/TIMESTAMP מספר שלם ב-64 ביט שמייצג את מספר המיקרו-שניות מאז ראשית זמן יוניקס (Unix epoch) (עקבי עם GoogleSQL)
מידע נוסף זמין במאמר קידוד בהפניית API של Data API.

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