מבוא לבחירת דאטה בייס

מבוא לבחירת דאטה בייס

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

מה לא יהיה בפוסט: בפוסט זה לא יהיה המלצה חד משמעית על דאטה בייסים. אם אתה מחפש תשובות כמו רק MySQLl או Redis is the new king אז הגעת למקום הלא נכון. בכלל בפוסט הזה אני אנסה בכלל לא להזכיר שמות של בסיסי נתונים אלא רק לדבר על העקרונות המופשטים.

שלב ראשון – מה קוראים

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

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

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

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

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

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

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

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

שלב שני – כותבים לבסיס הנתונים

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

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

נקודות חשובות כשכותבים לבסיס נתונים:

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

סיפור מהחיים – משחק תורות מרובה משתתפים

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

  1. מחכים עד שלפחות 4 אנשים מצטרפים למשחק.
  2. השרת מציג בעיה בפניי השחקנים.
  3. כל שחקן עונה תשובה – אך מרגע שהשחקן הראשון ענה יש להם רק 15 שניות לתת תשובה.
  4. כל שחקן רואה איזה שחקן אחר כבר ענה.
  5. השרת חושף את התשובות לכולם.
  6. השחקן שענה נכון מקבל 20 נקודות.
  7. אם יש שחקן שהגיע ל100 נקודות המשחק נגמר – אם לא אז חוזרים לשלב הראשון.

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

בהתחלה מימשנו את הדאטה בייס בRedis כדי לקבל דאטה בייס מהיר שתומך בשרתים רבים אך די מהר ראינו שהפיתרון איטי והוא לא סקלבילי. לאחר מכן ניסינו לממש את זה בעזרת Firebase Realtime Database שנותן גם אפשרות של דחיפת נתונים לקליינט אך גם זה לא פתר לנו את הבעיה. ואז הבנו שמיכוון שבכל משחק יש לנו מספר מוגבל של שחקנים לפרק זמן קצר אזי אנחנו לא חייבים דאטה בייס שיהיה משותף בין כל השרתים אלא כל שרת יכול לעבוד עם דאטה בייס קטן משלו, ובסוף המשחק לשמור את תוצאות המשחק בארכיון כמו שירות s3 בקובץ json פשוט.

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

החוקים

אל תתחתן עם בסיס הנתונים שלך

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

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

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

פרטיות והגנה

המידע של המשתמשים שלך נשמר בדאטה-בייס ואירוע דליפה שלו בדרך כלל יהיה הרבה יותר חמור מאשר עם קוד המקור של התוכנה שלך דולף ולכן חובה לשמור עליו מכל משמר. ב99%.99 מהמקרים בסיס הנתונים צריך לשבת מאחוריי VPN ולקבל בקשות גישה מרשימת כתובות מורשות וכמובן מאחורי שם משתמש וסיסמא.

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

כסף

תמיד חשוב לחשוב על העלות של הדאטה בייס ולראות שזה לא שורף לך את כל התקציב התפעולי של הפרויקט. לדוגמא בענן יש הרבה פעמים databases מנוהלים עם auto-scale אוטומטי מה שהופך אותם נוחים מאוד לתפעול – אך מצד שני הם עולים בערך 30% יותר מאשר לנהל בעצמך את מספר השרתים. מה שהופך אותם לפתרון מאוד נוח לדאטה בייסים קטנים ובינוניים אך להוצאה גדולה מאוד בשימוש גדול.

ביצועים

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

גיבוי

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

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

כתיבת תגובה

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

*