RSS 1.0 FEED Powered by GM-RSS ארכיון האתר בטל רישום כתוב אלינו משאבי הפריק רישום לאיגרת פורום מייקרוסופט פורום הפריק מי אנחנו דף הבית

פיתוח בסיסי נתונים על פוקט פיסי - הקדמה
Amir - 21/12/2003
 

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

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

להמשך הקריאה אנא הכנסו לכתבה המלאה...


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


בסיס נתונים הינו מאגר מידע שיכול להגיע למימדים עצומים ומכיל נתונים רבים ומגוונים. בדרך-כלל כשנרצה לאחסן מספר נתונים מצומצם, נשתמש במבנה הנתונים של שפת התכנות בה אנו עובדים. זה יכול להתחיל ממערכים פשוטים ולהגיע עד לרשימות מקושרות, עצים בינאריים וטבלאות Hash. אולם ברגע שהנתונים מתחילים להתנפח במידה משמעותית, הזכרון הדרוש כדי לנהל את מבני הנתונים הללו מתחיל לאזול. אותו המצב קורה גם על מחשב PC משוכלל. הסיבה לכך היא שמבנה הנתונים כולו נטען לזכרון וככל שיש בו יותר נתונים כך הוא דורש יותר זכרון ומשאבי מערכת.
הפתרון לבעיה הזו מגיע משני כיוונים - האחד הוא שימוש במבנה נתונים חדש שאנו ניצור בעצמנו ויטפל בניהול הזכרון בצורה יעילה כך שכל פעם חלק אחר מהנתונים יטען לזכרון המערכת.
הפתרון השני והגורף הוא שימוש במערכת לבסיסי נתונים מוכנה מראש. עבור ה-PC אנו יכולים לראות מספר פתרונות ובינהם Microsoft Access, MS SQL Server, ORACLE ועוד. כל המערכות הללו משתמשות במה שנקרא - Relational Database או בסיס נתונים יחסי.

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

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

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

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

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

כעת בואו נניח שלכל משתמש באתר יכולים להיות שלושה מכשירי טלפון. במקרה כזה אנו יכולים להוסיף עוד שני שדות שיקראו טלפון 1, טלפון 2, טלפון 3. ובכך לפתור את הבעיה.
הפתרון שהוצג כאן, במידה ויהיו הרבה מאד משתמשים באתר, עלול לנפח את הטבלה באחוזים רבים ובכך לגרום לאיטיות ולתפיסת מקום רב יותר באחסון. תחשבו שלכל רשומה אנו מוסיפים עוד שני שדות. נניח שיש 100,000 רשומות - הוספנו 200,000 משבצות ריקות. בהנחה שרק ל-300 משתמשים יש טלפון נוסף, בזבזנו כאן למעלה מ- 190,000 מקומות וזמן יקר בחיפוש אחר הנתונים האמיתיים בטבלה.

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

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

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

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

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

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

מספור אוטומטי נמצא כמעט בכל בסיס נתונים וזהו שדה מיוחד שמתעדכן באופן אוטומטי בכל הזנת רשומה חדשה. לדוגמה - אם נרשם משתמש חדש, נפתח רשומה חדשה בטבלת המשתמשים והשדה המזהה (המספור האוטומטי) מייד יתמלא ע"י המערכת כמספר האחרון + 1 מעבר למה שהוזן למשתמש הקודם. בדר"כ זה מתחיל מ-1 , 2 , 3... וכו'.

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

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

השדות בטבלת הטלפונים יהיו: זיהוי, טלפון.

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

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

דוגמה:

טבלת משתמשים:
1. משה, כהן, ללא מייל, 5 הודעות
2. ישראל, לוי, ללא מייל, 7 הודעות
3. רמי, דותן, ללא מייל, 20 הודעות

טבלת טלפונים:
2, 03-5551234
2, 03-5401234
1, 054-555555

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

בתמונה ניתן לראות המחשה של הטבלאות בצורה גראפית:

Freak-Table (29k image)

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

