הוספת נתונים מיותרים היא טכניקה שמשמשת להגנה על פרטיות המשתמשים כשמבצעים שאילתה במסד נתונים. הוא פועל על ידי הוספת רעש אקראי לסעיף SELECT של צבירה בשאילתה. הנתונים המיותרים האלה מגנים על פרטיות המשתמשים ומספקים תוצאות מדויקות למדי, כך שלא צריך לבצע בדיקות של ההבדלים וסף הצבירה הנדרש לפלט נמוך יותר. אפשר להריץ את רוב השאילתות הקיימות במצב רעש, עם כמה מגבלות.
מהם היתרונות של הוספת רעש
לא מתבצעות בדיקות של הבדלים: כשמריצים שאילתות עם הוספת רעשי רקע, מערכת Ads Data Hub לא מסננת שורות בגלל דמיון לקבוצות תוצאות קודמות. כלומר, עדיין תוכלו לקבל תמונה כוללת של הנתונים תוך שמירה על פרטיות המשתמשים.
פתרון בעיות פשוט יותר: השורות מושמטות רק בגלל דרישות צבירה, ולכן קל יותר לפתור בעיות ולהתאים שאילתות.
אין תחביר חדש שצריך ללמוד: לא צריך ללמוד תחביר חדש של שאילתות או להכיר מושגים שקשורים לפרטיות כדי להשתמש ברעש במקום בבדיקות של הבדלים.
דיוק התוצאות מדווח: אם העבודה בוצעה בהצלחה, מוצג האחוז הכולל של הנתונים שיכול להיות שהושפעו מרעשי רקע.
איך רעשים משפיעים על דרישות הפרטיות
בדיקות הבדלים: הוספת רעשי רקע לא מסתמכת על בדיקות הבדלים קיימות ב-Ads Data Hub. כשמשתמשים בהחדרת רעש, בדיקות ההבדלים מושבתות.
דרישת צבירה: נתוני החשיפות שמופקים מהוספת רעשי רקע מייצגים כ-20 משתמשים ייחודיים או יותר, ונתוני הקליקים או ההמרות מייצגים כ-10 משתמשים ייחודיים או יותר.
בדיקות סטטיות: אין השפעה.
תקציבים ומגבלות על שאילתות: שאילתות שמופעלות באמצעות שיתוף רעשים משתמשות בתקציב של גישה לנתונים שמשמש לבדיקות של הבדלים. בדומה לבדיקות של הבדלים, אם מריצים את אותה שאילתה על אותו מערך נתונים הרבה פעמים, יכול להיות שתאבדו את הגישה לתאריכים במערך הנתונים שמתבצעות לגביהם שאילתות לעיתים קרובות. זה יכול לקרות אם מריצים שאילתות של חלון נע, או אם שולחים את אותה בקשה כמה פעמים.
במצב רעש, מוטלות מגבלות נוספות ומחמירות יותר על חישוב מחדש של אותן תוצאות מצטברות בתוך שאילתות או בין שאילתות. בדומה לתקציב הגישה לנתונים, יכול להיות שתאבדו גישה לתאריכים שמופיעים לעיתים קרובות בשאילתות במערך הנתונים. אבל מגבלות שנובעות מחישוב מחדש של אותן תוצאות מצטברות יגבילו רק שאילתות במצב רעש, ולא שאילתות במצב בדיקת ההבדלים. מידע נוסף זמין במאמר בנושא תוצאות חוזרות.
הסבר על ההשפעה של הוספת רעשים על התוצאות
מערכת Ads Data Hub מוסיפה רעשי רקע כדי לצמצם את הסיכון לחשיפת מידע – הסיכון שמישהו יוכל ללמוד מידע על משתמש ספציפי. הוא מאזן בין פרטיות לבין שימושיות.
הוספת רעשי רקע ב-Ads Data Hub משנה את תוצאות השאילתה באופן הבא:
- הוא מצמצם את התרומה של משתמשים חריגים בתוצאות המצטברות. הוא מסכם את התרומה של כל משתמש בכל צבירה, ואז מגביל כל תרומה באמצעות גבולות הידוק מינימליים ומקסימליים.
- הוא מסכם את התרומות של כל משתמש אחרי ההגבלה.
- היא מוסיפה רעש לכל תוצאה מצטברת – התוצאה של כל קריאה לפונקציית צבירה בכל שורה. הקנה מידה של הרעש האקראי הזה הוא יחסי לגבולות המהודקים.
- היא מחשבת ספירת משתמשים עם רעש לכל שורה ומסירה שורות עם מעט מדי משתמשים. זה דומה ל-k-anonymity במצב בדיקת הבדלים, אבל בגלל הרעש, עבודות שמופעלות על אותו מערך נתונים יכולות להשמיט שורות שונות. בנוסף, במצב רעש מושמטות פחות שורות כי דרישת הצבירה נמוכה יותר (בערך 20 לעומת בדיוק 50).
התוצאה הסופית היא מערך נתונים שבו כל שורה מכילה תוצאות מצטברות עם רעשי רקע, וקבוצות קטנות נמחקו. ההסתרה הזו מסתירה את ההשפעה של משתמש ספציפי על התוצאות שמוחזרות.
מידע על צמצום צבירה
הזרקת רעשים ב-Ads Data Hub משתמשת בהצמדה מרומזת או מפורשת של נתונים מצטברים כדי להגביל את ההשפעה של חריגים. אתם יכולים לבחור את סוג ההגבלה שבו אתם רוצים להשתמש, בהתאם לתרחיש השימוש.
הגבלה מרומזת
לא צריך להשתמש בתחביר SQL מיוחד כדי להשתמש בהגבלת ערכים משתמעת, היא מופעלת כברירת מחדל. הגבולות המרומזים נגזרים מהנתונים עצמם ונקבעים לכל צבירה. אם לחלק מהצבירות יש טווח ערכים רחב יותר מאשר לאחרות,
הגבולות המשתמעים יכולים להסיק גבולות שונים לצבירות שונות לפי הצורך. בדרך כלל זה מוביל לפחות שגיאות. הערה: COUNT(DISTINCT
user_id) משתמש באופן אוטומטי בהגבלת ערכים מפורשת עם הגבול העליון של 1.
הגבלה מפורשת
הגבלת תרומה מפורשת מגבילה את התרומה הכוללת של כל משתמש לטווח שצוין. הגבולות המפורשים מוחלים באופן אחיד על כל הצבירות, והם חייבים להיות ערכים מילוליים. הגבלת ערכים מפורשת עשויה להניב תוצאות טובות יותר כשגבולות הערכים ידועים בדרך כלל. לדוגמה, הגבלת הגילאים בין 0 ל-100 משקפת מידע ציבורי כי הגיל של רוב האנשים הוא בדרך כלל בטווח הזה.
ב-Ads Data Hub יש ADH.ANONפונקציות מצטברות נוספות לצורך צמצום מפורש. כדי להשתמש בהגבלת ערכים מפורשת, צריך להגדיר את הגבולות לכל פונקציית צבירה נתמכת על ידי הוספת מספרים שלמים שמייצגים את הגבול התחתון והגבול העליון. לדוגמה:
SELECT
campaign_name,
-- Set lower and upper bounds to 0 and 1, respectively
ADH.ANON_COUNT(*, contribution_bounds_per_group => (0,1))
FROM data
GROUP BY 1
הרצת שאילתה באמצעות החדרת רעש
- פותחים דוח.
- לוחצים על המתג הגדרות "רעש" להגנה על הפרטיות כדי להעביר אותו למצב שימוש ברעש.
- מריצים את השאילתה.
- בודקים את ההשפעה של הרעש שנוסף.
- אופציונלי: מתאימים את השאילתה כדי לצמצם את ההשפעה של הרעש.
בדיקת ההשפעה של הרעש
אחרי שהעבודה מסתיימת בהצלחה, במערכת Ads Data Hub מוצגת מהימנות התוצאה בסיכום הפרטיות. המהימנות מבוססת על אחוז התאים בתוצאה שעשויים להיות מושפעים מאוד מרעשי רקע. ערך בטבלת התוצאות נחשב כערך שהושפע אם קנה המידה של הרעש שנוסף גדול מ-5% מהתוצאה בתא.
במערכי נתוני הפלט שהושפעו, בסיכום הפרטיות מפורטות עשר העמודות עם הכי הרבה רעשי רקע, מההשפעה הגבוהה ביותר להשפעה הנמוכה ביותר, והתרומה שלהן לרעשי הרקע. זה פירוט של תוויות ההשפעה של הרעש.
| % מהתוצאות שהושפעו | צבע האינדיקטור | השפעה |
|---|---|---|
| פחות מ-5% | ירוק | השפעה נמוכה |
| 5% עד 15% | צהוב | השפעה בינונית |
| 15% עד 25% | Orange | השפעה חזקה |
| יותר מ-25% | אדום | השפעה גבוהה מאוד |
אפשר גם לראות תצוגה מקדימה של סיכום הפרטיות של משימות דוחות מהזמן האחרון בדף דף הבית. כדי לראות תצוגה מקדימה של הגדרות הפרטיות של משרה מסוימת, מעבירים את העכבר מעל סמל טיפ הפרטיות privacy_tip בכרטיס המשרה בקטע פעילות אחרונה.
התאמת שאילתות
כשמעט משתמשים תורמים לתוצאה, יש סיכוי גבוה יותר שהצבירות יושפעו מרעשי רקע. זה יכול לקרות כשמחשבים צבירות ממערכי משתמשים קטנים, או כשחלק מהמשתמשים לא משפיעים על התוצאות. מצב כזה יכול לקרות, למשל, עם הפונקציה COUNTIF. על סמך דוח הרעשים, יכול להיות שתרצו לשנות את השאילתה כדי להקטין את אחוז התוצאות המושפעות.
אלה הנחיות כלליות:
- מרחיבים את טווח התאריכים.
- לשכתב את השאילתה כדי לצמצם את רמת הפירוט של הנתונים, למשל על ידי קיבוץ לפי פחות פרמטרים או החלפת
COUNTIFב-COUNT. - הסרת עמודות עם רעשי רקע.
- כדאי לנסות הגבלה מפורשת כשניתן לבחור גבולות סבירים.
פונקציות צבירה נתמכות
הפונקציות המצטברות הבאות נתמכות עם רעש:
SUM(...)COUNT(*)COUNT(...)COUNTIF(...)COUNT(DISTINCT user_id)APPROX_COUNT_DISTINCT(user_id)AVG(...)
מילת המפתח DISTINCT נתמכת רק בפונקציה COUNT, ורק כשמשתמשים בה עם הפניה ישירה לעמודה user_id מטבלה ב-Ads Data Hub או מביטוי שמחזיר את הערך user_id או NULL, כמו COUNT(DISTINCT IF(..., user_id, NULL)).
הערה: המגבלות האלה חלות רק על צבירות עם רעש, שהיא הרמה הראשונה של צבירה בין משתמשים. סכומים מצטברים ברמת המשתמש וסכומים מצטברים אחרי הוספת רעש לא מוגבלים.
פונקציות צבירה נוספות
בנוסף לתמיכה בפונקציות צבירה רגילות, מערכת Ads Data Hub מציגה פונקציות צבירה משלימות ADH.ANON שתומכות בהגבלת ערכים מפורשת.
הפונקציות האלה משתמשות באותו תחביר כמו פונקציות הצבירה של BigQuery עם פרטיות דיפרנציאלית, אבל לא צריך להשתמש בהן בסעיף WITH DIFFERENTIAL_PRIVACY:
ADH.ANON_SUM( ..., [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )ADH.ANON_COUNT( *, [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )ADH.ANON_COUNT( ..., [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )ADH.ANON_AVG( ..., [ contribution_bounds_per_group => (lower_bound, upper_bound) ] )ADH.ANON_PERCENTILE_CONT( ..., percentile, contribution_bounds_per_row => (lower_bound, upper_bound) )
הפרמטרים ADH.ANON_SUM, ADH.ANON_COUNT ו-ADH.ANON_AVG:
-
contribution_bounds_per_group: מספר התוכן שנוסף על ידי כל משתמש מוגבל לכל מחיצה שמוגדרת על ידי מפתחותGROUP BY. הגבולות העליון והתחתון מוחלים על ערכים לכל קבוצה אחרי שהערכים מצטברים לכל משתמש. -
lower_bound: ערך נומרי מילולי שמייצג את הערך הקטן ביותר שייכלל בצבירה. -
upper_bound: ערך נומרי קבוע שמייצג את הערך הגדול ביותר שייכלל בצבירה.
פרמטרים של ADH.ANON_PERCENTILE_CONT:
-
percentile: האחוזון לחישוב, ערך מילולי בטווח[0, 1]. -
contribution_bounds_per_row: התרומות לכל משתמש מוגבלות לפי שורה (לפי רשומה). שימו לב שנדרשים גבולות הידוק מפורשים לאחוזון, ולכן הפונקציה הזו נתמכת רק כפונקציה משלימה. -
lower_bound: ערך נומרי מילולי שמייצג את הערך הקטן ביותר שייכלל בצבירה. -
upper_bound: ערך נומרי קבוע שמייצג את הערך הגדול ביותר שייכלל בצבירה.
חישוב הערכים MIN ו-MAX
הפונקציות MIN ו-MAX לא נתמכות ישירות בצבירות של רעשי רקע,
אבל לרוב יש שיטות חלופיות לחישוב התוצאות האלה.
אם יש לכם MIN או MAX של ערכים שאפשר להשתמש בהם כמפתחות קיבוץ, כמו תאריך האירוע, אתם יכולים קודם להשתמש ב-GROUP BY לפי הערך הזה, ואז לחשב את MIN/MAX. הפונקציה מחזירה את הערך המינימלי או המקסימלי שעובר את סף הצבירה.
דוגמה:
WITH campaign_date_ranges AS (
SELECT campaign_id, MIN(event_date) AS min_date, MAX(event_date) AS max_date
FROM (
# Aggregation thresholding will be applied here
SELECT DISTINCT
campaign_id,
DATE(query_id.time_usec, @time_zone) AS event_date
FROM adh.google_ads_impressions
)
)
SELECT campaign_id, num_impressions, min_date, max_date
FROM (
# Noise and aggregation thresholding will be applied here
SELECT campaign_id, COUNT(*) AS num_impressions
FROM adh.google_ads_impressions
)
JOIN campaign_date_ranges USING(campaign_id)
לחלופין, אם יש לכם ערכים גרנולריים עם גבולות ידועים, אפשר להשתמש בפונקציה PERCENTILE_CONT עם גבולות מפורשים כדי לקבל תוצאה משוערת.
דוגמה:
SELECT
campaign_id,
COUNT(*) AS num_impressions,
ADH.ANON_PERCENTILE_CONT(
query_id.time_usec, 0,
contribution_bounds_per_row => (@min_timestamp, @max_timestamp))
AS min_timestamp,
ADH.ANON_PERCENTILE_CONT(
query_id.time_usec, 1,
contribution_bounds_per_row => (@min_timestamp, @max_timestamp))
AS max_timestamp
FROM adh.google_ads_impressions
מידע על תוצאות של מספרים שלמים
מערכת Ads Data Hub תכניס רעשי רקע באופן אוטומטי לפונקציות המצטברות האלה, אבל חתימות הפונקציות לא ישתנו. מכיוון שפונקציות כמו COUNT
או SUM של INT64 מחזירות INT64, כל חלק עשרוני של התוצאה עם הרעש יעוגל. בדרך כלל ההשפעה הזו זניחה ביחס לגודל התוצאה ולרעשי הרקע.
אם אתם צריכים את הדיוק של המספר העשרוני בתוצאה, אל תכתבו פונקציות שמחזירות INT64. לדוגמה, אפשר להשתמש בפונקציה SUM עם קלט שמומר ל-FLOAT64.
מידע על תוצאות שליליות
באופן עקרוני, רעשי רקע עם ערכים קטנים מאוד יכולים להוביל למספרים שליליים, גם אם מבחינה סמנטית זה לא אמור לקרות בשאילתה. כדי לשמור על התנהגות צפויה, כל הצורות של COUNT ו-COUNTIF מוגבלות אוטומטית לאפס, כך שהן אף פעם לא יניבו תוצאות שליליות. אם רוצים להשיג את אותה התנהגות עם פונקציה אחרת, כמו SUM, אפשר להגביל את התוצאות באופן ידני באמצעות GREATEST(0,
SUM(...)).
בדרך כלל השינוי הזה זניח, אבל הוא יוצר הטיה חיובית קלה בתוצאות הכוללות.
קבוצות ציבוריות
בעזרת פסקה GROUP BY, התוצאות האנונימיות של שאילתה מצטברות על פני קבוצות. הספים לצבירת נתונים מיועדים להבטיח שבקבוצה יהיה מספר מספיק של משתמשים, כדי להגן על נתונים של משתמשים ספציפיים. התהליך שבו נקבע אילו קבוצות אפשר לשחרר נקרא "בחירת מחיצה".
במקרים רבים, קבוצות הן ידע ציבורי. לדוגמה, קיבוץ לפי גרסת הדפדפן, היום בשבוע או אזור גיאוגרפי לא תלוי בנתוני משתמשים אם ערכי מפתח הקיבוץ ידועים מראש. במקרה הזה, אפשר להשמיט את בחירת המחיצה, כי הנוכחות או ההיעדר של קבוצה בפלט לא מספקים מידע חדש על המשתמשים.
מערכת Ads Data Hub מזהה שאילתות שמתאימות לקבוצות ציבוריות ולא מחילה עליהן סף צבירה. המשמעות היא שאף שורת פלט לא מסוננת. חשוב לזכור שהתוצאות שמחושבות על סמך מספר קטן של משתמשים יכולות להיות מושפעות מאוד מרעשי רקע.
כדי להיות זכאים לקבוצות ציבוריות, השאילתה צריכה להיות מובנית כך שכל מפתחות הקיבוץ יהיו ידועים מראש. העמודות של הקיבוץ צריכות לעמוד בתנאים הבאים:
- הם מגיעים מטבלה ציבורית (סעיף table או
SELECTללא נתוני משתמשים ב-Ads Data Hub). - הפונקציה
SELECT DISTINCTמוחלת עליהם כדי לאכוף ערכים ייחודיים. - הם מצורפים לשאילתה עם
OUTER JOINבכל העמודות הנפרדות.
דוגמאות לשאילתות של קבוצות ציבוריות:
SELECT age_group_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (SELECT DISTINCT age_group_id FROM adh.age_group)
ON demographics.age_group = age_group_id
GROUP BY age_group_id
SELECT age_group_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (SELECT DISTINCT * FROM UNNEST([1, 2, 3]) AS age_group_id)
ON demographics.age_group = age_group_id
GROUP BY age_group_id
בדוגמה הראשונה, הטבלה המוגנת adh.google_ads_impressions table מצורפת לטבלה adh.age_group שלא מכילה נתוני משתמשים בעמודה age_group_id. אותה עמודה בטבלה הציבורית age_group_id מופיעה בסעיף GROUP BY.
באופן דומה, בדוגמה השנייה, הטבלה המוגנת adh.google_ads_impressions מצורפת לטבלה הציבורית, שמסופקת באופן מפורש בתור UNNEST([1, 2, 3]). שימו לב שבשתי הדוגמאות, מפתח הקיבוץ age_group_id מגיע מהטבלה הציבורית.
אפשר גם לספק כמה פריטים לקיבוץ, למשל:
SELECT campaign_id, COUNT(*) FROM adh.google_ads_impressions
RIGHT OUTER JOIN (SELECT DISTINCT campaign_id, customer_id FROM adh.google_ads_campaign)
USING (campaign_id, customer_id)
GROUP BY campaign_id, customer_id
SELECT p.campaign_id, p.browser, COUNT(*) FROM adh.google_ads_impressions AS i
RIGHT OUTER JOIN (
SELECT DISTINCT * FROM UNNEST([1, 2]) AS campaign_id
CROSS JOIN UNNEST(['Chrome', 'Other']) AS browser
) AS p
ON i.campaign_id = p.campaign_id AND i.browser = p.browser
GROUP BY campaign_id, browser;
העובדה שאין סינון בשאילתות של קבוצות ציבוריות יכולה להיות שימושית אם מריצים שאילתות באופן חוזר, כי הפלט תמיד מוחזר עבור אותם ערכים קבועים של מפתחות הקיבוץ. האפשרות הזו יכולה להיות שימושית במיוחד, למשל, כשרוצים ליצור לוחות בקרה תקופתיים.
הערה: אם טבלה ציבורית מספקת מספר גדול מאוד של ערכי מפתח לקיבוץ, יכול להיות שתקבלו הרבה שורות עם מעט נתונים או ללא נתונים בכלל, וכל השורות האלה ידווחו כבעלות השפעה גבוהה של רעשי רקע. במקרה כזה, כדאי לשקול לספק במפורש רשימה קטנה יותר של מפתחות עם הערכים שמעניינים אתכם.
דפוסי שאילתות נתמכים
חשוב: רוב השיטות המומלצות הרגילות של Ads Data Hub עדיין רלוונטיות לשאילתות שמשתמשות בהוספת רעש. בפרט, מומלץ לעיין בהנחיות בנושא שליחת שאילתות חוזרות לגבי אותם נתונים.
בקטע הזה מתוארים דפוסי שאילתות שנתמכים כשמריצים שאילתות באמצעות הוספת רעש.
נתונים מצטברים ברמת המשתמש
מערכת AdMob תומכת בנתונים מצטברים ברמת המשתמש ללא הגבלות, בדיוק כמו במצב של בדיקת הבדלים. הוספת הרעש מתבצעת רק בצבירות שמשלבות נתונים של כמה משתמשים. צבירות שמקובצות במפורש לפי user_id, או פונקציות אנליטיות שמחולקות לפי user_id, לא מקבלות רעשים ומותרות לשימוש. צבירות ברמת המשתמש שלא מקובצות באופן מפורש לפי user_id – לדוגמה, GROUP BY impression_id – נחשבות לצבירות חוצות משתמשים, ולכן נוסף רעש.
קיבוץ לפי external_cookie לא מספיק. אפשר להשתמש ב-external_cookie כדי לצרף טבלאות *_match לטבלאות שבבעלות הלקוח, אבל כשמבצעים צבירה של נתונים של משתמש יחיד, צריך לקבץ במפורש לפי העמודה user_id, ולא רק לפי העמודה external_cookie.
דוגמה לפונקציית צבירה:
WITH user_paths AS (
# Grouping by user_id, no noise needed, all functions allowed
SELECT user_id, STRING_AGG(campaign_id, ">" ORDER BY query_id.time_usec) AS path
FROM adh.google_ads_impressions
GROUP BY 1
)
# Noise applied here to num_users
SELECT path, COUNT(*) AS num_users
FROM user_paths
GROUP BY 1;
דוגמה לפונקציה אנליטית:
WITH events AS (
# Partitioning by user_id, no noise needed, all functions allowed
SELECT
campaign_id,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY query_id.time_usec) AS index
FROM adh.google_ads_impressions
)
# Noise applied here to first_impressions
SELECT campaign_id, COUNT(*) AS first_impressions
FROM events
WHERE index = 1
GROUP BY 1;
צבירות מקבילות
כל צבירה של נתונים של כמה משתמשים מקבלת רעשי רקע בנפרד. אפשר להריץ כמה צבירות כאלה בהצהרה אחת, ולשלב את התוצאות בטבלה אחת באמצעות JOIN או UNION.
דוגמה:
WITH result_1 AS (
# Noise applied here to num_impressions
SELECT campaign_id, COUNT(*) AS num_impressions
FROM adh.google_ads_impressions
GROUP BY 1
), result_2 AS (
# Noise applied here to num_clicks
SELECT campaign_id, COUNT(*) AS num_clicks
FROM adh.google_ads_creative_conversions
GROUP BY 1
)
SELECT * FROM result_1 JOIN result_2 USING(campaign_id)
שימו לב: הפעולה הזו נתמכת, אבל מומלץ להימנע ממנה במצב של בדיקת הבדלים. השיטה הזו לא גורמת לבעיות שקשורות לרעשי רקע, כי כל צבירה מקבילה עוברת סינון והוספת רעשי רקע באופן נפרד.
נתונים נצברים שמאוחדים עם נתונים לא נצברים
מכיוון שמערכת Ads Data Hub תומכת רק בחלונות ניתוח שמחולקים למחיצות לפי user_id, פתרון נפוץ הוא לצבור את התוצאות האלה בנפרד ולבצע self-join לפני צבירה נוספת. השאילתות האלה נתמכות במצב רעש, ולרוב הביצועים שלהן טובים יותר מאשר במצב בדיקת הבדלים, כי דרישות הפרטיות נפתרות מוקדם יותר.
דוגמה:
WITH campaign_totals AS (
# Noise applied here to campaign_imps
SELECT campaign_id, COUNT(*) AS campaign_imps
FROM adh.google_ads_impressions
GROUP BY 1
)
# Noise applied here to imps
SELECT campaign_id, demographics, campaign_imps, COUNT(*) AS imps
FROM adh.google_ads_impressions JOIN campaign_totals USING(campaign_id)
GROUP BY 1,2,3
מצב הרעש מונע צבירה מחדש של תוצאות מצטברות, כמו AVG(campaign_imps).
דפוסי שאילתות לא נתמכים
בקטע הזה מתוארים דפוסי שאילתות שלא נתמכים כשמריצים שאילתות באמצעות הוספת רעש.
שאילתות שכוללות את היום
בשאילתות במצב רעש אין תמיכה בשאילתות על נתונים מהיום הנוכחי. (לא מומלץ לעשות את זה במצב בדיקת ההבדלים). אי אפשר לבחור את התאריך הנוכחי בשאילתות שמשתמשות בהוספת רעשי רקע.
תוצאות חוזרות
במצב רעש, מערכת Ads Data Hub מגבילה את מספר הפעמים שאפשר לחזור על אותה צבירה. אם תגיעו למגבלות האלה, השאילתות במצב רעש לא יוכלו לגשת לתאריכים במערך הנתונים שמתבצעות לגביהם שאילתות בתדירות גבוהה. בהמשך מפורטות כמה דוגמאות לאופן שבו זה יכול לקרות.
חזרה על שאילתה מתרחשת כשמריצים את אותה שאילתה כמה פעמים עם אותם פרמטרים או עם פרמטרים דומים מאוד, כמו טווחי תאריכים חופפים. כדי להימנע מכך, אפשר להשתמש בנתונים שכבר יוצאו לפרויקט BigQuery.
שימו לב: אם שתי משימות מבצעות שאילתות על טווחי תאריכים חופפים, יכול להיות שיווצרו חזרות אם הן מבצעות את אותו חישוב על אותם משתמשים. לדוגמה, השאילתה הבאה, שמופעלת על טווחי תאריכים חופפים, יוצרת חזרות כי היא מחלקת לפי תאריך:
SELECT DATE(TIMESTAMP_MICROS(event.event_time)) AS date,
COUNT(*) AS cnt
FROM adh.cm_dt_clicks
GROUP BY 1
במקרה כזה, כדאי להריץ את השאילתה על פלחי תאריכים לא חופפים.
דוגמה נוספת לחזרה על עצמה מתרחשת כשנתונים לא תלויים בתאריך מסוים. השאילתה הבאה יוצרת חזרות כשהיא מופעלת על תאריכים חופפים, כששתי המשימות מכסות את כל משך החיים של הקמפיין:
SELECT campaign_id, COUNT(*) AS cnt
FROM adh.google_ads_impressions
GROUP BY 1
במקרה כזה, כדאי להריץ את השאילתה רק פעם אחת כי התוצאה לא משתנה.
חזרה על צבירה מתרחשת כשאותה צבירה חוזרת על עצמה כמה פעמים בשאילתה:
SELECT COUNT(*) AS cnt1, COUNT(*) AS cnt2
FROM table
במקרה כזה, צריך להסיר את אחת החזרות.
שימו לב שאפילו אם הצבירות שונות מבחינה תחבירית אבל מחשבות את אותו ערך, הן ייחשבו כחזרה. במילים אחרות, אם הערכים של condition1 ו-condition2 זהים לכל המשתמשים עם ערך מסוים של key, השאילתה הבאה תחזור על עצמה:
SELECT key, COUNTIF(condition1) AS cnt1, COUNTIF(condition2) AS cnt2
FROM table
GROUP BY key
אם יש לכם תנאים דומים מאוד לכמה קבוצות של משתמשים, כדאי לשקול לכתוב מחדש את השאילתה כך שתכלול רק COUNT אחד.
שכפול שורות מתרחש כשמצטרפים לטבלת Ads Data Hub טבלה ב-BigQuery באופן שבו כל שורה מטבלת Ads Data Hub תואמת לכמה שורות בטבלת BigQuery. לדוגמה, השאילתה הבאה יוצרת חזרה אם יש כמה שורות עם אותו מזהה קמפיין ב-bq_table:
SELECT r.campaign_id, COUNT(*) AS cnt
FROM adh_table
INNER JOIN bq_table ON l.campaign_id = r.campaign_id
במקרה כזה, צריך לשנות את מבנה השאילתה כך שלכל ערך של מפתח הצירוף (campaign_id במקרה הזה) יהיה רק שורה אחת ב-bq_table.
שימו לב: ביטול הקינון של מערך מטבלה ב-Ads Data Hub יכול להניב את אותו אפקט אם לרוב המשתמשים יש את אותם מערכים של ערכים:
SELECT in_market_id, COUNT(*)
FROM adh.dv360_youtube_impressions,
UNNEST(in_market) AS in_market_id
GROUP BY 1
מידע נוסף על שיטות מומלצות אחרות לשאילתות
מידע על חלונות מבט לאחור
חלק מדפוסי השאילתות יוצרים דוחות על פני פרק זמן ארוך, ויוצרים אותם מחדש באופן תקופתי כדי לכלול תוצאות חדשות. יכול להיות שיהיה צורך לבצע שינויים בשאילתות האלה כדי שהן יפעלו במצב רעש, כי אם הן יחשבו מחדש תוצאות קודמות, הן ייחסמו. במקום זאת, כל עבודה צריכה ליצור רק תוצאות חדשות, ואז אפשר לשלב את התוצאות החדשות עם תוצאות מעבודות קודמות כדי לקבל דוח מלא.
לדוגמה, אם יוצרים דוח של מדדים לפי תאריך, שמתעדכן מדי יום:
SELECT
campaign_id,
DATE(TIMESTAMP_MICROS(query_id.time_usec), @time_zone) AS event_date,
COUNT(*) AS impressions
FROM adh.google_ads_impressions
GROUP BY 1,2
לא מומלץ להריץ את הפקודה הזו עם טווח תאריכים גדול, כי היא תחשב מחדש את התוצאות של הימים הקודמים. במקום זאת, צריך להריץ כל משימה רק ביום האחרון, שבו יש נתונים חדשים, ואז לשלב את התוצאות עם התוצאות של משימות קודמות.
אם אתם צריכים לרענן תוצאה קודמת (לדוגמה, כדי להתחשב בנתונים שהגיעו באיחור), מומלץ להימנע מחישוב מחדש של תוצאה מסוימת יותר מפעם אחת או פעמיים. אחרת, יכול להיות שתקבלו שגיאות בגלל ניסיונות חוזרים של שאילתות.
צבירה ישירה מחדש
ההפרעה מוחלת על השכבה הראשונה של צבירת נתונים בין משתמשים בשאילתה. שאילתות עם כמה שכבות של צבירה ישלבו תוצאות עם רעשי רקע, ולכן יכול להיות שרעשי הרקע בצבירות הסופיות יהיו גבוהים בהרבה. השאילתות האלה מקבלות אזהרה באימות:
WITH layer_1 AS (
# Noise applied here to partial_result
SELECT campaign_id, demographics, location, COUNT(*) AS partial_result
FROM adh.google_ads_impressions
GROUP BY 1,2,3
HAVING partial_result > 5
)
# Reaggregation of partial_result with no user-level data, will be rejected
SELECT campaign_id, SUM(partial_result) AS final_result
FROM layer_1
GROUP BY 1
כדי לקבל את התוצאות הטובות ביותר מהרעש, צריך לחשב את כל הפעולות של משתמשים שונים במסגרת צבירה אחת. לדוגמה, אפשר לצלם SUM של אירועים במקום SUM של ספירות ביניים.
אם אי אפשר להימנע מצבירה רב-שכבתית, אפשר לפתור את האזהרה על ידי ייצוא התוצאות ישירות מהשכבה הראשונה. כדי לעשות את זה במסגרת עבודה אחת בלי לשנות את תוצאות הסקריפט, יוצרים טבלה זמנית (או טבלה שמיוצאת לפרויקט BigQuery) באמצעות התחביר OPTIONS(privacy_checked_export=true). לדוגמה:
CREATE TEMP TABLE layer_1 OPTIONS(privacy_checked_export=true) AS (
# Noise applied here to partial_result
SELECT campaign_id, demographics, location, COUNT(*) AS partial_result
FROM adh.google_ads_impressions
GROUP BY 1,2,3
HAVING partial_result > 5
);
# Reaggregation of privacy checked data, no noise needed
SELECT campaign_id, SUM(partial_result) AS final_result
FROM layer_1
GROUP BY 1
אם רמת הצבירה הראשונה מפורטת מדי לצורכי בדיקות פרטיות, כדאי לשקול לכתוב מחדש את השאילתה עם צבירות ברמת המשתמש. אם זה לא אפשרי, השאילתה הזו לא נתמכת במצב רעש.
מזהי משתמשים שלא צורפו
בשאילתות במצב רעש, אסור לשלב נתונים ממשתמשים שונים בשורה אחת, אלא אם מבצעים צבירה עם רעש. לכן, כשמבצעים הצטרפות של נתונים לא מצטברים מ-Ads Data Hub, צריך לציין במפורש את העמודה user_id.
השאילתה הזו לא מצטרפת באופן מפורש לעמודה user_id, ולכן מוצגת אזהרת אימות:
SELECT …
FROM adh.google_ads_impressions
JOIN adh.google_ads_creative_conversions USING(impression_id)
יכול להיות שצירופים כאלה לא יפעלו כמו שציפיתם, כי רק שורות עם אותו ערך user_id יתאימו. כדי לפתור את הבעיה, צריך לשנות את סעיף USING כך שיכלול במפורש את user_id – לדוגמה, USING(impression_id, user_id).
שימו לב שההגבלה הזו חלה רק על שאילתות איחוד (join) בין טבלאות ב-Ads Data Hub (למעט טבלאות מאפיינים). היא לא חלה על טבלאות בבעלות הלקוח. לדוגמה, מותר לפרסם:
SELECT …
FROM adh.google_ads_impressions
JOIN bigquery_project.dataset.table USING(any_column)
צירופים חיצוניים ימניים ב-Ads Data Hub-BigQuery
צירופים חיצוניים עם נתונים בבעלות הלקוח עלולים להוביל לשורות שחסרים בהן מזהי משתמשים, ולכן לא ניתן להשתמש בהם כדי להפחית את הרעש.
שתי השאילתות האלה מפיקות אזהרות אימות כי הן מאפשרות שורות לא תואמות עם מזהי משתמשים חסרים בצד של Ads Data Hub:
SELECT …
FROM adh.google_ads_impressions
RIGHT JOIN bigquery_project.dataset.table USING(column)
SELECT …
FROM bigquery_project.dataset.table
LEFT JOIN adh.google_ads_impressions USING(column)
שימו לב: אם סדר הטבלאות היה הפוך, כל אחת מההצטרפויות הייתה עובדת. יש גם חריג לגבי טבלאות של נתוני RDID שמצורפות ישירות ל-device_id_md5. לדוגמה, השאילתה הבאה תפעל ללא אזהרות:
SELECT …
FROM bigquery_project.dataset.table
LEFT JOIN adh.google_ads_impressions_rdid USING(device_id_md5)
סיכום השורות שסוננו
מפרט סיכום השורות המסוננות לא נתמך במצב רעש. ברוב המקרים, אין צורך בתכונה הזו כשמשתמשים ברעש, כי שיעורי הסינון נמוכים יותר ואין סינון מבדיקות ההבדלים.
אם אתם רואים סינון משמעותי של נתונים בתוצאה של רעשי רקע, כדאי להגדיל את כמות הנתונים המצטברים. אפשר לבצע צבירה מקבילה על קבוצת הנתונים המלאה כדי להשוות אומדן של הסכום הכולל. לדוגמה:
SELECT campaign_name, COUNT(*)
FROM data
GROUP BY 1
UNION ALL
SELECT 'Total', COUNT(*)
FROM data
GROUP BY 1
שימו לב שהספירה הכוללת עוברת רעש באופן עצמאי, ולכן יכול להיות שהערכים הכוללים לא יסתכמו, אבל בדרך כלל הספירה הכוללת מדויקת יותר מסיכום של שורות עם רעש.
טבלאות שנוצרו במצב מעורב
אפשר להשתמש בטבלאות שלא יוצאו ב-Ads Data Hub רק באותו מצב פרטיות שבו הן נוצרו. אי אפשר ליצור טבלה במצב צבירה רגיל ולהשתמש בה במצב רעש, או להיפך (אלא אם הטבלה הזו מיוצאת קודם ל-BigQuery).