הטעויות הכי נפוצות בעיצוב מסד נתונים - ואיך להימנע מהן מראש¶
יש הבדל ענק בין לדעת לכתוב שאילתת SQL לבין לדעת לתכנן מסד נתונים טוב. ראיתי מתכנתים שכותבים קוד מעולה, אבל כשמגיעים לתכנון הטבלאות עצמן, עושים טעויות שרודפות את הפרויקט חודשים אחרי שהוא כבר בייצור. הנה הטעויות שאני רואה הכי הרבה, ואיך למנוע אותן.
טעות ראשונה - לשמור הכל בטבלה אחת ענקית¶
זו הטעות הכי נפוצה של מתחילים, ובאופן טבעי - זה נראה פשוט יותר בהתחלה. במקום לפצל מידע לטבלאות נפרדות עם קשרים ביניהן, הכל נדחס לטבלה אחת עם עשרות עמודות.
הבעיה מתחילה להתגלות רק אחרי כמה חודשים, כשמגלים שאותו מידע חוזר על עצמו בעשרות שורות, ועדכון פרט אחד דורש עדכון בעשרות מקומות. זה בדיוק מה שנורמליזציה נועדה למנוע - לפצל מידע לטבלאות שכל אחת אחראית על תחום ברור, ולקשר ביניהן במקום לשכפל.
טעות שנייה - לא להגדיר מפתחות זרים כמו שצריך¶
הרבה מתכנתים "מקשרים" בין טבלאות רק במחשבה, בלי לומר למסד הנתונים בפועל שיש קשר. למשל, עמודת customer_id בטבלת הזמנות בלי אילוץ (constraint) שאומר למסד הנתונים "הערך הזה חייב להתאים לשורה קיימת בטבלת לקוחות".
בלי האילוץ הזה, שום דבר לא מונע מכם ליצור הזמנה עם customer_id שלא קיים בכלל, וברגע שזה קורה בייצור, יש לכם מידע פגום שקשה לעקוב אחריו. הגדרת מפתח זר אמיתי (FOREIGN KEY) גורמת למסד הנתונים עצמו לשמור על התקינות הזאת, במקום לסמוך על שהקוד תמיד יהיה נכון.
טעות שלישית - לבחור סוג נתונים לא מתאים¶
זו טעות שנשמעת קטנה אבל גוררת בעיות אמיתיות. שמירת תאריכים כמחרוזת טקסט במקום כסוג DATE ייעודי, שמירת מספרים כטקסט, או שימוש בסוג נתונים שלא מגביל את הטווח הנכון של ערכים.
כשתאריך נשמר כטקסט, מיון לפי תאריך פתאום לא עובד נכון (כי מיון טקסטואלי שונה ממיון כרונולוגי), וחישובים כמו "כמה ימים עברו" הופכים מסובכים במקום פעולה פשוטה. תמיד כדאי להשתמש בסוג הנתונים המדויק ביותר שקיים למטרה - תאריכים כ-DATE, כסף כ-DECIMAL ולא כ-FLOAT (בגלל בעיות דיוק בנקודה צפה), וטקסט קצר עם הגבלת אורך כשמתאים.
טעות רביעית - לא לחשוב על אינדקסים מראש¶
תכנון טבלאות בלי לחשוב אילו שאילתות ירוצו עליהן זו טעות שמתגלה רק כשהנתונים כבר גדולים. עמודות שמחפשים בהן הרבה, כמו אימייל בטבלת משתמשים, חייבות אינדקס. בלעדיו, השאילתה תעבוד מצוין עם עשר שורות בפיתוח, ותהיה איטית באופן מכאיב עם מיליון שורות בייצור.
ההמלצה שלי היא לחשוב על השאילתות הנפוצות ביותר שהאפליקציה תריץ עוד בשלב התכנון, ולתכנן אינדקסים בהתאם, לא לחכות שמישהו יתלונן שהאתר איטי.
טעות חמישית - לתת לעמודות ID להיות בעלות משמעות עסקית¶
יש פיתוי לתת למספר הזמנה או קוד לקוח משמעות - למשל לקודד בתוך המזהה את השנה או הסניף. זה נראה נוח בהתחלה, אבל ברגע שהכללים העסקיים משתנים (סניף מתמזג, מבנה הקידוד משתנה), כל המידע שנשען על המזהה נשבר. עדיף שהמזהה יהיה ערך טכני נטול משמעות, ומידע עסקי כמו שנה או סניף יישמר בעמודה נפרדת משלו.
טעות שישית - לא לתכנן מראש מה קורה כשמוחקים רשומה¶
מה קורה כשמוחקים לקוח שיש לו הזמנות קיימות? האם ההזמנות נמחקות איתו? נשארות יתומות? הפעולה נחסמת? זו שאלה שצריך להחליט עליה במפורש בזמן תכנון הטבלאות, לא לגלות אותה בטעות בייצור כשמישהו מוחק לקוח וכל ההיסטוריה שלו נעלמת בטעות. מסדי נתונים רלציוניים נותנים לכם אפשרות להגדיר את ההתנהגות הזאת ישירות בהגדרת מפתח זר.
איך נמנעים מכל זה בפועל¶
התשובה האמיתית היא לא "לזכור רשימה של טעויות", אלא להבין לעומק את העקרונות שעומדים מאחוריהן - נורמליזציה, מפתחות, אינדקסים, וסוגי נתונים. ברגע שהעקרונות האלה מובנים, רוב הטעויות האלה פשוט לא קורות, כי הן מרגישות לא נכונות באופן אינטואיטיבי.
בקורס צד-שרת עוברים על תכנון סכמות דרך תרגילים אמיתיים, כולל לקבל דרישות עסקיות ולתכנן מבנה טבלאות שעומד במבחן הזמן.
עובדים על תכנון סכמה ולא בטוחים אם היא נכונה? זה בדיוק סוג הדבר שכדאי לבדוק עם עוד עיניים בקהילה.