דלגו לתוכן

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

זמין גם ב-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)

Two identical drawers on a workbench, seen from above: one jammed with everything mixed together, one divided so each kind of thing has its own compartment.
התמונה נוצרה בבינה מלאכותית

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

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

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

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

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

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

מנרמלים בשלבים שנקראים צורות נורמליות, וכל אחת שואלת שאלה אחת:

  • צורה נורמלית ראשונה (1NF): ערך אחד בכל שדה, ומשהו שמזהה באופן ייחודי כל שורה.
  • צורה נורמלית שנייה (2NF): כל עובדה מתארת את כל מה שמזהה את השורה, לא רק חלק ממנו.
  • צורה נורמלית שלישית (3NF): כל עובדה מתארת את הדבר הזה, לא משהו אחר שהוא קשור אליו.

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

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

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

כלבנולדבעליםמיקודעירגזעמגדלתרגילים
Bella2017Marcus80202דנוורלברדורMaple Ridgeשב, חכה, תן יד
Milo2019Marcus80202דנוורפודלGolden Meadowשב, התגלגל
Max2022Ana64105קנזס סיטימעורבשב, תעשה מת
Luna2020Kenji98101סיאטלהאסקיCascadeשב, חכה, סיבוב
Rocky2024Priya30301אטלנטהביגלMaple Ridgeשב
Coco2014Ana64105קנזס סיטיצ’יוואווהLittle Pawsתן יד, סיבוב

זה עובד. כל גיליון עובד ביום הראשון. אבל תראו מה כבר לא בסדר. איך אני מוצא כל כלב שיודע תן יד? המיקוד של Ana מופיע בשתי שורות, וגם של Marcus: מה קורה אם מישהו מעדכן אחת ולא את השנייה? Maple Ridge מופיע פעמיים, וגם קנזס סיטי. ו-Max הגיע מהכלבייה העירונית, אז אין לו מגדל בכלל.

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

כלב (מזוהה לפי מזהה כלב)

מזהה כלבשםנולדבעליםמיקודעירגזעמגדל
D-001Bella2017Marcus80202דנוורלברדורMaple Ridge
D-002Milo2019Marcus80202דנוורפודלGolden Meadow
D-003Max2022Ana64105קנזס סיטימעורב
D-004Luna2020Kenji98101סיאטלהאסקיCascade
D-005Rocky2024Priya30301אטלנטהביגלMaple Ridge
D-006Coco2014Ana64105קנזס סיטיצ’יוואווהLittle Paws

תרגיל של כלב (מזוהה לפי מזהה כלב + תרגיל)

מזהה כלבתרגילרמת קושירמת מיומנותנלמד
D-001שבקלמומחה2017-11
D-001חכהקלמומחה2018-01
D-001תן ידבינוניטוב2018-06
D-002שבקלמומחה2020-02
D-002התגלגלקשהבלמידה2023-05
D-003שבקלטוב2022-06
D-003תעשה מתקשהבלמידה2024-03
D-004שבקלמומחה2020-11
D-004חכהקלטוב2021-01
D-004סיבובבינונימומחה2021-06
D-005שבקלבלמידה2025-02
D-006תן ידבינונימומחה2015-06
D-006סיבובבינוניבלמידה2025-04

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

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

תרגיל

מזהה תרגילתרגילרמת קושי
T-01שבקל
T-02חכהקל
T-03תן ידבינוני
T-04התגלגלקשה
T-05תעשה מתקשה
T-06סיבובבינוני

תרגיל של כלב (מזהה כלב + מזהה תרגיל)

מזהה כלבמזהה תרגילרמת מיומנותנלמד
D-001T-01מומחה2017-11
D-001T-02מומחה2018-01
D-001T-03טוב2018-06
D-002T-01מומחה2020-02
D-002T-04בלמידה2023-05
D-003T-01טוב2022-06
D-003T-05בלמידה2024-03
D-004T-01מומחה2020-11
D-004T-02טוב2021-01
D-004T-06מומחה2021-06
D-005T-01בלמידה2025-02
D-006T-03מומחה2015-06
D-006T-06בלמידה2025-04

