פונקציות בהגדרת המשתמש (UDF)
פונקציות בהגדרת המשתמש (UDF) ב-BigQuery מאפשרות להכיל לוגיקה עסקית מותאמת אישית באמצעות ביטויי SQL או קוד JavaScript. הגדרת פונקציות זמניות או קבועות משלכם מאפשרת לכם להרחיב את היכולות של BigQuery ולהשתמש שוב בחישובים מורכבים בכמה שאילתות.
אפשר להגדיר שפונקציות UDF יהיו מתמידות או זמניות. אפשר להשתמש שוב בפונקציות UDF מתמידות בכמה שאילתות, ופונקציות UDF זמניות מסתיימות כשהשאילתה מסתיימת. ההצהרה DROP FUNCTION נתמכת בפונקציות UDF זמניות רק בשאילתות עם כמה הצהרות ובפרוצדורות.
במאמר פונקציות בהגדרת המשתמש ב-SQL מדור קודם מוסבר על פונקציות בהגדרת המשתמש ב-SQL מדור קודם.
פונקציות SQL מוגדרות על ידי המשתמש (UDF)
בדוגמה הבאה נוצרת פונקציית SQL UDF זמנית בשם AddFourAndDivide, והיא נקראת מתוך הצהרת SELECT:
CREATE TEMP FUNCTION AddFourAndDivide(x INT64, y INT64) RETURNS FLOAT64 AS ( (x + 4) / y ); SELECT val, AddFourAndDivide(val, 2) FROM UNNEST([2,3,5,8]) AS val;
הפלט של הדוגמה הזו:
+-----+-----+
| val | f0_ |
+-----+-----+
| 2 | 3.0 |
| 3 | 3.5 |
| 5 | 4.5 |
| 8 | 6.0 |
+-----+-----+
בדוגמה הבאה נוצרת אותה פונקציה כפונקציה מתמידה:
CREATE FUNCTION mydataset.AddFourAndDivide(x INT64, y INT64) RETURNS FLOAT64 AS ( (x + 4) / y );
מכיוון שה-UDF הזו היא מתמידה, צריך לציין קבוצת נתונים לפונקציה (mydataset בדוגמה הזו). אחרי שמריצים את ההצהרה CREATE FUNCTION, אפשר לקרוא לפונקציה משאילתה:
SELECT val, mydataset.AddFourAndDivide(val, 2) FROM UNNEST([2,3,5,8,12]) AS val;
פרמטרים של תבניות SQL UDF
פרמטר עם סוג ששווה ל-ANY TYPE יכול להתאים ליותר מסוג ארגומנט אחד כשקוראים לפונקציה.
- אם ליותר מפרמטר אחד יש את הסוג
ANY TYPE, BigQuery לא אוכף קשר בין הסוגים של הארגומנטים האלה. - סוג ההחזרה של הפונקציה לא יכול להיות
ANY TYPE. צריך להשמיט אותו, כלומר הוא ייקבע באופן אוטומטי על סמךsql_expression, או שהוא צריך להיות סוג מפורש. - אם תעבירו לפונקציה ארגומנטים מסוגים שלא תואמים להגדרה של הפונקציה, תתקבל שגיאה בזמן הקריאה.
בדוגמה הבאה מוצגת פונקציית SQL UDF שמשתמשת בפרמטר עם תבנית.
CREATE TEMP FUNCTION addFourAndDivideAny(x ANY TYPE, y ANY TYPE) AS ( (x + 4) / y ); SELECT addFourAndDivideAny(3, 4) AS integer_input, addFourAndDivideAny(1.59, 3.14) AS floating_point_input;
הפלט של הדוגמה הזו:
+----------------+-----------------------+
| integer_input | floating_point_input |
+----------------+-----------------------+
| 1.75 | 1.7802547770700636 |
+----------------+-----------------------+
בדוגמה הבאה נעשה שימוש בפרמטר עם תבנית כדי להחזיר את הרכיב האחרון של מערך מכל סוג:
CREATE TEMP FUNCTION lastArrayElement(arr ANY TYPE) AS ( arr[ORDINAL(ARRAY_LENGTH(arr))] ); SELECT lastArrayElement(x) AS last_element FROM ( SELECT [2,3,5,8,13] AS x );
הפלט של הדוגמה הזו:
+--------------+
| last_element |
+--------------+
| 13 |
+--------------+
שאילתות משנה סקלריות
פונקציית SQL UDF יכולה להחזיר את הערך של שאילתת משנה סקלרית. שאילתת משנה סקלרית חייבת לבחור עמודה אחת.
בדוגמה הבאה מוצגת פונקציית SQL UDF שמשתמשת בשאילתת משנה סקלרית כדי לספור את מספר המשתמשים בגיל מסוים בטבלת משתמשים:
CREATE TEMP TABLE users AS ( SELECT 1 AS id, 10 AS age UNION ALL SELECT 2 AS id, 30 AS age UNION ALL SELECT 3 AS id, 10 AS age ); CREATE TEMP FUNCTION countUserByAge(userAge INT64) AS ( (SELECT COUNT(1) FROM users WHERE age = userAge) ); SELECT countUserByAge(10) AS count_user_age_10, countUserByAge(20) AS count_user_age_20, countUserByAge(30) AS count_user_age_30;
הפלט של הדוגמה הזו:
+-------------------+-------------------+-------------------+
| count_user_age_10 | count_user_age_20 | count_user_age_30 |
+-------------------+-------------------+-------------------+
| 2 | 0 | 1 |
+-------------------+-------------------+-------------------+
פרויקט ברירת המחדל בביטויי SQL
בגוף של פונקציית SQL UDF, כל ההפניות לישויות של BigQuery, כמו טבלאות או תצוגות, חייבות לכלול את מזהה הפרויקט, אלא אם הישות נמצאת באותו פרויקט שמכיל את פונקציית ה-UDF.
לדוגמה, נניח שאתם רוצים להשתמש בהצהרה הבאה:
CREATE FUNCTION project1.mydataset.myfunction() AS ( (SELECT COUNT(*) FROM mydataset.mytable) );
אם מריצים את ההצהרה הזו מ-project1 ו-mydataset.mytable קיים ב-project1, ההצהרה תצליח. אבל אם תריצו את ההצהרה הזו מפרויקט אחר, היא תיכשל. כדי לתקן את השגיאה, צריך לכלול את מזהה הפרויקט בהפניה לטבלה:
CREATE FUNCTION project1.mydataset.myfunction() AS ( (SELECT COUNT(*) FROM project1.mydataset.mytable) );
אפשר גם להפנות לישות בפרויקט או במערך נתונים אחרים, ולא רק לזה שבו יוצרים את הפונקציה:
CREATE FUNCTION project1.mydataset.myfunction() AS ( (SELECT COUNT(*) FROM project2.another_dataset.another_table) );
שימוש במשתני מערכת עם פונקציות SQL UDF
משתני המערכת @@session_id ו-@@location נתמכים בפונקציות SQL UDF. אתם יכולים לכלול את משתני המערכת האלה בכל מקום בהצהרה ליצירת הפונקציה, כדי להחזיר את מזהה הסשן או את המיקום של השאילתה הנוכחית.
אין תמיכה במשתני מערכת אחרים.
פונקציות JavaScript מוגדרות על ידי המשתמש (UDF)
פונקציית JavaScript בהגדרת המשתמש מאפשרת להפעיל קוד שנכתב ב-JavaScript מתוך שאילתת SQL. פונקציות UDF ב-JavaScript בדרך כלל צורכות יותר משאבי יחידות קיבולת בהשוואה לשאילתות SQL סטנדרטי, מה שמפחית את ביצועי המשימות. אם אפשר לבטא את הפונקציה ב-SQL, בדרך כלל עדיף להריץ את הקוד כמשימת שאילתה ב-SQL סטנדרטי.
בדוגמה הבאה מוצגת פונקציית UDF ב-JavaScript. קוד ה-JavaScript מופיע במירכאות בתוך מחרוזת גולמית.
CREATE TEMP FUNCTION multiplyInputs(x FLOAT64, y FLOAT64) RETURNS FLOAT64 LANGUAGE js AS r""" return x*y; """; WITH numbers AS (SELECT 1 AS x, 5 as y UNION ALL SELECT 2 AS x, 10 as y UNION ALL SELECT 3 as x, 15 as y) SELECT x, y, multiplyInputs(x, y) AS product FROM numbers;
הפלט של הדוגמה הזו:
+-----+-----+--------------+
| x | y | product |
+-----+-----+--------------+
| 1 | 5 | 5 |
| 2 | 10 | 20 |
| 3 | 15 | 45 |
+-----+-----+--------------+
בדוגמה הבאה, הפונקציה מסכמת את הערכים של כל השדות שנקראים foo במחרוזת ה-JSON הנתונה.
CREATE TEMP FUNCTION SumFieldsNamedFoo(json_row STRING) RETURNS FLOAT64 LANGUAGE js AS r""" function SumFoo(obj) { var sum = 0; for (var field in obj) { if (obj.hasOwnProperty(field) && obj[field] != null) { if (typeof obj[field] == "object") { sum += SumFoo(obj[field]); } else if (field == "foo") { sum += obj[field]; } } } return sum; } var row = JSON.parse(json_row); return SumFoo(row); """; WITH Input AS ( SELECT STRUCT(1 AS foo, 2 AS bar, STRUCT('foo' AS x, 3.14 AS foo) AS baz) AS s, 10 AS foo UNION ALL SELECT NULL, 4 AS foo UNION ALL SELECT STRUCT(NULL, 2 AS bar, STRUCT('fizz' AS x, 1.59 AS foo) AS baz) AS s, NULL AS foo ) SELECT TO_JSON_STRING(t) AS json_row, SumFieldsNamedFoo(TO_JSON_STRING(t)) AS foo_sum FROM Input AS t;
הפלט שמתקבל מהדוגמה:
+---------------------------------------------------------------------+---------+
| json_row | foo_sum |
+---------------------------------------------------------------------+---------+
| {"s":{"foo":1,"bar":2,"baz":{"x":"foo","foo":3.14}},"foo":10} | 14.14 |
| {"s":null,"foo":4} | 4 |
| {"s":{"foo":null,"bar":2,"baz":{"x":"fizz","foo":1.59}},"foo":null} | 1.59 |
+---------------------------------------------------------------------+---------+
סוגי נתונים נתמכים של פונקציות JavaScript בהגדרת משתמש
לחלק מסוגי ה-SQL יש מיפוי ישיר לסוגי JavaScript, אבל לאחרים אין. ב-BigQuery, הסוגים מיוצגים באופן הבא:
| סוג הנתונים ב-BigQuery | סוג הנתונים ב-JavaScript |
|---|---|
| ARRAY | ARRAY |
| BOOL | בוליאני |
| BYTES | מחרוזת בקידוד Base64 |
| FLOAT64 | מספר |
| NUMERIC, BIGNUMERIC | אם אפשר לייצג ערך NUMERIC או BIGNUMERIC בדיוק כערך נקודה צפה (floating-point) של IEEE 754 ואין לו חלק של שבר, הערך מקודד כ-Number. הערכים האלה הם בטווח [-253, 253]. אחרת, הערך מקודד כמחרוזת. |
| מחרוזת | מחרוזת |
| STRUCT | OBJECT שבו כל שדה STRUCT הוא שדה בעל שם |
| TIMESTAMP | DATE עם שדה מיקרו-שנייה שמכיל את החלק microsecond של חותמת הזמן |
| תאריך | תאריך |
| JSON |
אובייקטים, מערכים וערכים ב-JSON מומרים לאובייקטים, מערכים וערכים מקבילים ב-JavaScript. JavaScript לא תומך בערכי INT64. רק מספרי JSON בטווח [-253, 253] מומרים באופן מדויק. אחרת, הערך המספרי מעוגל, מה שעלול לגרום לאובדן הדיוק. |
מכיוון ש-JavaScript לא תומך בסוג של מספר שלם של 64 ביט, INT64 לא נתמך כסוג קלט לפונקציות UDF של JavaScript. במקום זאת, השתמשו ב-FLOAT64 כדי לייצג ערכים של מספרים שלמים כמספר, או ב-STRING כדי לייצג ערכים של מספרים שלמים כמחרוזת.
BigQuery תומך ב-INT64 כסוג החזרה בפונקציות UDF של JavaScript. במקרה כזה, גוף הפונקציה של JavaScript יכול להחזיר מספר או מחרוזת של JavaScript. לאחר מכן, BigQuery ממיר את אחד מהסוגים האלה ל-INT64.
אם ערך ההחזרה של פונקציית ה-UDF ב-JavaScript הוא
Promise, המערכת של BigQuery ממתינה ל-Promise עד ש-Promise מוסדר. אם ה-Promise עובר למצב fulfilled, BigQuery מחזיר את התוצאה שלו. אם ה-Promise נדחה, BigQuery מחזיר שגיאה.
כללי ציטוטים
צריך להקיף את קוד ה-JavaScript במירכאות. לקטעי קוד של שורה אחת, אפשר להשתמש במחרוזת רגילה במירכאות:
CREATE TEMP FUNCTION plusOne(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS "return x+1;"; SELECT val, plusOne(val) AS result FROM UNNEST([1, 2, 3, 4, 5]) AS val;
הפלט של הדוגמה הזו:
+-----------+-----------+
| val | result |
+-----------+-----------+
| 1 | 2.0 |
| 2 | 3.0 |
| 3 | 4.0 |
| 4 | 5.0 |
| 5 | 6.0 |
+-----------+-----------+
אם קטע הקוד מכיל מירכאות או מורכב מכמה שורות, משתמשים בבלוקים עם מירכאות משולשות:
CREATE TEMP FUNCTION customGreeting(a STRING) RETURNS STRING LANGUAGE js AS r""" var d = new Date(); if (d.getHours() < 12) { return 'Good Morning, ' + a + '!'; } else { return 'Good Evening, ' + a + '!'; } """; SELECT customGreeting(names) AS everyone FROM UNNEST(['Hannah', 'Max', 'Jakob']) AS names;
הפלט של הדוגמה הזו:
+-----------------------+ | everyone | +-----------------------+ | Good Morning, Hannah! | | Good Morning, Max! | | Good Morning, Jakob! | +-----------------------+
הוספת ספריות JavaScript
אפשר להרחיב את פונקציות ה-UDF ב-JavaScript באמצעות הקטע OPTIONS.
בקטע הזה אפשר לציין ספריות קוד חיצוניות ל-UDF.
CREATE TEMP FUNCTION myFunc(a FLOAT64, b STRING) RETURNS STRING LANGUAGE js OPTIONS ( library=['gs://my-bucket/path/to/lib1.js', 'gs://my-bucket/path/to/lib2.js']) AS r""" // Assumes 'doInterestingStuff' is defined in one of the library files. return doInterestingStuff(a, b); """; SELECT myFunc(3.14, 'foo');
בדוגמה שלמעלה, הקוד ב-lib1.js וב-lib2.js זמין לכל קוד בקטע [external_code] של ה-UDF.
שיטות מומלצות לפונקציות UDF ב-JavaScript
סינון מראש של הקלט
אם אפשר לסנן את הקלט לפני שהוא מועבר לפונקציית UDF ב-JavaScript, יכול להיות שהשאילתה תהיה מהירה וזולה יותר.
הימנעות ממצב קבוע שניתן לשינוי
אל תאחסנו מצב שניתן לשינוי בקריאות JavaScript UDF ואל תיגשו אליו. לדוגמה, הימנעו מהתבנית הבאה:
-- Avoid this pattern CREATE FUNCTION temp.mutable() RETURNS INT64 LANGUAGE js AS r""" var i = 0; // Mutable state function dontDoThis() { return ++i; } return dontDoThis() """;
שימוש יעיל בזיכרון
לסביבת העיבוד של JavaScript יש זיכרון מוגבל לכל שאילתה. שאילתות UDF ב-JavaScript שצוברות יותר מדי מצב מקומי עלולות להיכשל בגלל מחסור בזיכרון.
אישור תרחישים
אפשר להקצות הרשאות לפונקציות UDF כשיגרה. שגרות מורשות מאפשרות לכם לשתף תוצאות של שאילתות עם משתמשים או קבוצות ספציפיים, בלי לתת גישה ישירה לטבלאות הבסיסיות. לדוגמה, שגרה יכולה לחשב צבירות או לחפש ערך בטבלה ולהשתמש בערך הזה בחישוב. מידע נוסף זמין במאמר Authorized routines.
הוספת תיאורים לפונקציות מוגדרות על ידי המשתמש (UDF)
כדי להוסיף תיאור לפונקציה מוגדרת-משתמש:
המסוף
נכנסים לדף BigQuery במסוף Google Cloud .
בחלונית הימנית, לוחצים על Explorer:

אם החלונית הימנית לא מוצגת, לוחצים על הרחבת החלונית הימנית כדי לפתוח אותה.
בחלונית Explorer, מרחיבים את הפרויקט ולוחצים על Datasets.
לוחצים על מערך הנתונים. אפשר גם להשתמש בתכונת החיפוש או במסננים כדי למצוא את מערך הנתונים.
לוחצים על הכרטיסייה פונקציות ובוחרים את הפונקציה.
בחלונית הפרטים, לוחצים על Edit Routine Details כדי לערוך את טקסט התיאור.
בתיבת הדו-שיח, מזינים תיאור בתיבה או עורכים את התיאור הקיים. לוחצים על שמירה כדי לשמור את טקסט התיאור החדש.
SQL
כדי לעדכן את התיאור של פונקציה, יוצרים אותה מחדש באמצעות הצהרת ה-DDL CREATE FUNCTION ומגדירים את השדה description ברשימה OPTIONS:
נכנסים לדף BigQuery במסוף Google Cloud .
בעורך השאילתות, מזינים את ההצהרה הבאה:
CREATE OR REPLACE FUNCTION mydataset.my_function(...) AS ( ... ) OPTIONS ( description = 'DESCRIPTION' );
לוחצים על Run.
מידע נוסף על הרצת שאילתות זמין במאמר הרצת שאילתה אינטראקטיבית.
יצירת תרחישים מותאמים אישית להסתרת רעשים
אתם יכולים ליצור פונקציות UDF לשימוש עם פונקציות מיסוך בהתאמה אישית. כדאי ליצור מערכי נתונים ייעודיים ולהגדיר הרשאות IAM מתאימות לניהול פונקציות UDF להסתרת מידע. שגרות מיסוך בהתאמה אישית צריכות לעמוד בדרישות הבאות:
- שגרת המיסוך בהתאמה אישית חייבת להיות SQL UDF.
- בפונקציה
OPTIONS, צריך להגדיר את האפשרותdata_governance_typeלערךDATA_MASKING. - אפשר להשתמש בפונקציות הבאות בשגרות של הסתרת מידע בהתאמה אישית:
AEAD.DECRYPT_BYTESפונקציית הצפנה של AEAD עםKEYS.KEYSET_CHAIN(אין תמיכה בשימוש במפתח גולמי)AEAD.DECRYPT_STRINGפונקציית הצפנה של AEAD עםKEYS.KEYSET_CHAIN(אין תמיכה בשימוש במפתח גולמי)- פונקציית הצפנה מסוג
AEAD.ENCRYPTAEAD עם keyset_chain (אין תמיכה בשימוש במפתח גולמי) - פונקציית ההמרה
CAST - פונקציית המחרוזת
CONCAT CURRENT_DATETIMEפונקציית datetime- פונקציית התאריך
CURRENT_DATE CURRENT_TIMESTAMPפונקציית חותמת הזמן- פונקציית הזמן
CURRENT_TIME DETERMINISTIC_DECRYPT_BYTESפונקציית הצפנה של AEAD עםKEYS.KEYSET_CHAIN(אין תמיכה בשימוש במפתח גולמי)DETERMINISTIC_DECRYPT_STRINGפונקציית הצפנה של AEAD עםKEYS.KEYSET_CHAIN(אין תמיכה בשימוש במפתח גולמי)DETERMINISTIC_ENCRYPTפונקציית הצפנה של AEAD עםKEYS.KEYSET_CHAIN(אין תמיכה בשימוש במפתח גולמי)FARM_FINGERPRINTפונקציית גיבוב (hash)- פונקציית המחרוזת
FROM_BASE32 - פונקציית המחרוזת
FROM_BASE64 - פונקציית המחרוזת
FROM_HEX GENERATE_UUIDפונקציה בסיסית- פונקציית ההצפנה
KEYS.KEYSET_CHAINAEAD - פונקציית המחרוזת
LENGTH - פונקציית המחרוזת
LOWER - פונקציית המחרוזת
LPAD - פונקציית המחרוזת
LTRIM MD5פונקציית גיבוב (hash)- פונקציית המחרוזת
REGEXP_REPLACE - פונקציית המחרוזת
REGEXP_EXTRACT - פונקציית המחרוזת
REPLACE - פונקציית המחרוזת
RPAD - פונקציית המחרוזת
RTRIM - פונקציית ההמרה
SAFE_CAST SHA1פונקציית גיבוב (hash)SHA256פונקציית גיבוב (hash)SHA512פונקציית גיבוב (hash)- פונקציית המחרוזת
STARTS_WITH - פונקציית המחרוזת
SUBSTRING - פונקציית המחרוזת
SUBSTR - פונקציית המחרוזת
TO_BASE32 - פונקציית המחרוזת
TO_BASE64 - פונקציית המחרוזת
TO_HEX - פונקציית המחרוזת
TRIM - פונקציית המחרוזת
UPPER
- שגרות מיסוך בהתאמה אישית יכולות לקבל קלט אחד או לא לקבל קלט בכלל בתוך סוגי הנתונים של BigQuery, חוץ מ-
GEOGRAPHYו-STRUCT. אי אפשר להשתמש ב-GEOGRAPHYוב-STRUCTבשגרות של הסתרת מידע בהתאמה אישית. - אין תמיכה בפרמטרים של תבניות SQL UDF.
- כשמזינים קלט, סוגי הנתונים של הקלט והפלט חייבים להיות זהים.
- צריך לציין סוג פלט.
- אי אפשר להפנות לפונקציות UDF, לשאילתות משנה, לטבלאות או לתצוגות אחרות בגוף ההגדרה.
- אחרי שיוצרים שגרת מיסוך, אי אפשר לשנות אותה לפונקציה רגילה. כלומר, אם האפשרות
data_governance_typeמוגדרת ל-DATA_MASKING, אי אפשר לשנות אתdata_governance_typeבאמצעות הצהרות DDL או קריאות ל-API. - שגרות מיסוך בהתאמה אישית תומכות בהצהרות CASE ו-CASE expr. אפשר להשתמש באופרטורים הבאים עם הצהרות
CASEו-CASE expr:Comparison Operators–<,<=,>,>=,=,!=,INLogical Operators–AND,OR,NOTIS Operator
לדוגמה, שגרת הסתרה שמחליפה את מספר תעודת הזהות של המשתמש ב-XXX-XX-XXXX עשויה להיראות כך:
CREATE OR REPLACE FUNCTION SSN_Mask(ssn STRING) RETURNS STRING
OPTIONS (data_governance_type="DATA_MASKING") AS (
SAFE.REGEXP_REPLACE(ssn, '[0-9]', 'X') # 123-45-6789 -> XXX-XX-XXXX
);בדוגמה הבאה מתבצע גיבוב (hash) עם salt שסופק על ידי המשתמש, באמצעות הפונקציה SHA256:
CREATE OR REPLACE FUNCTION `project.dataset.masking_routine1`( ssn STRING) RETURNS STRING OPTIONS (data_governance_type = 'DATA_MASKING') AS ( CAST(SHA256(CONCAT(ssn, 'salt')) AS STRING format 'HEX') );
בדוגמה הבאה, עמודה מסוג DATETIME מוסתרת באמצעות ערך קבוע:
CREATE OR REPLACE FUNCTION `project.dataset.masking_routine2`( column DATETIME) RETURNS DATETIME OPTIONS (data_governance_type = 'DATA_MASKING') AS ( SAFE_CAST('2023-09-07' AS DATETIME) );
כשיטה מומלצת, כדאי להשתמש בקידומת SAFE בכל מקום שאפשר כדי להימנע מחשיפת נתונים גולמיים באמצעות הודעות שגיאה.
אחרי שיוצרים את שגרת המיסוך בהתאמה אישית, היא זמינה ככלל מיסוך ביצירת מדיניות נתונים.
פונקציות שהקהילה תרמה
פונקציות UDF שנוספו על ידי הקהילה זמינות במערך הנתונים הציבורי bigquery-public-data.persistent_udfs ובמאגר הקוד הפתוח bigquery-utils ב-GitHub.
כדי לראות את כל הפונקציות המוגדרות על ידי המשתמש (UDF) של הקהילה במסוף Google Cloud , מסמנים בכוכב את הפרויקט bigquery-public-data בחלונית Explorer ואז מרחיבים את קבוצת הנתונים המקוננת persistent_udfs בתוך הפרויקט.
מתן גישה לפונקציות שנוספו על ידי הקהילה בהיקף של VPC Service Controls
בפרויקטים שבהם מופעל VPC Service Controls ו-BigQuery הוא שירות מוגן, צריך להגדיר כלל לתעבורת נתונים יוצאת (egress) לפרויקט bigquery-public-data (מזהה הפרויקט: 1057666841514).
הכלל הזה צריך לאפשר את הפעולות הבאות:
bigquery.routines.get(לשימוש בתרחישים)bigquery.tables.getData(לשליחת שאילתות לטבלאות ב-BigQuery)
הקוד הבא מציג דוגמה להגדרת YAML:
- egressFrom:
identityType: ANY_IDENTITY
egressTo:
operations:
- serviceName: 'bigquery.googleapis.com'
methodSelectors:
- permission: 'bigquery.routines.get'
- permission: 'bigquery.tables.getData'
resources:
- projects/1057666841514 # bigquery-public-data
אם אתם רוצים לתרום לפונקציות ה-UDF במאגר הזה, קראו את ההוראות במאמר תרומה לפונקציות UDF.
גישה מאוחדת לפונקציות בכמה אזורים
כדי להשתמש בפונקציות UDF בשאילתות בכמה אזורים, פונקציית ה-UDF צריכה להיות זמינה בכל אזור שבו מופעלת שאילתה שמכילה את פונקציית ה-UDF. לכן, צריך ליצור ולתחזק פונקציות UDF בכל אזור שבו אתם עשויים להשתמש בפונקציית ה-UDF בשאילתה. גם אם הטבלאות זהות, צריך לשמור שתי גרסאות של הפונקציה. לדוגמה, אם אתם מאחסנים את נתוני המכירות גם במספר האזורים EU וגם במספר האזורים US, אתם צריכים לשמור גרסה של הפונקציה בכל אזור. לדוגמה:
שאילתה במספר אזורים ב-EU:
SELECT id, europe_dataset.my_function(value) FROM sales;
שאילתה במספר אזורים ב-US:
SELECT id, us_dataset.my_function(value) FROM sales;
בנוסף, אם ההגדרה של הפונקציה משתנה, צריך לעדכן אותה בכל האזורים.
כדי שהפונקציות המוגדרות על ידי המשתמש לא יהיו תלויות באזור, אתם יכולים להשתמש בשכפול של מערכי נתונים באזורים שונים:
- יוצרים קבוצת נתונים ייעודית חדשה, לדוגמה
my_utils, כדי לאחסן את כל ה-UDF הנדרשים. חשוב לזכור שכל הטבלאות שנוספות למערך הנתונים הזה ישוכפלו, מה שיגדיל את העלות. עם זאת, שכפול של פונקציות UDF ופרוצדורות לא כרוך בעלות נוספת. - מוסיפים את כל ה-UDF שלכם לקבוצת הנתונים החדשה. זה יכול לכלול גם פונקציות UDF של הקהילה, כמו
bqutilשהועתקו מ-GitHub. - הפעלת שכפול של מערך נתונים. מגדירים את מערך הנתונים הזה כך שישוכפל לכל האזורים שבהם צריך להריץ שאילתות שקוראות לפונקציות ה-UDF האלה. הפעולה הזו תעתיק את הפונקציות לאזורים האלה ותסנכרן אותן.
כשמריצים שאילתה, BigQuery משתמש באופן אוטומטי בגרסה המקומית של ה-UDF מהרפליקה המקומית של מערך הנתונים, בלי לציין את האזור שבו הפונקציה מוגדרת. כך אפשר להעביר את השאילתות בין מיקומים שונים. לדוגמה:
SELECT id, my_utils.my_function(value) FROM sales;
מגבלות
המגבלות הבאות חלות על פונקציות זמניות ופונקציות מתמידות בהגדרת המשתמש:
- אין תמיכה באובייקטים של DOM
Window,Documentו-Node, ובפונקציות שדורשות אותם. - פונקציות JavaScript פועלות בסביבת ארגז חול, ופונקציות שמסתמכות על קוד מערכת בסיסי עלולות להיכשל בגלל קריאות מערכת מוגבלות.
- יכול להיות שפונקציית UDF ב-JavaScript תגרום לזמן קצוב לתפוגה ותמנע את השלמת השאילתה. זמן קצוב לתפוגה יכול להיות קצר כמו 5 דקות, אבל הוא יכול להשתנות בהתאם לכמה גורמים, כולל כמה זמן מעבד (CPU) של המשתמש הפונקציה צורכת, וכמה גדולים הקלט והפלט של פונקציית ה-JavaScript.
- פעולות Bitwise ב-JavaScript מטפלות רק ב-32 הביטים המשמעותיים ביותר.
- פונקציות UDF כפופות למגבלות מסוימות של הגבלת קצב של יצירת בקשות ומכסות. מידע נוסף זמין במאמר מגבלות של פונקציות UDF.
המגבלות הבאות חלות על פונקציות מתמידות בהגדרת המשתמש:
- כל קבוצת נתונים יכולה להכיל רק פונקציה מתמידה אחת עם אותו שם. עם זאת, אפשר ליצור פונקציה מוגדרת-משתמש עם שם זהה לשם של טבלה באותה קבוצת נתונים.
- כשמפנים לפונקציה מתמידה מוגדרת-משתמש מפונקציה מתמידה מוגדרת-משתמש אחרת או מתצוגה לוגית, צריך להוסיף לשם את קבוצת הנתונים. לדוגמה:
CREATE FUNCTION mydataset.referringFunction() AS (mydataset.referencedFunction()); - אפשר להפעיל פונקציות מתמידות בבטחה כשמשתפים אותן בין בעלים. פונקציות UDF לא יכולות לשנות נתונים, לתקשר עם מערכות חיצוניות או לשלוח יומנים ל-Google Cloud Observability או לאפליקציות דומות.
המגבלות הבאות חלות על פונקציות זמניות בהגדרת המשתמש.
- כשיוצרים פונקציית UDF זמנית,
function_nameלא יכול להכיל נקודות. - תצוגות ופונקציות UDF מתמידות לא יכולות להפנות לפונקציות UDF זמניות.