דלגו לתוכן

תכננו לצורה הנורמלית השלישית, ואז קחו צעד אחורה

זמין גם ב-28 שפות

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A park seen from above: paths at right angles, and one diagonal shortcut that people kept walking, now deliberately paved, with the old worn track still faint beside it.
התמונה נוצרה בבינה מלאכותית

יחידה 5 מתוך 6 בפרק מידול נתונים למען המשמעות, הפרק השני בקורס Data Architect. כל יחידה עומדת בפני עצמה. הקודם: שימו את הנתונים במקום שלהם · הבא: הפכו את המודל ל-Salesforce

השאלה שהיחידה הזו עונה עליה: מתי כדאי להתרחק בכוונה ממודל נקי ומנורמל?

ביחידה הקודמת אמרתי לכם לתכנן לצורה הנורמלית השלישית.

עכשיו אני הולך להגיד לכם לשבור אותה.

לפעמים.

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

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

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

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

התחילו במידול של האמת. ואז החליטו איך צריך למסור את האמת הזו.

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

גזע: רשימת בחירה, או טבלה משלו? העבירו אותו דרך השאלות שאתן לכם בהמשך היחידה. האם יש יותר מעמודה אחת של מידע? כן: לפחות הגודל. כמה ערכים? מועדוני כלבנות מכירים בכמה מאות גזעים (ה-American Kennel Club לבדו מונה 205), הרבה מעבר לכלל האצבע שלי של בערך 20. אז הגזע מרוויח טבלה משלו, וכל כלב מצביע על הגזע שלו. זה מכריע את השאלה שסחבנו מאז יחידה 1: גזע הוא קופסה משלו.

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

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

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

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

מודל חיות המחמד אחרי הפשרות מודל חיות המחמד כמודל נתונים מפורט. חיית מחמד יושבת במקום שבו היה כלב: מזהה חיית מחמד, מוכרת גם לפי מספר השבב, המזהים של הבעלים, המגדל והגזע, מין (רשימת בחירה: כלב או חתול), שם, תאריך לידה וספירת תרגילים שנלמדו שנשמרת לדיווח. גזע מחובר עכשיו (חיית מחמד היא מגזע אחד) ויש לו מין, שם וגודל משלו. תרגיל של חיית מחמד, בין חיית מחמד לתרגיל, מחזיק את רמת המיומנות כרשימת בחירה ואת תאריך הלימוד; הערכת תרגיל, מתחתיו, מחזיקה תאריך, רמת מיומנות ומי העריך. בעלים מחזיק חיות מחמד ומגדל מגדל אותן, כמו קודם. הבעלים של מגדל הוא יודע ידוע ב נבדק ב בעלים מזהה בעלים מזהה רשומה שם טלפון ZIP עיר מגדל מזהה מגדל מזהה רשומה שם עיר חיית מחמד מזהה חיית מחמד מזהה רשומה מספר שבב מוכר גם בתור מזהה בעלים מזהה מגדל מזהה גזע מין (רשימת בחירה) שם תאריך לידה תרגילים שנלמדו (ספירה) גזע מזהה גזע מזהה רשומה מין (רשימת בחירה) שם גודל תרגיל של חיית מחמד מזהה תרגיל של חיית מחמד מזהה רשומה מזהה חיית מחמד מזהה תרגיל רמת מיומנות (רשימת בחירה) תאריך לימוד תרגיל מזהה תרגיל מזהה רשומה שם רמת קושי הערכת תרגיל מזהה הערכת תרגיל מזהה רשומה מזהה תרגיל של חיית מחמד תאריך רמת מיומנות (רשימת בחירה) הוערך על ידי בדיוק אחד אפס או אחד אחד או רבים אפס או רבים © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

עכשיו אותם סוגי החלטות ב-Steve Trucking, שבה הסיכון גבוה יותר.

המודל הנקי ביותר הוא לא תמיד המערכת הטובה ביותר

Section titled “המודל הנקי ביותר הוא לא תמיד המערכת הטובה ביותר ”

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