טבלת תרגיל של כלב היא זו שמצאנו ביחידה 2, ויש לה שם במידול נתונים: צומת (junction), או כמו שאני קורא לה, אובייקט צומת לוגי. כלב יודע הרבה תרגילים; תרגיל ידוע להרבה כלבים. הצומת יושב ביניהם, והוא לא אינסטלציה ריקה: הוא מחזיק את העובדות ששייכות לקשר עצמו, רמת המיומנות והתאריך. ניפגש בו שוב ביחידה 6, ובפרק 3 נראה ש-Salesforce משתמשת ב”אובייקט צומת” במובן צר יותר: אובייקט הצומת של Salesforce (Salesforce Junction Object) הוא אובייקט מותאם אישית עם שני קשרי master-detail (פרק 3, יחידה 7).

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

  • כלב: מזהה כלב, שם, נולד, מזהה בעלים, מזהה גזע, מזהה מגדל
  • בעלים: מזהה בעלים, שם, מיקוד, עיר
  • גזע: מזהה גזע, גזע, גודל
  • מגדל: מזהה מגדל, שם, עיר
  • תרגיל ותרגיל של כלב, משלב 2

עכשיו Ana שמורה פעם אחת, ושני הכלבים שלה מצביעים עליה. Maple Ridge שמור פעם אחת, וטבלת הגזע נותנת לנו בית לעובדות על כל גזע, כמו הגודל שלו, שלגיליון לא היה איפה לשים אותן. מפתח זר יכול להיות ריק: ל-Max אין מזהה מגדל, וזו תשובה כנה, לא חור. ואז אני זורק לחדר שאלה מכשילה: מתי הבעלים קיבלו את הכלב, לאן התאריך הזה הולך? על הכלב. לכלב יש בעלים אחד בכל רגע נתון במודל הזה, אז התאריך הזה מתאר את הקשר של הכלב לבעלים שלו.

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

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

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

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

עכשיו בואו ניישם את זה על Steve Trucking

Section titled “עכשיו בואו ניישם את זה על Steve Trucking ”

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

משלוחשותף קמעונאימרכז הפצהעיר מרכז ההפצהצוותמשאית
1001KeystoneKeystone Phoenix DCפיניקסצוות 12117
1002KeystoneKeystone Phoenix DCפיניקסצוות 8122
1003KeystoneKeystone Phoenix DCפיניקסצוות 12117

במבט ראשון שום דבר כאן לא מסובך. אבל תסתכלו על מרכז ההפצה. אנחנו חוזרים על “Keystone Phoenix DC, פיניקס” בכל משלוח שיוצא ממנו: Steve Trucking מבצעת בערך 3,300 משלוחים ביום בתשעה מרכזי הפצה, אז כמה מאות ביום מכל אחד. מה קורה אם מרכז ההפצה הזה עובר? כמה רשומות משנים, ומה קורה אם מפספסים אחת? עכשיו הנתונים אומרים שמרכז ההפצה נמצא בשתי ערים בבת אחת. זו אנומליית עדכון. ומה אם אנחנו רוצים להקים מרכז הפצה חדש לפני המשלוח הראשון שלו? ומה אם אנחנו מוחקים את המשלוח האחרון ממרכז הפצה: מחקנו הרגע את המקום היחיד שבו שמרנו משהו עליו?

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

צורה נורמלית ראשונה: אל תסתירו מבנה שחוזר על עצמו

Section titled “צורה נורמלית ראשונה: אל תסתירו מבנה שחוזר על עצמו ”

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

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

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

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

תראו את זה ב-orgs אמיתיים כל הזמן. מישהו צריך תיאור בכמה שפות, אז הוא יוצר שדה בשם Description_English, אחר כך Description_French, אחר כך Description_German. או שאישור צריך כמה אנשים, אז מקבלים Approver 1, Approver 2, Approver 3. כשאני מוצא את זה בסקירה, זו מכה על היד: תתקנו את מודל הנתונים. אחד או שניים, אולי, אם לעסק באמת יש תמיד רק אחד או שניים. כל דבר מעבר לזה צריך להיות אובייקט ילד: תרגום (Translation) עם שפה, שלב אישור (Approval Step) עם מאשר. השפה הבאה, או המאשר הרביעי, הופכים לרשומה חדשה, לא לשדה חדש ולפריסה.

צורה נורמלית שנייה: תארו את הדבר כולו

Section titled “צורה נורמלית שנייה: תארו את הדבר כולו ”

