שיקולים ולבטים בתכנון בסיס הנתונים של FireStats

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

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

טבלאת הכתובות נראית היום כ:
urls table
טבלאת ההמפנים נראית היום כך:
referrers table

אפשר לראות שיש דמיון:
url וreferer הם בעצם שדה הכתובת.
md5 הוא שדה של גיבוב md5 של הכתובת
אבל גם הבדלים:
בטבלאת המפנים יש עוד כמה שדות שקשורים לתמיכה במילות חיפוש (שנכנסה בגרסא האחרונה).

במסגרת רצון להוסיף תמיכה בווידג'ט של פוסטים פופולריים הוספתי טבלאת METADATA לטבלאת הURLים.
הmetadata יכול להכיל פרטים כמו כותרת של הפוסט, אם יש, וסוג הכתובת (post, לינק להורדה בהמשך ועוד).

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

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

Facebook Comments

4 תגובות בנושא “שיקולים ולבטים בתכנון בסיס הנתונים של FireStats”

  1. אהלן עומרי, פוסט מעניין.
    אני לא עברתי קורס מתאים באונ', ואין לי את הרקע התאורתי הפורמלי, אבל אולי משהו שאכתוב יהיה בו ערך.

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

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

    * עבור הפיצ'ר שהעלית של "פוסטים פופולאריים", הייתי שוקל להוסיף לטבלת המפנים המאוחדת את השדה של "האם ה- URL הזה הוא חלק מהבלוג או לא". (כי אם לא תרשום זאת כשדה, נישמע שתצטרך לחשב את זה כל פעם מחדש, בשביל לענות על השאלה "איזה לינקים *מתוך הבלוג שלי* הם הכי פופולאריים").

    * אפשר לחסוך מקום על ידי פירוק כל לינק מפנה לשתי מחרוזות "דומיין של כתובת" ו- "שארית הדומיין" (ולעשות שדה לכל אחד מהם בניפרד).
    כלומר, שני הלינקים הבאים:
    http://firefang.net/blog/701
    http://firefang.net/blog/700
    יפורקו כך:
    http://firefang.net/ + blog/701
    http://firefang.net/ + blog/700
    ואז אפשר לעשות טבלת דומיינים לפיה http://firefang.net/ = 1
    רק על אנשים שמגיעים מגוגל, כבר חסכת המון מקום.

    * נקודה נוספת היא מילות החיפוש,
    נישמע כאילו אפשר לעשות גם טבלה מזהה ניפרדת למילות חיפוש (כלומר שיהיה: search_terms_id שתפנה לטבלה מתאימה)

    צ'או 🙂

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

    אותו שיקול לגבי מילות החיפוש: אפשר אבל מיותר ויעלה בביצועים.

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

סגור לתגובות.