כעת אני אדבר בקצרה על נושא השאילתות. נשלח שאילתה אל בסיס-נתונים כאשר נרצה לקבל תשובה מוגדרת לגבי הנתונים שמאוחסנים בו. למשל, אם נרצה לראות את כל המשתמשים באתר פוקט פיסי פריק. אם נרצה לראות את רשימת הטלפונים של משתמש מסויים. אם נרצה לראות כמה משתמשים שלחו למעלה ממספר הודעות מסויים וכו'. את השאילתה נוכל לבנות באמצעות אשף בסביבה גראפית כמו שמתאפשר במספר סביבות פיתוח של מסדי נתונים, לדוגמה: MS Access, או בצורה טקסטואלית בעזרת שפה מיוחדת שנקראת SQL (נהוג לבטא את המילה כמו - sequel). את הצורה הגראפית אני לא מתכוון לתאר, במיוחד בגלל שזוהי שיטה מאד פשוטה שמשתנה בין סביבות הפיתוח במידת מה.

שאילתות לדוגמה בשפת SQL:


SELECT *
FROM Freak_Users

SELECT id, first_name, last_name, email
FROM Freak_Users

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

שאילתות מתקדמות יותר יכולות להיות:


SELECT id, first_name, last_name, email
FROM Freak_Users
WHERE first_name ="Moshe"

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

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

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


SELECT Freak_Users.id, first_name, last_name, phone
FROM Freak_Users, Freak_Phones
WHERE Freak_Users.id = Freak_Phones.id

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

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

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

1) שטח אחסון.
2) יכולות תקשורת.

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

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

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

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

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

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

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

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

לבסוף, עלינו להחליט כיצד לשמור את הנתונים בתוך מחשב כף-היד. זה יכול להיות במספר צורות והעיקריות הן:
1) בקובץ cdb שמקביל לקובץ mdb על המחשב השולחני.
2) באמצעות קבצי XML שנמצאים בשימוש בעיקר בארכיטקטורת .NET CF
3) בעזרת SQL Server CE שהוא שרת בסיסי-נתונים מורכב שמותקן על מחשב כף-היד. תוכנה זו מקבילה ל-SQL Server עבור המחשב השולחני.

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

בכתבה הבאה אני אתמקד בבסיס הנתונים של Microsoft Access, כיצד הוא מתקשר ל-Pocket Access. מהי ההמרה בין בסיסי הנתונים שמתבצעת בהעברה דרך ActiveSync אל הפוקט מקובץ mdb לקובץ cdb, וכיצד לסנכרן בצורה תכנותית בעזרת ה-API שמגיע מהקובץ adofiltr.dll ועבודה עם ADOCE.

טיפ למתכנתים:
שתי הפונקציות המרכזיות הן:

DEVICETODESKTOP
DESKTOPTODEVICE

מקווה שנהנתם מהכתבה.

תגובות, הערות, תיקונים ותוספות יתקבלו בברכה.

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

אמיר ולדמן
(BlastPPC)
פורום המפתחים
פוקט פיסי פריק

הערות: 2 הערות

תודה על הפידבק :)
נרשם על ידי BlastPPC בתאריך 22/12/2003, בשעה 10:52PM לפי שעון ישראל

ממש תענוג!
מקצועי וברור!!!
נרשם על ידי ade777 בתאריך 21/12/2003, בשעה 04:31PM לפי שעון ישראל

[ הקודם: "VOXIT MAIL - שהפוקט פיסי יקרא לנו את הדואר" ] [לעמוד הראשי] [ הבא: "PPX - תחליף למסך ה-TODAY" ]

Powered By Greymatter





חפש   
חפש באתר עם גוגל   
Google
Web pocketpcfreak.com
חברות התומכות באתר
Onroad
iGo Website
PocketPCNetL (5k image)
Visual CE
Pocket Gear
חפש מוצר באמזון
Search Now:
הגרלות באתר
פרסים ומעמדים
Helio Diamant and Saar Avigour are Microsoft MVPs
אתרים חברים
Pocket PC Thoughts
Pocket PC Writer Net