הצורה הנורמלית השנייה, או 2NF, חשובה כשרשומה מזוהה לפי צירוף של דברים. קחו את פריט המשלוח. יש לו מזהה רשומה משלו, אבל כל אחד ייחודי לפי משלוח + מוצר. נניח שאנחנו שומרים את המשלוח, את המוצר, את הכמות ואת תיאור המוצר.

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

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

צורה נורמלית שלישית: אל תשמרו עובדות על עובדות אחרות

Section titled “צורה נורמלית שלישית: אל תשמרו עובדות על עובדות אחרות ”

עכשיו זו שהכי חשובה לי במידול היומיומי: הצורה הנורמלית השלישית, או 3NF.

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

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

עובדה על עובדה אחרת: מנהל ה-DC שני חלונות. בכל משלוח: רשומת משלוח עם מזהה הרשומה שלה, תאריך המשלוח, מרכז ההפצה, והעיר והמנהל של ה-DC, שניהם מסומנים כחוזרים. נשמר פעם אחת, אצל ה-DC: המשלוח שומר את מזהה הרשומה, תאריך המשלוח ומזהה מרכז ההפצה, ויוצא ממרכז הפצה, שיש לו מזהה רשומה משלו, שם, עיר ומנהל. הערה מתחת: מנהל DC חדש פירושו מאות עדכונים משמאל ואחד מימין. בכל משלוח נשמר פעם אחת, אצל ה-DC יוצא מ משלוח מזהה משלוח מזהה רשומה תאריך משלוח מרכז הפצה עיר ה-DC חוזר מנהל ה-DC חוזר משלוח מזהה משלוח מזהה רשומה תאריך משלוח מזהה מרכז הפצה מרכז הפצה מזהה מרכז הפצה מזהה רשומה שם עיר מנהל מנהל DC חדש: מאות עדכונים משמאל, אחד מימין. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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

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

Steve Trucking אחרי נרמול חמש תיבות מחוברות בקווים. שותף קמעונאי מפעיל אפס מרכזי הפצה או רבים. משלוח יוצא ממרכז הפצה אחד בדיוק ומכיל פריט משלוח אחד או רבים. כל פריט משלוח הוא מוצר אחד בדיוק, ומוצר מופיע באפס פריטי משלוח או רבים. מפעיל יוצא מ מכיל מופיע ב שותף קמעונאי משלוח פריט משלוח מוצר מרכז הפצה בדיוק אחד אפס או אחד אחד או רבים אפס או רבים © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

אותן שלוש שאלות, אותה תוצאה: כל עובדה במקום אחד.

דרך פשוטה לחשוב על 1NF, 2NF ו-3NF

Section titled “דרך פשוטה לחשוב על 1NF, 2NF ו-3NF ”

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

  • 1NF: האם אני מסתיר כמה ערכים או מבנים שחוזרים על עצמם בתוך שדה או רשומה?
  • 2NF: האם העובדה הזו מתארת את כל הדבר שאני מזהה?
  • 3NF: האם העובדה הזו באמת מתארת את הישות הזו, או משהו שקשור אליה?

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

כן, הנרמול ממשיך הלאה: צורה נורמלית Boyce-Codd (BCNF) מהדקת את הכללים סביב 3NF למודלים עם מפתחות מסובכים יותר, ויש צורות נורמליות רביעית, חמישית ואפילו שישית. הן עוסקות בסוגים נדירים יותר של חזרה, כאלה שנובעים ממבני מפתח לא שגרתיים יותר מאשר מרשומות עסקיות יומיומיות. הרבה תיאוריה, ולפי הניסיון שלי לא שווה את כאב הראש בסוג המערכות שאנחנו בונים על Salesforce. במערכות עסקיות, הלחץ בדרך כלל הולך לכיוון ההפוך: הרבה יותר סביר שניקח צעד אחורה מהצורה הנורמלית השלישית, בשביל משתמשים, דיווח וביצועים, מאשר שנעבור אותה. זו היחידה הבאה. דעו שהצורות הנוספות קיימות, אבל לרוב מה שאנחנו עושים, 1NF עד 3NF נותנות לנו את כלי החשיבה שאנחנו צריכים.

תכננו לצורה הנורמלית השלישית

Section titled “תכננו לצורה הנורמלית השלישית ”

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

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

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

כשאני מנרמל מודל לוגי, אני מחפש:

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

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