המודל המנורמל יפהפה: משלוח ← פריט משלוח ← רשימת בדיקה להתקנה ← תמונה, כל אחד במקום שבו הוא שייך.

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

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

אנחנו מתכננים מערכת.

לפעמים חוויית המשתמש מנצחת

Section titled “לפעמים חוויית המשתמש מנצחת ”

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

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

כאן אני מפסיק לשאול רק “איפה העובדה הזו שייכת בתיאוריה?” ומתחיל לשאול “איך באמת ישתמשו במערכת הזו?”

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

דיווח הוא עוד סיבה נפוצה.

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

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

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

עכשיו הכנסתי כפילות. אז אני צריך עוד שאלה: למי שייכת האמת?

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

דה-נרמול לא מעלים מורכבות.

הוא מזיז אותה.

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

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

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

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

אז אני שואל: האם יש לו מידע משלו? קשרים? האם הוא משתנה באופן עצמאי? האם צריך לנהל אותו כנתונים? האם העסק עשוי בסוף להזדקק ממנו ליותר מתווית?

הנה השאלות שאני באמת שואל בפגישת תכנון.

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

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

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

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

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

תווית או ישות? סטטוס וסוג העצירה שני כרטיסים. סטטוס משלוח, רשימת בחירה: שמונה ערכים יציבים, כל אחד מילה אחת או מילה עם מקפים (מתוזמן, הועמס, בדרך-למסירה, מגיע, נמסר, הותקן, חריגה, הוחזר), וכל אחד הוא רק תווית. סוג עצירה, ישות: עשרים וארבעה ערכים ועוד יבואו, כמו משלוח בלבד, משלוח ועוד התקנה של מכונת כביסה או כיריים גז, משלוח ועוד פינוי, פינוי בלבד, איסוף החזרה ועוד שמונה עשר; לכל אחד משך עצירה, כישורי צוות נדרשים ורשימת בדיקה להתקנה משלו. הערה מתחת: מעל כ-20 ערכים, או עם מאפיינים משלו, זו ישות, לא תווית. סטטוס משלוח רשימת בחירה הערכים: 8, ויציבים מתוזמן הועמס בדרך-למסירה מגיע נמסר הותקן חריגה הוחזר כל ערך הוא רק תווית סוג עצירה ישות הערכים: 24, ועוד יבואו משלוח בלבד משלוח + התקנה: מכונת כביסה משלוח + התקנה: כיריים גז משלוח + פינוי פינוי בלבד איסוף החזרה …ועוד 18 לכל ערך יש משלו משך העצירה כישורי צוות נדרשים רשימת בדיקה להתקנה מעל כ-20 ערכים, או מאפיינים משלו: זו ישות, לא תווית. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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

Section titled “לפעמים קנה המידה משנה את התשובה ”

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

אז אל תסתכלו רק על התרשים. הכירו את המספרים.

Steve Trucking מבצעת בערך מיליון משלוחים בשנה, עם צמיחה של 30% בשנה. כל משלוח צובר בערך שמונה עדכוני סטטוס. זה שמונה מיליון רשומות סטטוס השנה, ובערך 13.5 מיליון בשנה עד השנה השלישית. הוסיפו ארבעה או חמישה מיליון תמונות בשנה.

אותו מודל. ארכיטקטורה שונה מאוד.

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

צרכנים שונים רוצים צורות שונות

Section titled “צרכנים שונים רוצים צורות שונות ”

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

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

מערכת אנליטית עשויה לרצות את אותו מידע מאורגן אחרת. תשמעו מונחים כמו מחסן נתונים (data warehouse), fact, dimension ו-star schema. לא נפרק אותם כאן; ב-Steve Trucking זה מחסן הנתונים ב-Snowflake, ונחזור אליו בהמשך הקורס.

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

הבינה המלאכותית מוסיפה עוד צרכן

Section titled “הבינה המלאכותית מוסיפה עוד צרכן ”

ועכשיו יש עוד צרכן: בינה מלאכותית (AI).

נמען שולח הודעה: “איפה המשלוח שלי?” עוזר בינה מלאכותית יכול לשלוף את זה:

