ההכנסות עלו ב־18% אחרי המעבר למערכת המעקב החדשה.

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

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

זאת ייחודיות.

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

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

שורות כפולות הן לא תמיד ישויות כפולות

אנשים מדברים על כפילויות כאילו הבעיה מובנת מאליה. לעיתים קרובות היא לא.

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

לכן SELECT DISTINCT * הוא בדרך כלל הודאה בכך שרמת הפירוט מעולם לא הובנה כמו שצריך.

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

אירועים כפולים לעומת לקוחות כפולים לעומת עסקאות כפולות

הכשלים האלה מתנהגים אחרת.

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

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

הנזק מוכפל, כי אותן עובדות כפולות מזינות לעיתים כמה דשבורדים במקביל.

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

לפני שסופרים, מגדירים מה שורה אחת אמורה לייצג.

זה נשמע בסיסי. בפועל, זה לא מספיק בסיסי בהרגלי העבודה שלנו.

שאלו:

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

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

איך אנליסטים בדרך כלל מפספסים את זה

הם סומכים על מזהה מוכר בלי לשאול איך הוא נוצר.

ייתכן ש־event_id אינו ייחודי בכל המערכת. order_id עשוי לחזור בניסיונות חוזרים. email אולי לא מייצג לקוח אחד. עוגייה יכולה לפצל אדם אחד בין כמה מכשירים. איש קשר ב־CRM יכול לאחד כמה אנשים אמיתיים תחת רשומה אחת של חברה.

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

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

איך מזהים את המפתח הייחודי האמיתי

המפתח הנכון תלוי ביחידת המשמעות, ולא בעמודה שבמקרה קיימת.

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

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

בדיקת כפילויות מעשית

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

SELECT
  user_id,
  event_name,
  event_timestamp,
  COUNT(*) AS duplicate_count
FROM analytics.events
WHERE event_name = 'purchase'
  AND event_date >= CURRENT_DATE - INTERVAL '7 day'
GROUP BY 1, 2, 3
HAVING COUNT(*) > 1
ORDER BY duplicate_count DESC, event_timestamp DESC;

ואז העמידו את התוצאה למבחן:

  • האם החזרות הן ניסיונות חוזרים לגיטימיים או שליחות כפולות ברורות?
  • האם הכפילויות מתרכזות סביב שחרור גרסה?
  • האם הן מוגבלות לפלטפורמה מסוימת או למשתמשים במצב מחובר?
  • האם רענון עמוד, ניסיון חוזר של webhook או הרצה חוזרת של תהליך ETL מסבירים את הדפוס?

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

מה בעיות ייחודיות שוברות מבחינה עסקית

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

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

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