ארכיון יומי: 8 נובמבר, 2009

תשובה לחידה

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

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

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

הערך הקודם פלוס הערך הקודם ושומרת אותו ב sequence בתור הערך הבא. כל זה, כל עוד הערך הוא לא 0 או ריק, כי אז הsequence מכיל את הערך 1.

התוצאה הסופית היא סדרה כזו: 1, 2, 4, 8, 16, 32, 64, 128, 512, 1024 … (דיברתי על 10 הערכים הראשונים).

הפעולה מתבצעת כאמור על ידי פעולת חיבור ולא כפל או חזקה (דיאגו).

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

השימוש ב GEN_ID מספק את הדרך היחידה לגשת ל sequence בגלל שהsequnce חייב להיות מוגן מפני שינויים רנדומליים ורק שינויים שהתכוונו אליהם חייבים להתבצע בצורה שהיא transaction safe, כך שכל טרנזאקציה תוכל לספק ערך חד חד ערכי בלי קשר לשאר החיבורים והטרנזאקציות האחרות בנושא. זו אחת מהדרישות של מבחן ה ACID עבור מסדי נתונים, וכאמור Firebird עובר בציון של 100 את המבחן. הפונקציה ד"א מעלה את הערך של ה sequence בכמות שאנחנו מספקים לה בפרמטר השני, כך שאם הערך הוא 0, זה בסה"כ מחזיר את הערך של sequence ולא מבצע פעולת חיבור.

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