מתן הייתי מציע שינוי קטן. אני אסביר, אבל קודם
תודה על הרצון לעזור אתמול
בסוף דיברתי עם אסף פרנקל בטלפון וקיבלתי ממנו את כל הפרטים שרציתי ובנוסף גם כמה טיפים חשובים, כך שהיתה שיחה מאוד מועילה.
לגבי ההסבר והשאלה כאן:
אם היינו רוצים לאפשר רק להעלות ברמה אחת אז למעשה הפתרון של מתן יעבוד, אבל זה פתרון מאוד לא יעיל ועל אחת כמה וכמה במקרה שרוצים לאפשר למשתמש להעלות נתון ביותר מרמה אחת למעלה.
למשל אם רוצים להעלות את Song3 למיקום הראשון. האם נעלה אותו למיקום 1 ונעביר את Song2 למיקום 2 ואז נעביר את Song3 למיקום 0 ונעביר את Song1 למיקום 1?
זה יעבוד, אבל זה מאוד לא יעיל ולא מומלץ! אלו ארבע פעולות UPDATE יקרות מאוד. דרך יותר טובה יהיה להעביר למקום הסופי ולהוסיף 1 לכל נתון שהמקום שלו בין המיקום הסופי או שווה לו ובין המיקום של הרשומה שרוצים להעביר. לפחות ככה זו פעולת עדכון אחת. עדיין מדובר על נעילות מסוג X יקרות מאוד והמתנה עד לסיום כל הפעולות (כפי שהסביר מתן חייבים לעבוד תחת טרנזקציה אחת כדי להבטיח: הכל או לא כלום)
אז מה כן? הדרך הנכונה היא לתכנן את מסד נתונים בצורה יותר נכונה
תכנון לא נכון מראש תמיד עולה לנו במשאבים ובעבודה מיותרת בהמשך! עצם העובדה שזה מבנה הנתונים שלנו מצביע על בעיה. יש כמה מבנים יותר יעילים של DDL למטרות שמוצגות כאן כניראה, אבל רק לשם הפשטות אני אציג פתרון קל מאוד (קל אינטואטיבית להבנה ולא מבחינת מיטוב או משאבים) ו
בנוסף ייתן לנו סדרי גודל של מיטוב ביחס לקיים (שוב אני אומר שזה לא הפתרון המיטבי אלא ה"מספיק טוב" כך שגם יהיה לי קל להסביר בפורום)
הרעיון הוא פשוט לעבור לטור מסוג decimal, ולהתבסס על הכלל במתמטיקה שבין כל 2 מספרים שונים אפשר למצוא מספר שנמצא בינם ושונה מהם. זה כמובן לא נכון במקרה של מספרים שלמים אבל במקרה הכללי זה נכון. יש לזכור שבגלל מגבלת העיגול ספרות הרי שגם בשימוש ב decimal יכול להיות מצב שהכלל לא יתקיים אבל מצב זה נדיר מאוד ויקרה רק אחרי הרבה מאוד פעולות (מליארדים ככל הנראה) של הקפצת שורה.
הביצוע: אם רוצים להעלות את Song4 להיות בין Song1 לבין Song2 אז
צריך לעדכן רק רשומה אחת במסד הנתונים. את הרשומה של Song4. פשוט נותנים לה את המיקום של Song1 + המיקום של Song2 לחלק ל 2 (ז"א במקרה שלנו בפעם הראשנה פשוט ניתן ל Song4 את המיקום 0.5 וראו איזה פלא הרשומה קופצת למקום המתאים מייד
)
* הדבר היחיד שחשוב לוודא לפני הפעולה זה שהמיקום שאנו רוצים לקבוע (במקרה שלנו 0.5 ז"א התוצאה של חישוב המיקום החדש) לא שווה למיקום של הרשומה מעל או מתחת. זה מכסה את הבעיה שנוצרת בגלל עיגול ספרות.
למשל אם בחרנו לעבוד עם טור המוגדר כסוג decimal(38,17) ואנחנו רוצים להכניס רשומה בין מיקום
12345678901234567890.123456789012345677
למיקום
12345678901234567890.123456789012345678
אז לא נוכל מכיוון ששני נתונים אלו מעוגלים לאותו מספר בהגדרת הטור שלנו.
** יש הרבה נקודות חשובות לדון בהן ודרכים לפעול בכל מצב, ש חשיבות להגדרת הטור שלנו כמובן כפי שראינו זה משפיע על אופן העבודה אבל מצד שני זה משפיע על מיקום ועוד הרבה... אבל זו הדרך הבסיסית המתאימה יותר (ועדיין אינה המיטבית אם כי הכי פשוטה)
*** כל מקרה לגופו כמובן וישנם מצבים בו נבחר אפילו לעבוד עם ה DDL הקיים בעוד באחרים יתאים הדרך שתיארתי כן ובעוד מצבים תתאים דרך אחרת, כמו התבססות על טבלה מקושרת או שימוש בטור בינארי או אפילו טור גיאומטרי... לכתוב הכל ייקח לי כמה ימים אז נישאר עם הבסיס: תמיד תתכננו נכון את המערכת שלכם לפני שמתחילים לחפש דרכים לפתור בעיות שלא היו אמורות להיות בתכנון נכון