LAST_INSERT_ID() | mysql_insert_id

coolel

New member
LAST_INSERT_ID() | mysql_insert_id

ממה שהבנתי LAST_INSERT_ID() היא נשמרת פר-קונקשיין(per-connection) מה שאומר שאם מישהו יוסיף רשומה חדשה תוך כדי הפעולה ואני אבקש את הLAST_INSERT_ID() אני אקבל את הID של הרשומה האחרונה שהעמוד הנוכחי הכניס לא משנה אם הכניסו אחרי זה. זה נכון? אפשר להשתמש בזה בבטחון שאם מישהו יכניס משהו מיד אחרי ההכנסה ולפני שאני משתמש בLAST_INSERT_ID() אני עדיין אקבל את הID של מה שאני הכנסתי ולא של הרשומה שמישהו אחר הכניס תוך כדי? זה אותו סיפור לגבי mysql_insert_id? מה מהם יותר "בטוח"?
 

shanor

New member
מממ....

כן ולא כן ולא. בטוח, כן, כי זה נכון לגבי כל חיבור וחיבור, משמע חיבור אחד הכניס רשומה חדשה, חיבור אחר הכניס במקביל עוד 10 רשומות חדשות, כל אחד מהחיבורים יקבל את הרשומה האחרונה שהוא עצמו הכניס בלי קשר לאחרים. אם אתה רוצה 100 אחוז ביטחון תבצע נעילת טבלאות ל- WRITE לפני שאתה מכניס את הרשומה ושיחרור טבלה אחר כך, ואז אתה מבטיח לעצמך שהתוצאה של LAST_INSERT_ID היא 100% נכונה. אבל זה כמובן בא על חשבון מהירות ויעילות כי לוקח זמן לנעול ולפתוח טבלאות ובאותו הזמן שהטבלה נעולה ב- WRITE שום שאילתה אחרת לא יכולה להתבצע על הטבלה עד שהיא לא תשוחרר. זה בערך אותו הדבר לגבי MYSQL_INSERT_ID פרט לכמה דברים קטנים שחשוב לשים לב אליהם. MYSQL_INSERT_ID היא תוצאה שה- PHP נותנת בהתאם לחיבור (CONNECTION), בעוד ש LAST_INSERT_ID היא תוצאה שניתנת על ידי MYSQL ועל כן צריך להעביר אותה בשאילתה לתוך MYSQL ואז "להוציא" את הנתון מתוך התוצאה. הדבר השני החשוב הוא הגודל שכל אחד מהדברים הללו יכול ליצג, בעוד שMYSQL_INSERT_ID הוא מוגבל ל- INTEGER (אם אני זוכר נכון, אל תתפסו אותי במילה אבל הוא עדיין מוגבל בגודל המקסימלי שלו) בעוד ש- LAST_INSERT_ID יכול להגיע למספרים הרבה יותר גדולים, ככה שכל עוד הטור שהוא AUTO_INCREMENTED, בטווח המספרים של MYSQL_INSER_ID הכל טוב ויפה, אבל אם הוא יותר מזה למשל BIGINT, אז אי אפשר לסמוך על התוצאה הזו וצריך לקבל את התוצאה מ- LAST_INSERT_ID. זהו. מקווה שזה עוזר להבהיר את העיניין. בברכה שנאור.
 

coolel

New member
תודה רבה רבה רבה

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

behemot

New member
לי היה עם זה בלגן בהוספת רשומות -

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

coolel

New member
במה השתמשת?

בזה של הMYSQL או בזה של PHP? ואיך פתרת את הבעיה בסוף?
 

behemot

New member
של הMYSQL - בסוף הרצתי עוד שאילתה

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

coolel

New member
לא הבנתי....

כאילו להוסיף לבדיקה עוד פרמטרים כמו המשתמש ששלח וכו'?
 

behemot

New member
זה מה שאני עשיתי - פשוט אצלי כל

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

coolel

New member
אוקיי נעילת הDB זהו כנראה הפתרון הי

היחיד. שאלות: 1. איך נועלים את הDB? 2. משתמשים שינסו לכתוב לDB כשהוא נעול יחכו עד שהוא ייפתח או יקבלו הודעת שגיאה מה קורה אם מסיבה מסויימת הDB ננעל אך לא נפתח... ? יש אפשרות לפתוח אותו ידנית?
 

shanor

New member
מממ...

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

coolel

New member
איזה דרכים אחרות יש?

הייתי שמח אם תוכל לפרט עליהם...
 

shanor

New member
מממ...

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

coolel

New member
איך מבחינת קוד נועלים את הטבלה ../images/Emo35.gif

איך אני נועל טבלה כדי שלא יוכלו לכתוב בה? ואיך משחררים את הנעילה?
 

shanor

New member
מממ...

לנעילה: lock tables XYZ write או lock tables XYZ read תלוי בסוג הנעילה שאתה צריך. לשיחרור טבלאות: unlock tables למרות שאפשר גם בלי ממש לשחרר טבלה, ברגע שנסגר החיבור (CONNECTION) הטבלאות הנעולות אמורות להפתח - אבל שים לב ל"אמורות"...זה לא תמיד קורה. תקרא על זה יותר בהרחבה בתוך המדריך של MYSQL: www.mysql.com בהצלחה שנאור.
 

coolel

New member
אבל זה לא ינעל גם אותי מכתיבה לטבלה

????????????????????????????????????????
 

shanor

New member
מממ...

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

coolel

New member
אבל כתוב באתר של MYSQL

שהTHREAD שמשתמש בWRITE - רק לו יש אפשרות לקרוא/לכתוב לטבלה אני רוצה לנעול שרק מי שנעל יוכל לכתוב/לקרוא וכל השאר יוכלו לקרוא...
 

shanor

New member
מממ...

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