אני לא הספקתי לעבור מקודם על כל התגובות כאן, משון מה זה נתקע לי, כנראה בגלל שהעבירו את נושא לפורום אקסקלוסיבי.
כעת אני רואה את כל השרשור
כבר לפני כמה שעות השלמתי את הפיתוח של סיסמא הנ"ל (שהתיישבתי עליו מיד אתמול לאחר החסימה הזמנית, רק שפשוט נרדמתי על ההגה..).
אני מחכה שאליהו יעבור על השינויים שעשיתי ויעדכן את הקבצים בשרת שלו..
למזלי הוא בהפסקת חשמל כבר כמה שעות..
מיד הבנתי שזה לטובתי, ס"ה כמה שיותר אבטחה הוא ודאי הכרחי, אין ספק
חוקר
-
ישיבה על קברו, בלי סיסמא? -
ניהול קאש למאות קריאות במקביל@nigun אמר בניהול קאש למאות קריאות במקביל:
[200] 19968 responses
רק שים לב, 32 מתוך 20000 בקשות נכשלו..
-
איטיות ב SUM ב MYSQL@יוס אמר באיטיות ב SUM ב MYSQL:
ממש תודה אכן "טס" במהירות
אבל עשית גם אינדקס או שזה עוד לפני האינדקס?
-
סליקה ישירות מהאתר@ש-ב-ח
מי ספק הסליקה שלך? או שעדיין אין לך? (א"כ הייתי ממליץ על נדרים פלוס, אני משתמש איתו ומאוד מרוצה).
יש לו API? אולי יש לו גם איפריימים או רדיירקטים.
איך אתה מתכנן לבצע את הסליקה מול השרת? -
ריענון נתונים בממשק צפיהיש לי מערכת טלפונית לרישום נקרא לזה "תורים"
נרשמים במערכת ובוחרים את השעה המבוקשת מתוך טבלת התורים.
במערכת נוצר כל יום רשימת תורים על פי הגדרות, וכאשר לקוח מתקשר הוא יכול לבחור תור פנוי מרשימת התורים.
בשטח, יש דלפק בו נמצא נציג המקבל את הבאים וכאשר מגיעים לשטח מזדהים באמצעות הזיהוי והנציג רואה למתי הוזמן ומעדכן על התור אישור הגעה ו/או מעדכן באם שולם או לא התור הנוכחי.
המערכת הטלפונית היא באמצעות (ימות המשיח עם שלוחת API המחוברת לשרת שלי הכתוב) בנוד.
ממשק הניהול הינו בפרימוורק YII2 הכתוב בPHP.
בסיס הנתונים הינו mysql, השרת הינו nginx.
כל רישום במערכת הטלפונית נשמרת ישירות בבסיס הנתונים, ובמקביל גם בתהליך עצמו בנוד.
ממשק הניהול שואב את הנתונים ישירות מבסיס הנתונים.
השאלות הן בנוגע לממשק הניהול.
יש לי כבר בממשק תצוגה שמציגה את טבלת הרישום.
אך הבעיה היא שאני צריך שהמסך יתעדכן כל הזמן בנתונים הדינאמיים של הרישום, זאת אומרת שאם כעת נרשם מישהו במערכת או ביטל ושינה תור וכו' הכל ישתקף אונליין במסך הממשק.
למיטב הבנתי ישנם שתי דרכים, א. ריענון אוטומטי של הדף כל X שניות, שזה אומר שהPHP ישאב שוב את הנתונים מבסיס הנתונים וירנדר את ה HTML שוב שוב.
אני לא צריך לטעון ממש את כל הדף, אלא YII2 תומך ב pjax שזה ריענון אוטומטי של רק חלק מסויים בדף. שזה אומר לרענן רק את החלק של הטבלה של התורים ללא התפריט העליון, כך שזה פחות מפריע לעין.
אך עדיין דורש כל פעם שאיבת הנתונים המלאים, ויכול גם להפריע לביצוע פעולות על תור. כגון אם הנציג ירצה לבצע שמירה ידנית של תור ותוך כדי מישהו נרשם לתור זה דרך הטלפון וכדומה, (אני בכל מקרה יעשה ולידאציה בצד השרת לפני שמירת תור ידני שאני בודק שהוא אכן עדיין פנוי, אבל בכל זאת לצד הלקוח הייתי רוצה שזה מיד יעודכן כנרשם ויתבטל האפשרות של שמירה ידנית).
האמת היא שאני יכול אולי גם לבדוק אפשרות של ריענון על ידי שאיבת json בלבד של הטבלה העדכנית, ולבצע מיזוג מחדש לתוך הטבלה, או יותר מזאת לעבור שורה שורה ולבצע השוואה ובאם השתנה משהו מהקיים זה יעדכן אותו ואחרת לא ישנה אותו כלל, שזה הכי פחות יפריע לעין.
הדרך השניה שאף פעם לא נגעתי בה הינה באמצעות סוקט, שהדף יהיה מחובר כל הזמן לשרת ובכל שינוי בשרת אני דוחף אותו ישירות לקליינט.
אשמח לדעת מה חוות דעתכם, ראשית אם יש פיתרון יותר טוב, שנית האם לעבוד עם סוקט הוא קל או קשה, ומה קורה כאשר החיבור נופל לרגע וכו', עד כמה עבודה ובלאגן יהיה לי מזה.
בנוסף, מעניין לעניין באותו עניין, בעת רישום ידני, על הנציג לבחור את המנוי מתוך טבלת המנויים, לצורך כך עלי לפתוח לו חלון בחירת מנוי, שהוא יכול לחפשו בקלות בכל אחד מהפרטים, כגון שם או טלפון או מספר זהות וכדומה, חשבתי לטעון לו את הכל לחלונית בחירה שיהיה בה טבלה קטנה מבוססת datatable.
השאלה היא איך אני יכול לגרום שגם אם נרשם כעת מנוי חדש למערכת (לא לתור, אלא למינוי), זה יתווסף אוטומטי לטבלה השמורה בזכרון, והאם זה בכלל יעיל לשמור בזכרון של הדף טבלת מנויים, שיכול להגיע לכמה אלפי מנויים לסניף, אלא עדיף תמיד לבצע חיפוש בצד שרת בלבד, אך מסיר את הדינאמיות והקלילות של החיפוש בטבלה על ידי datatable.
סליחה על האריכות אך @dovid אוהב לקבל סיפור מלא (מקוה שכך הכל ברור).
אשמח לקבל את חוות דעתכם -
שליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות@dovid אמר בשליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות:
return {'next' : normalizedTimes[nearestIndex - 1], 'previous' : normalizedTimes[nearestIndex]};
אם אני צודק זה אמור להיות הפוך:
return {'previous' : normalizedTimes[nearestIndex - 1], 'next' : normalizedTimes[nearestIndex]};
תקן אותי אם אני טועה
-
שליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות@dovid
רק תיקון קטן בשורה השניהif (nearestIndex === 0) return {'next' : normalizedTimes[0]};
-
שליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות@dovid אמר בשליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות:
הקוד שלך היינו שורות 10-14 הם בדיוק הדרך בה הייתי כותב,
קוד זה אינו מספיק בכדי לקבל את השעה הקודמת והבאה כשהוא מבקש שעה שהיא בתוך הטווח הנמצא במערך.
לכן אני צריך עדיין את מה ש@yossiz כתב -
json web token vs cookie auth@dovid אמר בjson web token vs cookie auth:
@חוקר במקומות בהם יש API חיצוני זה מאוד נפוץ.
עיקר השאלה זה במקרה שמדובר נטו בממשק דפדפני, כך שקוקויז לכאורה זה הפתרון הטבעי.גם בדשבורד שלהם זה עובד כך.
אך ייתכן מהסיבה שבין כך בנו את ל API -
שליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות@yossiz אמר בשליפת שעה קודמת ומאוחרת של הממצא המבוקש ממערך שעות:
כי אני עצל מדי
אם כן עשית, שמע מינא שאין כאן עצלות
אם כבר אז אני עצל שעיני כמעט ונעצמות, ומספיק אתמול נרדמתי על המחשב.. -
חיפוש ובחירת מופעים של טקסט בIDE@חוקר אמר בחיפוש ובחירת מופעים של טקסט בIDE:
אני רוצה שהוא יסמן לי רק את "לשעה" ואת "הקש"
למעשה זה לא בדיוק כי אני רואה שלפעמים מופיע כיתוב בעברית בלי ה f- ואני כן צריך גם אותם, לכן הלינק שלעיל כבר מספיק לי
תודה
אגב איך מצאת את זה? -
דירוג בקשות לפיתוח מלקוחותאני מחפש דרך שהלקוחות יוכלו להוסיף לי בקשות לפיתוח, וכן יוכלו לדרג את הצורך שלהם בפיתוח.
למשל במערכות הלמידה מרחוק, יש לי ב"ה עשרות לקוחות, ואני מחפש ליעל ולשדרג לנוחיתם, רק לא תמיד אני יודע נכון את הצרכים מה באמת חשוב/חסר להם, ומצד שני שיוכלו לבקש פיתוחים, וכל אחד ידרג עד כמה חשוב לו כל רעיון שהוצע
ואלי אפילו להוסיף נקודה האם מוכן לשלם עלות פיתוח במידה ונדרש
אציין שעדיף משהו שאוכל להטמיע בממשק שלי שהוא מבוסס YII2 שנכתב בPHP.
אך גם משהו שנכתב בנוד יעזור.
אם אם יש פלטפורמה מיוחדת לצורך מסוג זה.
נכנסתי לרחרח ברשת אך לא הגעתי למשהו.
תודה -
js throw false@dovid
יש לך עמדה בנושא? -
js throw false@yossiz אמר בjs throw false:
(סתם הערה, בצורה שבה כתבת פונקציית read מחוץ לפונקציה שקורא לה, יוצא ש-res הוא undefined)
צודק
אני העתקתי מהפוסט הישן קטע קוד ורק רציתי להדגיש שהפונקציה של read היא מחוץ לקטע הקוד של הrouter
ועליה לעצור את המשך הקוד שנמצא בתוך הrouter
. ולכן הוצאתי אותה אל החוץ. -
איך לשמור JSON שנשלח אלי ב POST ב PHP כאשר אני לא יודע איזה ערכים אמורים להשלח אלי@nigun אמר באיך לשמור JSON שנשלח אלי ב POST ב PHP כאשר אני לא יודע איזה ערכים אמורים להשלח אלי:
(זה טוב לדעת כי לפעמים שורפים הרבה זמן על המשחק של ההאדרים)
אכן זה מה שהיה..
-
איך לשמור JSON שנשלח אלי ב POST ב PHP כאשר אני לא יודע איזה ערכים אמורים להשלח אלי@יוס אמר באיך לשמור JSON שנשלח אלי ב POST ב PHP כאשר אני לא יודע איזה ערכים אמורים להשלח אלי:
אבל איך אני יכול לתפוס את הערכים שהם שולחים לי
לנוחיותך, כתבתי הערה ליד כל שורה מה זה
https://tchumim.com/post/106225 -
שדרוג mySQL מגרסה 5.7 ל 8לבסוף בוצע השדרוג כמופיע כאן.
https://tchumim.com/post/105759 -
mysql יצירת עמודה עבור ID שניתן להסתדר בלעדיו@yossiz
נראה שיש באמת שינוי משמעותי לאחר סידור האינדקסים כפי שכתבת למעלה.
להלן השוואה:
עבור שאילתה:EXPLAIN ANALYZE SELECT * FROM (SELECT * FROM `Pupils` WHERE `ProjectID` LIKE 'tifertMoshe') AS Pupils LEFT JOIN (SELECT `EnterId` , MAX(IF(`EnterDate` = CURRENT_DATE ,co,0)) AS 'day_co', MAX(IF(`EnterDate` = CURRENT_DATE,SEC_TO_TIME(CONVERT(su, SIGNED)),0)) AS 'day_su' ,MAX(IF(`EnterDate` = DATE_SUB(CURRENT_DATE,INTERVAL 1 DAY) ,co,0)) AS 'Yesterday_co', MAX(IF(`EnterDate` = DATE_SUB(CURRENT_DATE,INTERVAL 1 DAY),SEC_TO_TIME(CONVERT(su, SIGNED)),0)) AS 'Yesterday_su' , MAX(IF(YEARWEEK(`EnterDate`, 1) = YEARWEEK(CURRENT_DATE, 1) ,co,0)) AS 'week_co', MAX(IF(YEARWEEK(`EnterDate`, 1) = YEARWEEK(CURRENT_DATE, 1),SEC_TO_TIME(CONVERT(su, SIGNED)),0)) AS 'week_su' , MAX(IF(YEARWEEK(`EnterDate`, 1) = YEARWEEK(DATE_SUB(CURRENT_DATE,INTERVAL 7 DAY), 1) ,co,0)) AS 'lest_week_co', MAX(IF(YEARWEEK(`EnterDate`, 1) = YEARWEEK(DATE_SUB(CURRENT_DATE,INTERVAL 7 DAY), 1),SEC_TO_TIME(CONVERT(su, SIGNED)),0)) AS 'lest_week_su' , MAX(IF(MONTH(`EnterDate`) = MONTH(CURRENT_DATE) ,co,0)) AS 'month_co', MAX(IF(MONTH(`EnterDate`) = MONTH(CURRENT_DATE),SEC_TO_TIME(CONVERT(su, SIGNED)),0)) AS 'month_su' , MAX(IF(MONTH(`EnterDate`) = MONTH(DATE_SUB(CURRENT_DATE,INTERVAL 1 MONTH)) ,co,0)) AS 'lest_month_co', MAX(IF(MONTH(`EnterDate`) = MONTH(DATE_SUB(CURRENT_DATE,INTERVAL 1 MONTH)),SEC_TO_TIME(CONVERT(su, SIGNED)),0)) AS 'lest_month_su' , MAX(co) AS all_co , SEC_TO_TIME(CONVERT(SUM(su), SIGNED)) AS all_su FROM (SELECT `EnterId`, COUNT(`id`) AS co, SUM(`TimeTotal`) AS su, `EnterDate` FROM `LogPlaybackPlayStop` WHERE `ProjectID` LIKE 'tifertMoshe' GROUP BY `EnterId`, `EnterDate`) AS t1 GROUP BY EnterId) AS t2 ON `Pupils`.`user_id` = `t2`.EnterId ORDER BY `class`, `Family`, `name`
בטבלה המקורית לקח הביצוע 2.651 שניות
וזה התוצאה-> Nested loop left join (actual time=2565.828..2568.774 rows=716 loops=1) -> Sort: Pupils.class, Pupils.Family, Pupils.`name` (cost=812.76 rows=716) (actual time=9.546..9.867 rows=716 loops=1) -> Index range scan on Pupils using ProjectID, with index condition: (Pupils.ProjectID like 'tifertMoshe') (actual time=0.423..4.044 rows=716 loops=1) -> Filter: (Pupils.user_id = t2.EnterId) (actual time=3.573..3.574 rows=1 loops=716) -> Index lookup on t2 using <auto_key0> (EnterId=Pupils.user_id) (actual time=0.002..0.002 rows=1 loops=716) -> Materialize (actual time=3.573..3.573 rows=1 loops=716) -> Table scan on <temporary> (actual time=0.001..0.513 rows=666 loops=1) -> Aggregate using temporary table (actual time=2553.656..2554.225 rows=666 loops=1) -> Table scan on t1 (actual time=0.002..3.429 rows=16831 loops=1) -> Materialize (actual time=2454.324..2459.523 rows=16831 loops=1) -> Table scan on <temporary> (actual time=0.002..5.742 rows=16831 loops=1) -> Aggregate using temporary table (actual time=2437.997..2445.624 rows=16831 loops=1) -> Index range scan on LogPlaybackPlayStop using ProjectID, with index condition: (LogPlaybackPlayStop.ProjectID like 'tifertMoshe') (cost=717075.83 rows=641706) (actual time=138.827..1616.996 rows=354415 loops=1)
בטבלה שבה סידרתי את האינדקסים כפי שכתבת:
זמן ביצוע לקח 2.079
והתוצאה-> Nested loop left join (actual time=1946.354..1956.694 rows=716 loops=1) -> Sort: Pupils.class, Pupils.Family, Pupils.`name` (cost=812.76 rows=716) (actual time=5.865..6.479 rows=716 loops=1) -> Index range scan on Pupils using ProjectID, with index condition: (Pupils.ProjectID like 'tifertMoshe') (actual time=0.252..1.879 rows=716 loops=1) -> Filter: (Pupils.user_id = t2.EnterId) (actual time=2.718..2.721 rows=1 loops=716) -> Index lookup on t2 using <auto_key0> (EnterId=Pupils.user_id) (actual time=0.003..0.003 rows=1 loops=716) -> Materialize (actual time=2.715..2.717 rows=1 loops=716) -> Table scan on <temporary> (actual time=0.002..0.549 rows=666 loops=1) -> Aggregate using temporary table (actual time=1937.403..1938.763 rows=666 loops=1) -> Table scan on t1 (actual time=0.002..11.759 rows=16831 loops=1) -> Materialize (actual time=1842.499..1875.116 rows=16831 loops=1) -> Table scan on <temporary> (actual time=0.002..13.555 rows=16831 loops=1) -> Aggregate using temporary table (actual time=1793.238..1827.118 rows=16831 loops=1) -> Index range scan on LogPlaybackPlayStop using ProjectID, with index condition: (LogPlaybackPlayStop.ProjectID like 'tifertMoshe') (cost=838658.37 rows=733932) (actual time=79.989..1189.331 rows=354415 loops=1)
ולמען האמת מהשאילתה עם EXPLAIN ANALYZE אני עדיין לא כ"כ מבין את הלוגים, אבל בהרצת השאילתה עצמה ושליפת התוצאות אני רואה:
בטבלה המקורית 2.686
בטבלה לאחר השינוי 1.510 -
mysql יצירת עמודה עבור ID שניתן להסתדר בלעדיו@yossiz
ההתחלה שלך.. אך עם לימוד יסודי..
אני צריך לעבור יותר בעיון על הכל, אך משהו אחד אני כן מבין כאן גם מלמעלה.
שאם תמיד אני משתמש בסינון של פרוייקט ובנוסף את הסינונים האחרים, אז אינדקס על כל עמודה בנפרד הוא לא נכון, אלא עלי לעשות אינדקס על כל עמודה רק יחד עם העמודה של הפרוייקט?
בנוסף אציין שבשאילתה לעיל הסינון של עמודת התאריך ועמודת השעה הינה רק בשביל המיון לפי תאריך.
זה אומר משהו? -
mysql יצירת עמודה עבור ID שניתן להסתדר בלעדיו@חוקר אמר בmysql יצירת עמודה עבור ID שניתן להסתדר בלעדיו:
EXPLAIN ANALYZE SELECT COUNT(*) FROM
LogPlaybackPlayStop
WHEREProjectID
= 'tifertMoshe'כהמשך לנסיונות
יצרתי שרת אחר שם מחקתי את העמודה של ID ועשיתי את המפתח הראשי מורכב מ פרוייקט+תאריך+שעה.
ולהלן התוצאות:
שאילתהEXPLAIN ANALYZE SELECT COUNT(*) FROM `LogPlaybackPlayStop` WHERE `ProjectID` = 'tifertMoshe'
תוצאה
-> Aggregate: count(0) (actual time=562.230..562.231 rows=1 loops=1) -> Index lookup on LogPlaybackPlayStop using ProjectID (ProjectID='tifertMoshe') (cost=78749.48 rows=698936) (actual time=0.048..336.836 rows=354415 loops=1)
השאילתה צרכה 53 אחוז CPU.
שאילתה
EXPLAIN ANALYZE SELECT * FROM `LogPlaybackPlayStop` WHERE `ProjectID` = 'tifertMoshe' ORDER BY `EnterDate` DESC, `EnterTime` DESC LIMIT 2000
התוצאה
-> Limit: 2000 row(s) (actual time=2140.300..2144.361 rows=2000 loops=1) -> Sort: LogPlaybackPlayStop.EnterDate DESC, LogPlaybackPlayStop.EnterTime DESC, limit input to 2000 row(s) per chunk (cost=428549.39 rows=698936) (actual time=2140.295..2141.907 rows=2000 loops=1) -> Index lookup on LogPlaybackPlayStop using ProjectID (ProjectID='tifertMoshe') (actual time=0.964..1718.924 rows=354415 loops=1)
צרך 97.2 אחוז CPU.
@yossiz
כעת נותר לפנח לי את התוצאות מה הן אומרות בהשוואה לטבלה בה יש מפתח ראשי ID