משלוח 10427, מסלול 3312, עצירה 7, משאית 117, חלון 13:00–15:00.

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

מדיח הכלים שלכם מ-Redrock הוא העצירה השביעית במסלול של היום ממרכז ההפצה בפיניקס. המשאית נמצאת במרחק שלוש עצירות, ואתם עדיין בתוך החלון שלכם, 13:00–15:00.

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

זה לא אומר שאני הורס את המודל המנורמל שלי. וזה בטח לא אומר “בינה מלאכותית אוהבת נתונים שטוחים, אז שימו הכול באובייקט ענק אחד.” אל תעשו את זה.

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

מקור אמת אחד יכול לתמוך בכמה צורות לצריכה.

נעמיק הרבה יותר בעיגון בנתונים (grounding) ובאחזור בהמשך הקורס.

יש כאן סכנה.

אם אני מעתיק את האזור למשלוח בשביל דיווח, שולח גרסה שטוחה ל-Snowflake, ובונה גרסה עשירה בהקשר לעוזר הבינה המלאכותית, איזו מהן נכונה?

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

המקום הזה הוא מערכת הרשומה (system of record). עותקים לא מנורמלים יכולים להיות טובים: מסך העצירה, כרטיס הציון, Snowflake וההקשר של הבינה המלאכותית עושים כל אחד את העבודה שלו טוב יותר עם צורה שנבנתה בשבילו, ולהסתמך עליהם זה בסדר. אבל כשמשהו משתנה, השינוי מתחיל במערכת הרשומה, בדרך כלל המודל הרלציוני, וזורם החוצה לכל עותק. אף אחד לא מתקן את האזור ב-Snowflake, או עורך את ההקשר של הבינה המלאכותית ביד. תקנו במקור, ותנו לשינוי לזרום.

מערכת הרשומה: שינוי זורם החוצה תיבה אחת למעלה, מערכת הרשומה, רלציונית, שבה מתחילים שינויים, ממנה חצים זורמים למטה לארבעה עותקים שנבנים ממנה: מסך העצירה של הצוות, עצירה אחת, הכול בעמוד אחד; כרטיס הביצועים של השותף, משלוחים מאחרים לפי אזור; מחסן הנתונים Snowflake, שנים של היסטוריה; והקשר הבינה המלאכותית למשלוחים, עבור "איפה המשלוח שלי?". הערה מתחת: שינוי מתחיל במערכת הרשומה וזורם החוצה לכל עותק; לעולם אל תתקנו עותק. מערכת הרשומה רלציונית: שינויים מתחילים כאן מסך העצירה של הצוות עצירה אחת, הכול בעמוד אחד כרטיס הביצועים של השותף משלוחים מאחרים לפי אזור מחסן הנתונים Snowflake שנים של היסטוריה הקשר בינה מלאכותית למשלוחים "איפה המשלוח שלי?" שינוי מתחיל במערכת הרשומה וזורם החוצה לכל עותק. לעולם אל תתקנו עותק. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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

בגלל זה דה-נרמול לעולם לא צריך לקרות במקרה. כל עובדה משוכפלת מעלה שאלות על בעלות, סנכרון, היסטוריה ואמון. זו חשיבת הפשרות מפרק 1: דעו מה אתם קונים (מסך קל יותר, דוח פשוט יותר, הקשר טוב יותר לבינה מלאכותית) ומה אתם משלמים (נתונים כפולים, סנכרון, בעלות מסובכת יותר על האמת). ומכיוון שהתחלנו ממודל לוגי נקי, אנחנו יכולים להצביע על כל עותק ולומר: “אני יודע שזה שייך לשם. אני שם כאן ייצוג שלו בגלל הדרישה הזו.” זו החלטה שאפשר לסקור, לאתגר ולתעד, כדי שהארכיטקט הבא ידע למה.

כשאני שוקל דה-נרמול, אני מחליט:

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

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

בהמשך, Salesforce חוזרת לתמונה. אנחנו הולכים להפוך את מה שתכננו למודל נתונים פיזי.