מודלינג נתונים
מהמנוע שמתחת למכסה ועד מודל כוכב עובד: VertiPaq, קשרים, Star Schema וקרדינליות — על דאטה אמיתי של AdventureWorks.
איך עובד השיעור
שלוש דקות קריאה שיחסכו חיפושים: איך מנווטים, איפה השאלות, ומה נשמר. אחר כך תוכן השיעור, מפת החלקים וההכנה לתרגול.
ניווט בין נושאים
הכפתורים הקודם והבא קבועים בראש המסך. אפשר גם בחצי המקלדת, בהחלקת אצבע בטלפון, או לקפוץ מרשימת הנושאים.
שאלות ותרגול
הכפתור למבחן שבראש המסך מוביל תמיד לעמוד השאלות הראשון: בוחן עצמי, תרגיל בית ובוחן אמריקאי.
ההתקדמות נשמרת
הנושא שבו עצרתם והנושאים שקראתם נשמרים בדפדפן שלכם בלבד. אפשר לסגור ולחזור, ולאפס מתוך רשימת הנושאים.
ארבעת שיעורי הקורס
המסלול המלא. אפשר לעבור לכל שיעור בלחיצה.
מפת השיעור — עשרה פרקים
מהמנוע שמתחת למכסה, דרך הסיבה שבגללה צריך קשרים, ועד מודל כוכב עובד על דאטה אמיתי.
| פרק | מה נלמד |
|---|---|
| I · המנוע | VertiPaq: אחסון עמודתי, דחיסה, ולמה מודל טוב חשוב לו |
| II · למה קשרים | מה קורה בלי קשר, קשר כצינור פילטר, ומפתחות PK ו-FK |
| III · עובדות ומימדים | Fact מול Dimension, שבע הטבלאות שלנו, ומימד מנוון |
| IV · Star מול Snowflake | שני המבנים, השוואה ראש בראש, ולמה Star מנצח |
| V · מנגנון הקשרים | קרדינליות, כיווניות סינון, קשר פעיל מול לא-פעיל |
| VI · קשר דו-כיווני | הסיפור המלא: מסלייסר אחד ועד רשימת הלקוחות, שלב אחרי שלב |
| VII · מדריך מהיר | מחיקת קשרים בארבעה שלבים, עם צילומי מסך |
| VIII · סיכום | שמונה נקודות ובוחן של 40 שאלות על קשרים |
| IX · תרגול | 12 משימות מעשיות על AdventureWorks |
| X · מה הלאה | משאבים והמשך הדרך |
הכנה לתרגול
התרגיל המעשי מגיע בסוף השיעור (נושא 29). כדאי להוריד את הדאטה ולפתוח את Power BI Desktop כבר עכשיו.
AdventureWorks_Sales.xlsx — שבעה גיליונות
Sales עם 121,253 שורות ושש טבלאות מלוות. סה"כ מכירות בקובץ: $109,809,274.20. כל מספר בשיעור אומת מול הקובץ הזה.
מה זה VertiPaq
מנוע אחסון טבלאי In-Memory מבוסס-עמודות — הליבה שעליה בנוי מודל הנתונים של Power BI.
In-Memory
המנוע פועל כולו בזיכרון ה-RAM ולא ניגש לדיסק בזמן החישוב.
מבוסס עמודות
שומר את הנתונים לפי עמודות, בניגוד ל-SQL ששומר לפי שורות — וכך מתאפשרת דחיסה ושליפה יעילות.
טכנולוגיית הליבה
אחראי על האחסון, הדחיסה ושליפת המידע — וזה אותו מנוע שמריץ גם Analysis Services.
מה VertiPaq עושה בפועל
ארבעה תפקידים, כולם על נתונים דחוסים בתוך הזיכרון.
דחיסת נתונים
מזהה ערכים חוזרים ובונה מילונים פנימיים. יחסי דחיסה של 1:10 הם שגרתיים.
אחסון עמודתי
מדד על Sales Amount נוגע בעמודה אחת בלבד — 14 העמודות האחרות כלל לא נקראות.
עיבוד DAX
מחשב בזמן אמת על הנתונים הדחוסים ומחזיר תוצאה לוויזואל.
ניהול קשרי גומלין
מתרגם סינון מטבלת מימד אל טבלת העובדות — וזה בדיוק הנושא של השיעור.
למה בכלל צריך מנוע כזה
נפחי נתונים
מיליוני שורות על מחשב נייד רגיל, בלי לרוקן את הזיכרון.
חוויה אינטראקטיבית
לחיצה על פילטר מחזירה תוצאה מיד, בלי המתנה.
חישובים מהירים
סריקה יעילה בזמן חישוב מדדים — קריטי במודלים מורכבים.
הנקודה שתלווה את כל השיעור: המנוע מהיר, אבל רק אם המודל בנוי נכון. מודל שטוח או מסועף מבטל את היתרון.
מה קורה רגע אחרי הטעינה
- טענו שבע טבלאות. כל אחת נכנסה כ"אי" נפרד.
- Power BI לא יודע ש-Sales[ProductKey] קשור ל-Product[ProductKey].
- בשלב הזה אפשר לחתוך בתוך כל טבלה — אבל לא בין טבלאות.
- המשימה במודלינג: לבנות את הגשרים שמחברים את האיים.
Power BI כן יוצר חלק מהקשרים אוטומטית בטעינה — והם לא תמיד מדויקים. לכן עוברים עליהם ידנית, אחד-אחד.
המבחן: מה קורה כשאין קשר
ויזואל אחד שמוכיח את כל הנקודה: Sales Amount לפי Category, בלי קשר בין Product ל-Sales.
| Category | בלי קשר — שבור | עם קשר — תקין |
|---|---|---|
| Bikes | $109,809,274.20 | $94,620,526.21 |
| Components | $109,809,274.20 | $11,799,076.66 |
| Clothing | $109,809,274.20 | $2,117,613.45 |
| Accessories | $109,809,274.20 | $1,272,057.89 |
הפילטר מ-Category לא מוצא דרך אל Sales, ולכן SUM(Sales[Sales Amount]) רץ על כל הטבלה בכל שורה. ברגע שנבנה את הקשר — כל קטגוריה מקבלת את הסכום שלה.
עוד דוגמה: מכירות לפי שנה
| Fiscal Year | בלי קשר | עם קשר |
|---|---|---|
| FY2018 | $109,809,274.20 | $23,860,891.17 |
| FY2019 | $109,809,274.20 | $34,070,108.50 |
| FY2020 | $109,809,274.20 | $51,878,274.54 |
בלי הקשר הגרף יוצא שטוח לחלוטין — כאילו מכרנו אותו דבר בכל שנה. עם הקשר Date[DateKey] → Sales[OrderDateKey] מתגלה צמיחה של פי 2.2 בשלוש שנים. זה סיפור שלם שנעלם בלי קשר אחד.
מוחקים את הקשרים — והכוכב מתפרק
- מוחקים את כל הקשרים ב-Model view — והכוכב חוזר להיות שבעה איים.
- אין צינור שדרכו פילטר עובר ממימד אל Sales: כל סינון פשוט מתעלם.
- כל ויזואל בדוח מציג את אותו מספר — $109,809,274.20 — לא משנה מה בוחרים.
- הסיבה: המדד רץ על כל הטבלה; בלי קשר אין מי שיצמצם את ה-Filter Context.
בלי קשרים אין מודל — רק טבלאות שלא מדברות. הקשר הוא מה שהופך נתונים לדוח.
קשר = צינור שדרכו זורם הפילטר
- קשר מחבר עמודה בטבלה אחת לעמודה מקבילה בטבלה אחרת.
- הוא לא מעתיק נתונים — הוא פותח צינור שדרכו זורמים פילטרים.
- כשבוחרים Category = Bikes, הסינון זורם דרך הצינור ומצמצם את Sales.
- כיוון הזרימה הטבעי: מהמימד (המתאר) אל ה-Fact (האירועים).
- לכל קשר שלושה מאפיינים: קרדינליות, כיווניות, ופעיל או לא-פעיל.
המפתחות שמחזיקים את הקשר
| Primary Key — צד ה-1 | Foreign Key — צד ה-* | |
|---|---|---|
| איפה יושב | בטבלת המימד | בטבלת ה-Fact |
| ייחודיות | ערך אחד = שורה אחת בדיוק | חוזר על עצמו — מוצר נמכר אלפי פעמים |
| בדאטה שלנו | Product[ProductKey] — 397 ערכים על 397 שורות | Sales[ProductKey] — 121,253 שורות |
| מגבלות | אסור NULL ואסור כפילויות | כל ערך חייב להתאים ל-PK קיים במימד |
בדיקה מהירה ב-Power Query: Column profile על עמודת המפתח. אם Distinct = מספר השורות ואין ריקים — זה PK תקין.
Fact מול Dimension — איך מזהים
| Fact — עובדות | Dimension — מימדים | |
|---|---|---|
| מה רושמת | אירועים: מכירה, הזמנה, החזרה | ישויות: מוצר, לקוח, תאריך, אזור |
| גודל | המון שורות, גדלה כל יום | מעט שורות, יציבה |
| תוכן | מספרים לסיכום: כמות, סכום, עלות | טקסט וקטגוריות לחיתוך וסינון |
| מפתחות | מפתחות זרים לכל מימד | מפתח ראשי ייחודי |
| שאלת הזיהוי | "כמה? בכמה?" | "מי? מה? מתי? איפה?" |
כלל אצבע: מספרים שסוכמים ← Fact. תיאורים שמסננים ← Dimension.
שבע הטבלאות של AdventureWorks
| טבלה | שורות | סוג | תפקיד |
|---|---|---|---|
| Sales | 121,253 | Fact | כל שורה = פריט שנמכר |
| Sales Order | 121,253 | מימד מנוון | Channel ומספרי הזמנה |
| Customer | 18,485 | Dim | לקוחות קצה |
| Reseller | 702 | Dim | משווקים |
| Product | 397 | Dim | כולל Category ו-Subcategory כעמודות |
| Date | 1,461 | Dim | 1.7.2017 עד 30.6.2021 |
| Sales Territory | 11 | Dim | אזורי מכירה |
טבלת Fact אחת רושמת מה קרה; שש הטבלאות האחרות מתארות את מי שמעורב.
איך מסווגים בדאטה שלנו
| Sales — ה-Fact | ששת המימדים | |
|---|---|---|
| גרעין | SalesOrderLineKey ייחודי לכל שורה | מפתח ראשי אחד לכל ישות |
| עמודות מפתח | שבעה מפתחות זרים — היא תמיד צד ה-* | PK ייחודי — תמיד צד ה-1 |
| מדדים | Sales Amount · Order Quantity · Total Product Cost | אין מדדים, רק תיאורים |
| גודל | 121,253 שורות וגדלה | 11 עד 18,485 שורות, יציבות |
ל-Sales יש 15 עמודות, מהן שבע מפתחות. זו החתימה הקלאסית של טבלת עובדות במודל כוכב.
Sales Order — המקרה המיוחד: מימד מנוון
121,253 שורות — בדיוק כמו Sales. קשר 1:1, בלי מדדים.
למה לא Fact
אין בה שום מדד לסיכום — רק Channel, מספר הזמנה (31,455 שונים) ומספר שורה בהזמנה.
למה לא מימד רגיל
מימד רגיל הוא 1:N עם מעט שורות. כאן הקשר 1:1 ואותו גרעין בדיוק כמו ה-Fact.
אז מה זה
מימד מנוון (Degenerate Dimension): תכונות ההזמנה שהוצאו לטבלה צדדית. השימוש העיקרי: פילוח לפי Channel.
הפילוח שהוא מאפשר: Reseller $80,450,596.98 מול Internet $29,358,677.22 — 73% מהכסף מגיע מהערוץ הסיטונאי.
קשר 1:1 מול 1:N
| 1:N — Product מול Sales | 1:1 — Sales Order מול Sales | |
|---|---|---|
| המשמעות | מוצר אחד חוזר באלפי מכירות | כל שורה מתאימה לשורה אחת בדיוק |
| המספרים | 397 ← 121,253 | 121,253 ↔ 121,253 |
| מתי מופיע | ברירת המחדל בין מימד ל-Fact | כששתי הטבלאות מתארות את אותו אירוע |
שני הסוגים תקינים. ב-1:1 ההתאמה מושלמת שורה-לשורה, וזה סימן שהטבלאות מתארות את אותו דבר. ב-1:N צד המימד ייחודי וצד ה-Fact חוזר.
למה לא טבלה אחת ענקית
- כפילות: שם המוצר, הקטגוריה והצבע היו חוזרים בכל 121,253 השורות.
- תחזוקה: שינוי שם קטגוריה = עדכון בעשרות אלפי שורות.
- ניתוח: אי אפשר לראות מוצרים שלא נמכרו — הם פשוט לא קיימים בטבלה.
בקובץ שלנו 47 מוצרים מתוך 397 מעולם לא נמכרו, ו-66 משווקים מתוך 702 בלי מכירות. בטבלה שטוחה אחת המידע הזה נעלם.
הפתרון: מפצלים לפי אחריות. טבלה אחת רושמת מה קרה, טבלאות אחרות מתארות את מי שמעורב. פחות זיכרון, יותר מהירות, וניתוח מלא.
Star Schema — כוכב עם Fact במרכז
כל מימד מתחבר ישירות ל-Fact — קפיצה אחת מכל פילטר אל הנתונים. זה המבנה ש-Power BI נבנה בשבילו: שטוח, מהיר ב-VertiPaq וקל לסינון.
הכוכב — שרטוט המודל
שרטוט נקי של המודל: טבלת העובדות במרכז, המימדים סביבה, וחצים שמראים לאן זורם הפילטר. הקישו על טבלה כדי להאיר את הקשר שלה, והחליפו בין חד-כיווני לדו-כיווני כדי לראות את ההבדל.
Snowflake — מימדים מפוצלים לשרשרת
- אותו Fact במרכז — אבל המימדים מנורמלים (מפוצלים) לטבלאות.
- במקום Dim Product רחבה אחת: Category ← Subcategory ← Product.
- כל פילטר על Category עובר שרשרת של שלושה קשרים בדרך ל-Fact.
- מגיע מעולם מסדי הנתונים (DWH), שבו נרמול חוסך מקום בדיסק.
- השם: הדיאגרמה מסתעפת כמו גביש שלג.
ראש בראש
| קריטריון | Star Schema | Snowflake |
|---|---|---|
| מבנה המימדים | טבלה רחבה אחת לכל נושא | מפוצל לשרשרת טבלאות |
| מספר קשרים | מעט — קשר ישיר אחד | הרבה — שרשרת קשרים |
| ביצועים ב-Power BI | מהיר — קפיצה אחת | איטי יותר — כמה קפיצות |
| שליפת ערך מהמימד | ישירה — קפיצה אחת | דורשת מעבר בכמה טבלאות |
| חיסכון בזיכרון | VertiPaq דוחס מצוין | הנרמול לא תורם הרבה |
| מקור | עולם ה-BI והאנליטיקה | עולם ה-DWH והנרמול |
אז למה Star מנצח
- ב-DWH מסורתי נרמול חוסך מקום בדיסק — יתרון אמיתי.
- אבל VertiPaq דוחס עמודות בצורה מבריקה, והדחיסה מבטלת את החיסכון.
- מה שנשאר מ-Snowflake הוא רק החסרונות: יותר קשרים, ביצועים איטיים, DAX מסובך.
הכלל המעשי: ב-Power Query מאחדים (Merge) את שרשרת המימדים לטבלת מימד אחת רחבה. בקובץ שלנו זה כבר עשוי — Category ו-Subcategory יושבות כעמודות בתוך Product.
קרדינליות
- קרדינליות = היחס המספרי בין שתי הטבלאות בקשר.
- One-to-Many (1:N) — מימד ייחודי מסנן Fact חוזר. זה המצב הבריא.
- דוגמה: מוצר אחד (1) נמכר באלפי שורות מכירה (N).
- Many-to-Many (N:M) — שתי הטבלאות עם כפילויות. אות אזהרה.
- הסימון על הקו: 1 בצד המימד, * בצד ה-Fact.
אם Power BI מציע N:M — עצרו. ברוב המקרים נכנסה כפילות לטבלת המימד, וזה מה שצריך לתקן.
כיווניות סינון
| Single — ברירת מחדל | Both — דו-כיווני | |
|---|---|---|
| כיוון הזרימה | מצד ה-1 לצד ה-* בלבד | גם מה-Fact חזרה למימד |
| התנהגות | צפוי, מהיר, בטוח | עלול לעוות תוצאות בסינון עקיף |
| ביצועים | קל למנוע | כבד יותר |
| סיכון נוסף | אין | מסלולי סינון כפולים (Ambiguity) |
האנלוגיה: Single = רחוב חד-סטרי, התנועה צפויה. Both = כיכר בלי תמרורים — לפעמים מסתדר, ובעומס מתרסק. ב-99% מהמקרים משאירים Single.
קשר פעיל מול לא-פעיל
- ל-Sales שלוש עמודות תאריך: OrderDateKey, DueDateKey, ShipDateKey.
- כולן רוצות להתחבר ל-Date — אבל מותר רק קשר פעיל אחד בין זוג טבלאות.
- הקשר הפעיל (קו רציף): OrderDateKey — ברירת המחדל לכל החישובים.
- הקשרים הלא-פעילים (קו מקווקו): שוכבים מוכנים ומופעלים נקודתית ב-DAX.
איך מפעילים קשר לא-פעיל? נקודתית, בתוך חישוב מסוים — ורק לאותו חישוב. הקשר הפעיל וכל שאר הדוח לא מושפעים. את התחביר המדויק נלמד בשיעור ה-DAX; בשלב הזה חשוב להבין את המנגנון: הקשר קיים, שוכב מוכן, ומופעל לפי דרישה.
למה קשר לא-פעיל דווקא טוב
מדוע רק אחד פעיל
שני קשרים פעילים בו-זמנית = דו-משמעות. Power BI לא היה יודע לפי איזה תאריך לסנן, אז הוא אוסר זאת.
מה הרווחנו
טבלת תאריכים אחת נקייה משרתת את שלושת התאריכים, במקום לשכפל אותה שלוש פעמים.
שימו לב לריקים
ב-AdventureWorks יש 2,113 שורות ללא תאריך משלוח ($1,281,073.41) — בקשר על ShipDateKey הן ייפלו לשורה ריקה.
הכלל: לסינון יש כיוון
לסינון יש כיוון, כמו זרם במורד הנהר. הפרק הזה מפרק את הרעיון צעד-צעד על שאלה אחת: אילו לקוחות קנו משקפי שמש?
הדוגמה מבוססת על מודל Contoso Retail Star · כל המספרים חושבו מהדאטה
↓ כל חמשת החצים נכנסים אל Sales — ואף חץ לא יוצא ממנה
כל קו במודל = צינור חד-סטרי
הסינון זורם תמיד מהממד אל העובדה, בכיוון החץ. בוחרים שנה ב-Date? החץ מוריד את הסינון אל Sales. בוחרים קטגוריה ב-Product? אותו דבר. לעולם לא נגד הזרם.
וזה מספיק ל-90% מהשאלות
"כמה מכרנו", "מתי", "איפה", "מי מכר" — לכולן מספיקה ברירת המחדל Single. אבל מה קורה כשהתשובה יושבת בממד אחד והמסנן בממד אחר?
נקודת פתיחה — שלוש טבלאות, שני צינורות
שלוש טבלאות, שני צינורות. העמודות הצהובות הן המפתחות — דרכן הסינון זורם.
ממד Product
| ProductKey | ProductName | Subcategory |
|---|---|---|
| 214 | Aviator Classic | Sunglasses |
| 215 | Sport Polarized | Sunglasses |
| 87 | TrekPro Red Sock | Socks |
| 132 | Alpine Jacket | Jackets |
עוד 396 שורות ⋮
עובדה Sales
| OrderID | ProductKey | CustomerKey | Amount |
|---|---|---|---|
| 10442 | 214 | 551 | ₪240 |
| 10871 | 215 | 1203 | ₪310 |
| 10902 | 87 | 551 | ₪35 |
| 11054 | 132 | 890 | ₪520 |
עוד 51,996 שורות ⋮
ממד Customer
| CustomerKey | Name | City |
|---|---|---|
| 551 | Mia Dubois | Paris |
| 890 | Dana Mor | Haifa |
| 1203 | Liam Carter | London |
עוד 1,997 שורות ⋮
בכל שורת מכירה יש ProductKey ("מה נמכר") ו-CustomerKey ("מי קנה"). Power BI מסנן על ידי התאמת מפתחות — ובכיוון החץ בלבד.
ארבעה שלבים: מ-Sunglasses ל-662 לקוחות
אותו סיפור בארבעה שלבים. לחצו על שלב כדי לראות מה קורה למספרים בכל טבלה.
מה קורה בטבלאות עצמן
Product — 13 נשארו
| ProductKey | ProductName | Subcategory |
|---|---|---|
| 214 | Aviator Classic | Sunglasses |
| 215 | Sport Polarized | Sunglasses |
| 216 | Urban Retro | Sunglasses |
| 87 | TrekPro Red Sock | Socks |
| 132 | Alpine Jacket | Jackets |
נשארו 13 שורות ירוקות ⋮
Sales — 813 נשארו
| OrderID | ProductKey | CustomerKey |
|---|---|---|
| 10442 | 214 | 551 |
| 10871 | 215 | 1203 |
| 11433 | 216 | 551 |
| 10902 | 87 | 551 |
| 11510 | 301 | 1203 |
נשארו 813 שורות ירוקות ⋮
Customer — 662 אחרי Both
| CustomerKey | Name |
|---|---|
| 551 | Mia Dubois |
| 890 | Dana Mor |
| 1203 | Liam Carter |
נשארו 662 שורות ירוקות ⋮
למה לא פשוט סלייסר על Customer
"למה לא פשוט לשים גם את Customer בסלייסר?" כי סלייסר הוא מה שאתם יודעים — והרשימה שאתם מחפשים היא בדיוק מה שאתם לא יודעים.
סלייסר = קלט
ב-Product קל: אתם יודעים שאתם רוצים "משקפי שמש" — מקליקים ובוחרים. אבל מה תבחרו בסלייסר של Customer? אתם לא יודעים מי מ-2,000 הלקוחות קנה משקפי שמש — זו בדיוק התשובה שאתם מחפשים.
הרשימה = פלט
המנהל אומר: "תוציא רשימה של כל מי שקנה משקפי שמש, לקמפיין SMS". הרשימה היא התוצאה, לא הבחירה. Both נותן ל-813 שורות המכירה לספר ל-Customer מי מופיע בהן — והרשימה מצטמצמת ל-662 לבד.
והמקרה ההפוך — ה-Both עובר צד
"מה קנתה Mia Dubois?" — עכשיו יודעים לקוחה ומחפשים מוצרים. אותו רעיון, כיוון הפוך.
הכלל: מה שאתם יודעים ← לסלייסר. מה שאתם מחפשים ← לשם הסינון צריך להגיע. ואם בדרך הוא חייב לעלות מהעובדה אל ממד — בשביל זה, ורק בשביל זה, Both.
במטריצה: לפני ואחרי, ומתי כן
אותה מטריצה, אותו סלייסר. ההבדל היחיד: כיוון החץ על הקשר Sales–Customer.
מטריצה: שורות = שם הלקוח · ערכים = ספירת לקוחות · סלייסר = Subcategory: Sunglasses
לפני — Single
| Customer Name | לקוחות |
|---|---|
| Alice Werner | 1 |
| Dana Mor | 1 |
| Liam Carter | 1 |
| Mia Dubois | 1 |
| Noah Fischer | 1 |
סה"כ 2,000 — כל לקוח שקיים בטבלה
אחרי — Both
| Customer Name | לקוחות |
|---|---|
| Amelia Novak | 1 |
| Liam Carter | 1 |
| Mia Dubois | 1 |
| Omar Haddad | 1 |
| Sofia Rinaldi | 1 |
סה"כ 662 — רק מי שמופיע ב-813 שורות המכירה
למה לפעמים זה "עובד" גם בלי Both? אם הערכים במטריצה מגיעים מ-Sales (למשל סכום מכירות), שורות ריקות מוסתרות אוטומטית והכול נראה תקין. אבל ברגע שהמטריצה נשענת על הממד עצמו — רשימת שמות, ספירת לקוחות, שדות מ-Customer בלבד — בלי Both תקבלו את כל 2,000 השורות.
מתי כן ומתי לא
✓ מדליקים Both כאשר…
השאלה היא "אילו / מי מתוך הממד?" והמסנן יושב בממד אחר: אילו לקוחות קנו X, אילו מוצרים קנה לקוח Y, אילו עובדים מכרו בקטגוריה Z. הסימן המסגיר: רשימה שמסרבת להצטמצם — 2,000 במקום 662.
✗ לא מדליקים Both כאשר…
השאלה היא "כמה?" — סכומים, כמויות, מגמות. שם Single מספיק תמיד. ולא מדליקים "ליתר ביטחון" על הכול: כל צינור דו-סטרי נוסף מסבך את המודל ומאט אותו.
המשפט לזכור: הסינון זורם תמיד עם החץ, מהממד אל העובדה. Both לא משנה את הקשר — הוא רק מוסיף לחץ ראש שני, כדי שהעובדה תוכל לסנן ממד בחזרה. פותחים אותו רק לשאלת "אילו / מי", וסוגרים כשמסיימים.
מחיקת קשרים בארבעה שלבים
כדי להדגים בעצמכם מה קורה בלי קשרים — או כדי לנקות מודל שהתמלא בקשרים אוטומטיים שגויים.
האזהרה בדיאלוג — "ויזואלים שמשתמשים בטבלאות האלה עלולים להישבר" — היא בדיוק ההדגמה שאנחנו רוצים.
טיפ: שהקשרים לא יחזרו לבד
לפני שטוענים מחדש את הנתונים:
File → Options and settings → Options
→ Current File → Data Load
→ [ ] Autodetect new relationships after data is loadedכשהאפשרות כבויה, Power BI לא ייצור מחדש קשרים אוטומטית — ההדגמה תישאר נקייה, וכל קשר במודל נוצר במודע.
מה למדנו — שמונה נקודות
VertiPaq
מנוע In-Memory עמודתי. דוחס, שולף רק את הדרוש, ומריץ DAX על הנתונים הדחוסים.
בלי קשר אין מודל
כל ויזואל יציג את הסכום הכולל, $109,809,274.20, בכל שורה.
קשר = צינור פילטר
הוא לא מעתיק נתונים; הוא מאפשר לסינון לזרום מהמימד אל ה-Fact.
PK ו-FK
ייחודי בצד המימד, חוזר בצד ה-Fact. Distinct = מספר שורות זו הבדיקה.
Fact מול Dim
מספרים שסוכמים מול תיאורים שמסננים. Sales Order היא מימד מנוון בקשר 1:1.
Star מנצח
קפיצה אחת מכל מימד. הנרמול של Snowflake לא תורם כי VertiPaq כבר דוחס.
1:N ו-Single
ברירת המחדל הבריאה. N:M ו-Both הם דגלים אדומים שדורשים בדיקה.
קשר לא-פעיל
טבלת תאריכים אחת משרתת שלושה תאריכים: אחד פעיל, השאר מחכים ומופעלים לפי הצורך.
בוחן — 40 שאלות על קשרים
שאלה אחת בכל פעם, ארבע אפשרויות, משוב מיידי עם הסבר. אין ניקוד עובר — המטרה לזהות מה כדאי לחזור עליו.
טענתם שבע טבלאות ולא הגדרתם אף קשר. מה המצב במודל?
בוויזואל של מכירות לפי קטגוריה, בלי קשר בין טבלת המוצרים לטבלת המכירות — מה יוצג?
מה הכיוון הטבעי של זרימת הסינון במודל כוכב?
בתצוגת המודל, מה מסמל החץ שעל קו הקשר?
מודל שבו כל מימד מחובר ישירות לטבלת העובדות — כמה "קפיצות" עובר פילטר מהמימד אל הנתונים?
במודל שבו המימדים מפוצלים לשרשרת (קטגוריה ← תת-קטגוריה ← מוצר), מה קורה לפילטר על הקטגוריה?
מחקתם את כל הקשרים במודל. מה יקרה לוויזואלים בדוח?
איפה יושב המפתח הראשי בקשר תקין?
מה מאפיין את המפתח הזר בטבלת העובדות?
איזו בדיקה מאשרת שעמודה מתאימה לשמש מפתח ראשי?
בטבלת מוצרים יש 397 שורות ובטבלת המכירות 121,253. איזו קרדינליות תתקבל?
מה מסמנים הסימנים 1 ו-* על קו הקשר?
שתי טבלאות עם אותו מספר שורות ואותו גרעין — למשל שורת מכירה ושורת הזמנה. איזה קשר ייווצר?
Power BI מציע קרדינליות רבים-לרבים בין מימד לעובדה. מה הצעד הראשון?
למה קשר רבים-לרבים נחשב מסוכן יותר מ-אחד-לרבים?
טבלת מכירות עם 121,253 שורות מקושרת לטבלת לקוחות עם 18,485 שורות. איפה יושב ה-*?
עמודת המפתח במימד היא מספר, ובעובדה אותה עמודה נטענה כטקסט. מה יקרה?
מהי ברירת המחדל של כיווניות הסינון בקשר חדש?
בחרתם קטגוריה בסלייסר, והמטריצה שמציגה שמות לקוחות לא הצטמצמה בכלל. מה הסיבה הסבירה?
מה בדיוק משנה הפיכת קשר לדו-כיווני?
באיזו שאלה עסקית תזדקקו לכיווניות דו-כיוונית?
בדוגמת משקפי השמש: סלייסר הותיר 13 מוצרים, שסיננו 813 שורות מכירה. מה יראה סלייסר הלקוחות בכיווניות חד-כיוונית?
ובאותה דוגמה, מה יקרה אחרי הפיכת הקשר בין המכירות ללקוחות לדו-כיווני?
מה הסיכון בהדלקת כיווניות דו-כיוונית על כמה קשרים במקביל?
איך משפיעה כיווניות דו-כיוונית על ביצועי המודל?
מטריצה שמציגה סכום מכירות לפי לקוח נראית תקינה גם בלי כיווניות דו-כיוונית. למה?
מהו הכלל המעשי לגבי כיווניות דו-כיוונית?
מה נכון לגבי הקשר בין כיווניות לקרדינליות?
כמה קשרים פעילים מותרים בין אותו זוג טבלאות?
איך מזוהה קשר לא-פעיל בתצוגת המודל?
לטבלת מכירות יש שלוש עמודות תאריך: הזמנה, יעד ומשלוח. מה הפתרון הנכון?
מה תפקידו של קשר לא-פעיל?
איזה מהתאריכים בטבלת מכירות מקובל להשאיר כקשר הפעיל?
ניסיתם ליצור קשר שני בין אותן שתי טבלאות. מה יקרה?
2,113 שורות מכירה ריקות בעמודת תאריך המשלוח, והקשר נבנה על העמודה הזו. מה יקרה?
בטבלת אזורים יש שורה שלא מופיעה באף שורת מכירה. מה יוצג עבורה?
לאיזו מטרה משמש חלון Manage relationships?
למה כדאי לכבות את זיהוי הקשרים האוטומטי לפני טעינה מחדש?
איזו התנהגות מעידה שכדאי לבדוק את הקשרים במודל?
טרם ענית על שאלות — 0 מתוך 40
תרגיל בית — 12 משימות עם פתרונות
בונים את המודל מאפס על AdventureWorks: מוחקים את הקשרים האוטומטיים, רואים מה נשבר, ומחברים בעצמכם — עם אימות מספרי בכל שלב.
AdventureWorks_Sales.xlsx
שבעה גיליונות. כל מספר בפתרונות אומת מול הקובץ הזה — אם קיבלתם משהו אחר, יש בעיה במודל.
מעקב התקדמות
0 מתוך 5
1 טעינה ובדיקת שורות
Get Data ← Excel ← AdventureWorks_Sales.xlsx ← בחרו את כל שבעת הגיליונות ← Load.
| שלב | מה עושים |
|---|---|
| 1 | בדקו כל טבלה בתצוגת Data ובדקו את מונה השורות למטה |
| 2 | ודאו: Sales 121,253 · Sales Order 121,253 · Customer 18,485 · Reseller 702 · Product 397 · Date 1,461 · Sales Territory 11 |
| טבלה | שורות | תפקיד |
|---|---|---|
| Sales | 121,253 | Fact — כל שורה היא פריט שנמכר |
| Sales Order | 121,253 | מימד מנוון — Channel ומספרי הזמנה |
| Customer | 18,485 | מימד |
| Reseller | 702 | מימד |
| Product | 397 | מימד — כולל Category ו-Subcategory |
| Date | 1,461 | מימד — 1.7.2017 עד 30.6.2021 |
| Sales Territory | 11 | מימד |
2 מחיקת הקשרים האוטומטיים
Home ← Manage relationships ← תיבת הסימון בכותרת ← Delete ← אישור.
| שלב | מה עושים |
|---|---|
| 1 | File ← Options ← Current File ← Data Load — כבו את Autodetect new relationships after data is loaded |
| 2 | מחקו את כל הקשרים וודאו ב-Model view שנשארו שבעה איים מנותקים |
3 המבחן: ויזואל בלי קשר
Table עם Product[Category] ו-Sales[Sales Amount].
| שלב | מה עושים |
|---|---|
| 1 | גררו Category לשורות ו-Sales Amount לערכים |
| Category | מה יוצג |
|---|---|
| Bikes | $109,809,274.20 |
| Components | $109,809,274.20 |
| Clothing | $109,809,274.20 |
| Accessories | $109,809,274.20 |
4 הקשר הראשון — Product
Model view ← גררו Product[ProductKey] אל Sales[ProductKey].
| שלב | מה עושים |
|---|---|
| 1 | ודאו קרדינליות 1:* וכיווניות Single |
| 2 | חזרו לוויזואל — המספרים נפרדים |
| Category | Sales Amount | % מסה"כ |
|---|---|---|
| Bikes | $94,620,526.21 | 86.2% |
| Components | $11,799,076.66 | 10.7% |
| Clothing | $2,117,613.45 | 1.9% |
| Accessories | $1,272,057.89 | 1.2% |
5 תאריכים — הקשר הפעיל
Date[DateKey] אל Sales[OrderDateKey].
| שלב | מה עושים |
|---|---|
| 1 | גררו את הקשר ב-Model view |
| 2 | Line chart: Fiscal Year מול Sales Amount |
| Fiscal Year | Sales Amount |
|---|---|
| FY2018 | $23,860,891.17 |
| FY2019 | $34,070,108.50 |
| FY2020 | $51,878,274.54 |
6 שלושת המימדים הנותרים
Customer, Reseller ו-Sales Territory אל Sales.
| שלב | מה עושים |
|---|---|
| 1 | CustomerKey · ResellerKey · SalesTerritoryKey — שלושה קשרים 1:* |
| 2 | Bar chart: Region מול Sales Amount, מיון יורד |
| Region | Sales Amount |
|---|---|
| Southwest | $24,184,609.60 |
| Canada | $16,355,770.46 |
| Northwest | $16,084,942.55 |
| Australia | $10,655,335.96 |
7 הקשר 1:1 — Sales Order
Sales[SalesOrderLineKey] אל Sales Order[SalesOrderLineKey].
| שלב | מה עושים |
|---|---|
| 1 | Power BI יזהה קרדינליות 1:1 |
| 2 | Donut: Channel מול Sales Amount |
| Channel | Sales Amount | שורות |
|---|---|---|
| Reseller | $80,450,596.98 | 60,855 |
| Internet | $29,358,677.22 | 60,398 |
8 בדיקת המודל
Model view — סדרו את Sales במרכז ואת ששת המימדים סביבו.
| שלב | מה עושים |
|---|---|
| 1 | ספרו את הקשרים: שישה פעילים |
| 2 | ודאו שכל החצים מהמימד אל Sales, וכולם Single |
9 קשר לא-פעיל — תאריך משלוח
Date[DateKey] אל Sales[ShipDateKey] — יסומן מקווקו.
| שלב | מה עושים |
|---|---|
| 1 | Power BI ייצור אותו כלא-פעיל אוטומטית — זה תקין |
| 2 | בדקו ב-Power Query כמה שורות ShipDateKey ריקות |
| בדיקה | תוצאה |
|---|---|
| שורות ללא תאריך משלוח | 2,113 |
| הסכום שלהן | $1,281,073.41 |
| מה יקרה בוויזואל | ייפלו לשורה ריקה (Blank) |
10 הקשר הלא-פעיל — מה הוא ישנה
Manage relationships — בדקו את הקשר על תאריך המשלוח.
| שלב | מה עושים |
|---|---|
| 1 | פתחו את חלון הקשרים ואתרו את הקשר שסטטוסו Inactive |
| 2 | רשמו לעצמכם: איזו עמודה בכל צד, מה הקרדינליות, ומה כיווניות הסינון |
| 3 | בתצוגת המודל ודאו שהוא מצויר בקו מקווקו, בעוד שהקשר על תאריך ההזמנה מצויר בקו מלא |
11 מוצרים שלא נמכרו
Table: Product[Product] ו-Sales Amount.
| שלב | מה עושים |
|---|---|
| 1 | הוסיפו Count (Distinct) על Sales[ProductKey] |
| 2 | סננו לשורות שבהן Sales Amount ריק |
| בדיקה | תוצאה |
|---|---|
| מוצרים בקטלוג | 397 |
| מוצרים שנמכרו | 350 |
| מעולם לא נמכרו | 47 |
12 משווקים ללא מכירות
אותה בדיקה על Reseller.
| שלב | מה עושים |
|---|---|
| 1 | Count (Distinct) על Sales[ResellerKey] מול מספר השורות ב-Reseller |
| בדיקה | תוצאה |
|---|---|
| משווקים בקובץ | 702 |
| משווקים עם מכירות | 636 |
| ללא מכירות | 66 |
סיכום — המספרים שחייבים להתקבל
| בדיקה | תוצאה מאומתת |
|---|---|
| סה"כ מכירות | $109,809,274.20 |
| Bikes | $94,620,526.21 |
| FY2020 | $51,878,274.54 |
| Southwest | $24,184,609.60 |
| Reseller מול Internet | $80,450,596.98 מול $29,358,677.22 |
| שורות ללא תאריך משלוח | 2,113 · $1,281,073.41 |
| מוצרים שנמכרו | 350 מתוך 397 |
| משווקים עם מכירות | 636 מתוך 702 |
משאבים והמשך הדרך
להעמיק במודלינג
אפשר לנווט גם בכפתורים שבראש המסך, בחצי המקלדת, ובטלפון בהחלקת אצבע