2018-07-19

כיצד לצמצם פוליטיקה ארגונית? (מבלי לעבוד לבד)


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

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

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

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

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







האם ניתן להימנע מפוליטיקה ארגונית?


פוליטיקה היא עניין מאוד סובייקטיבי - עניין של תפיסת המציאות.

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

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

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

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

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

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

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

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

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


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






כיצד לתמרץ פוליטיקה ארגונית


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


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


אין משמרות

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

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

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

הנזק מהחלטה נקודתית ותמימה לכאורה - היה עמוק ומתמשך.

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

לכאורה, זו תגובה "פרגמטית" ללא כוונות זדון / ללא רצון להעדפת עובד כזה או אחר. "זה נכפה עלינו".

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



The Chosen

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

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

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

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

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

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

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







הפרד ומשול

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

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

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

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

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


לקדם את טוראי ראיין

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

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

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

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

נשמע win-win, לא?

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

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


דוגמאות קצרות אחרות ששווה להזכיר:
  • מנהל שלא מספק קרדיט לעובדיו. שמו מתנוסס על פרויקטים, עליהם בקושי השפיע. 
    • גם ההתנהגות (הרעה) הזו - היא מודל לחיקוי.
  • מנהל שלא "מרגיע" עובדים סופר-תחרותיים, המתייחסים לעובדים אחרים בזילזול, או עובדים מרירים שלא מפסיקים להתלונן ולעקוץ עובדים אחרים.
    • לפעמים העובד ה"קשה" יהיה ביצועיסט מצויין - ויהיה קשה לאמוד את מידת הנזק הסביבתי שההתנהגות שלו, ובעיקר: קבלת ההתנהגות שלו - גורמת.
    • התפרסמו בשנים האחרונות תוצאות מחקרים שהראו שקיום יריבות מתמשכת בצוות, ותחושת אי-ביטחון לעשות שגיאות ולטעות - היא מנבא מוצלח למדי לאי-הצלחה של ארגון.
      למשל: Google on Psychological Safety
  • וריאציה נוספת: קליקות מזיקות
    חברויות עמוקות בצוות הן דבר מבורך, אך לעתים נוצרות "קליקות" שלא מקבלות אחרים: חבורת מפתחים ותיקים שעבדו ביחד בחברה קודמת, מפתחים מול QA, צוות דוברי רוסית שמשתמשים ברוסית גם מול חבר צוות שאינו יודע את השפה, וכו'.
    • ברגע שהקליקה מאיימת ודוחה עובדים אחרים - אותם עובדים יחפשו קליקה אחרת להאחז בה, מה שעלול להוביל ליריבויות קבוצתיות בחברה. בהחלט לא דבר מועיל.





ואם רוצים בכל זאת, דווקא - לצמצם את הפוליטיקה?


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

עניין ההוגנות היא עניין בסיסי ביותר. זה אפילו לא עניין אנושי, אלא עניין של בעלי חיים נבונים.

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

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



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

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

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


לשמור על הוגנות גבוהה זה לא קל. הנה דוגמאות - ומחירים:
  • עובד מצוין מקבל הצעת שכר עדיפה ממקום עבודה אחר? תשמרו אותו (ותפגעו במדרג הוגן של המשכורות) - או תתנו לו ללכת עם כל הכאב שבענין?
    • כאב נלווה: עובדים אחרים שהמוראל שלהם יפגע מעזיבת העובד המצוין ("פעם היו פה עובדים....")
    • ייתכן ותפספסו Deliveries. יש עובדים שעזיבתם עושה זאת. לפספס Deliveries - זה אף פעם לא נעים.
  • עובד "לוחץ" לקבל קידום? האם שתקפו לו את המצב "דוגרי", או תסתובבו סביב?
    • הרבה יותר קל "לנסות", "לתת לו מפת-דרכים להגיע לתפקיד בעתיד" (אצל המנהל הבא), או לשתף פעולה עם השאיפות שלו שאינן בהכרח מציאותיות.
    • "לנסות" את התפקיד הוא בהחלט לא מודל רע - הוא דווקא עשוי להיות טוב מאוד. הבעיה היא כאשר אתם גוררים ודוחים את הפידבק השלילי כאשר זה לא מצליח (מירב הפעמים). "למה לאכזב בחור טוב שרוצה כ"כ?", "ככה להרוס חלום במו ידי?"
  • שינויים ארגוניים, והעלות שכר הם תמיד "חומר נפץ" פוליטי.
    • האם תצליחו לעשות את התהליכים בצורה הוגנת ושקופה, או תעדיפו ל"סיים מהר" את התקופה הלחוצה? (שאיפה ברורה ומובנת).
    • כמה "ג'ובים" תחלקו כדי להרגיע עובדים ממורמרים, שסה"כ אתם רוצים שישארו, בלי להקשות עליכם יותר מידי? כשיש הרבה טרדות על הראש (תמיד יש) - קידום עובד מתוסכל ל"תפקיד לא מזיק" יכול לספק לכם רגע של נחת.
      • הנזק כאן יקרה - אם בעיני עובדים אחרים זה קידום לא מוצדק. "מה הוא עשה בכדי לקבל את התפקיד הנוח הזה? אני רוצה גם!".
    • מנהלים שאפתניים שחותרים בלי סוף להרחבת תחומי-אחריותם הוא גם נושא קשה. הם ינסו "לתפוס" אתכם בהבטחות - שאח"כ תצטרכו לקיים, גם אם זה לא משרת בצורה מיטבית את צרכי הארגון.
  • עובדים הבאים בביקורת זה כלפי זה. אין לכם כוח וזמן - אבל דורשים מכם לעסוק בנושא.
    • כמה קל להגיע למסקנה חפוזה - ו"להוריד את הקוף מהגב".
    • קשה להבין את הנושאים לעומק (אולי לא כדאי), וגם קשה להבין אם יש מולכם עובד גרוע, או עובד תוקפן.
      אני מניח שאת המינימום הזה (מקרי הקיצון) עליכם להבין - ואחרת דרשו מהם להתאמץ, ולהסתדר בכוחות עצמם.

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

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

Self < Team < Organization


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

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

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

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

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



סיכום


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

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

כמו בסיפור של עוץ לי גוץ לי - החוב סופו להיפרע.  [1]

שיהיה בהצלחה!



----

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



2018-07-08

נושאים מתקדמים ב MySQL: חלק ב' - Generated columns ו json_each

פוסט נוסף לקבוצת הפוסטים בנושא MySQL:

"תסביר לי" - גרסת ה SQL
לקחת את הביצועים ברצינות, בעזרת MySQL Performance Schema
נושאים מתקדמים ב MySQL: חלק א' - עבודה עם JSON



בפוסט הקודם דיברנו על שימוש ב json column ב MySQL.

אחת המגבלות הגדולות של שדות json הם מהירות החיפוש בהם:
  • אם השדות שמורים כ json - יש לקרוא את ה json כולו מהדיסק לזיכרון - על מנת לשלוף ערך בודד.
  • אם השדות שמורים כ text column - אזי יש עוד עבודת CPU של פענוח מבנה ה json - זמן לא זניח ב jsons גדולים. להזכיר: בעמודה מטיפוס json הם שמורים כ key-value עם גישה מהירה יותר לפי מפתח.
הפתרון האפליקטיבי המתבקש שבו מפתחים שונים נוקטים הוא לאחסן "עותק" של מספר מצומצם של שדות עליהם יש חיפוש - ב columns מקבילים לזה של ה json. ההשפעה על הביצועים - תהיה לרוב דרמטית.

הנה סכמה כזו לדוגמה:

[ Id (guid/auto-inc), json_data (json), field_x (varchar(100)), field_y (int) ]

את השדות x ו y - נרצה לרוב להחזיק גם בתוך ה josn וגם בצד לצורך גישה מהירה / שימוש באינדקסים.
למה שכפול נתונים?
אם נאחסן אותם רק מחוץ ל json - העבודה עם אובייקט ה json תהיה מסורבלת יותר.
לפעמים השדה שאנו מוציאים הוא גם ערך וגם מיקום באובייקט - למשל: המחיר של ההזמנה המאוחרת ביותר (כאשר יש לנו מערך של גרסאות של הזמנות).

את התהליך הנ"ל - ניתן לבצע בצורה פשוטה יותר בעזרת יכולת של MySQL שנקראת generated column, או בעברית "עמודות מחוללות" (מלשון לחולל, ולא מלשון חילול).

נתחיל בדוגמה, איך מגדירים עמודה שכזו:

ALTER TABLE policies
  ADD COLUMN state VARCHAR(30) GENERATED ALWAYS
    AS (json_unquote(json_extract(`json_data`,'$.address.state'))) STORED
;

אני מוסיף שערכו יהיה הביטוי (expression) שבסוגריים לאחר המילה השמורה AS.
  • חשוב לי להשתמש ב json_unquote על מנת שהעמודה לא תכיל מירכאות - וכך אוכל לבצע חיפוש יעיל מול האינדקס.
  • הביטוי GENERATED ALWAYS הוא רשות - ועוזר להבליט את העובדה שמדובר ב generated column - עבור קוראים עתידיים.


תזכורת חשובה: אם השאילתה עושה פעולה כלשהי על שדה מאונדקס (נאמר: state) - לא יהיה שימוש באינדקס. למשל:

... 
WHERE my_state = json_unquote(state)

לא טוב!

השינוי הבא יאפשר שימוש באינדקס (כי את הערך "כפי שהוא" ניתן להשוות בינרית לאינדקס):

... 
WHERE json_quote(my_state) = state

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


בגדול יש שני סוגים של generated columns:
  • Virtual - המחושב בזמן הגישה לרשומה. 
    • בסיס הנתונים ישמור את הביטוי החישובי (expression) כ metadata על הסכמה, ובכל גישה לרשומה / הפעלת trigger - יתבצע החישוב מחדש. קונספט דומה מאוד ל "calculated field" במערכות BI.
    • אנו חוסכים מקום בדיסק - אבל מכבידים על ה CPU בכל גישה. 
    • זהו ערך ברירת המחדל - אם לא ציינתם כלום.
  • Stored - הערכת הביטוי תבוצע בזמן יצירה / עדכון של הרשומה, וישמר לדיסק כמו עמודות אחרות.
    • יש מחיר בנפח אכסון, אך לרוב - הרבה פחות עבודת CPU.
    • זו הגישה הטבעית בעבודה עם json.


לצורך העניין generated column יכול לשמש לצרכים נוספים מלבד json.

למשל:

CREATE TABLE periods 
  id VARCHAR(32), 
  start_date_millis INT, # WARN: https://en.wikipedia.org/wiki/Year_2038_problem  
  end_date_millis INT,   # WARN: https://en.wikipedia.org/wiki/Year_2038_problem  
  start_date_sec AS (state_date_millis * 1000) VIRTUAL 
;

יש כמה מגבלות על שימוש ב generated columns שכדאי להכיר. בביטוי של עמודה מחוללת לא ניתן להשתמש ב:
  • פונקציות לא דטרמיניסטיות - כאלו שיציגו ערכים שונים אם הופעלו פעם שניה. למשל: ()now או ()current_user.
  • sub-queries
  • Parameters / Variables או User Defined Functions.
  • עמודת AUTO_GENERATED או תכונת AUTO_INCREMENT.
  • שדה generated יכול להיות מבוסס רק על שדות generated המופיעים לפניו.
  • לא ניתן להשתמש על ה stored generated column באילוצים של FK מסוגי ON_UPDATE / ON_DELETE

עוד פרט מעניין: ניתן להשתמש באינדקס (משני) גם על virtual generated column מעל innoDB. הוא יהיה מסוג BTree בלבד (כלומר: לא FULLTEXT או GIS).

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



קצת יותר על השימוש בפונקציות ה JSON של MySQL



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


רקע: אני רוצה לבצע מיגרציה לשם של אלמנט בתוך מבנה json שאנו עושים בו שימוש. שם האלמנט היום הוא breakdown אבל השם לא כ"כ נכון - ואני רוצה לשנות אותו ל amounts. הנה דוגמה פשוטה למבנה ה json הקיים לפני השינוי:

[{"policyId":"policy_id","lob":"GL","breakdown":{"PREMIUM":{"amount":423.17}}}]  

וכך אני רוצה שמבנה יראה לאחר השינוי:

[{"policyId":"policy_id","lob":"GL","amounts":{"PREMIUM":{"amount":423.17}}}] 


איך לעזאזל ניגשים למיגרציה "עמוקה" בתוך שדה json? האם זה חייב להיות פרויקט מורכב?

ברור שלא.

אז הנה אני אעשה את השינוי בכמה שלבים פשוטים:

ראשית, אני רוצה ליצור שדות כפולים: גם breakdown וגם amounts - כי באופן טבעי בזמן deployment ירוצו 2 גרסאות של הקוד (גרסה חדשה שמחפשת אחר amounts וגרסה ישנה שמחפשת אחר breakdown). אני צריך להתכונן לכפילות הזו.
אני דואג לכך שבזמן ה deploy (כמה דקות) - לא יווצרו רשומות חדשות (במקרים אחרים ניתן למצוא אותן בעזרת זמן יצירה, ולתקן ידנית אח״כ). 

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

אני מתחיל בשאילתה פשוטה של SELECT על מנת לראות אם קלעתי נכון ב query.
בחרתי לי רשומה שהמפתח שלה הוא '009277a371b8c3def40996a754085030' על מנת לבצע את הניסויים ב scale קטן.

SELECT Json_insert(financial_attribution, '$[0].foo', 2) 
FROM   `payments` 
WHERE  id = '009277a371b8c3def40996a754085030'; 

במבט ראשון זה קצת מבלבל שאני משתמש ב ()JSON_INSERT בפקודת SELECT.
מה קורה כאן?

אני שולף שדה json בשם `financial_attribution` ואז מבצע עליו מניפולציה בזיכרון. המניפולציה שבחרתי היא הכנסה של ערך. מפתח מוזר בשם foo עם ערך של 2. רק לצורך הבדיקה. 

הנה התוצאה:

[{"foo": 2, "lob": "GL", "policyId": "policy_id", "breakdown": {"PREMIUM": {"amount": 423.17}}}]   

השדה נוסף בהצלחה (לי לקח ניסיון או שניים עד שזה עבד) - אך שום מידע לא השתנה בבסיס הנתונים.

עכשיו ננסה משהו יותר אמיתי:

SELECT Json_insert(financial_attribution, '$[0].amounts'                   financial_attribution -> '$[0].breakdown') 
FROM   `payments` 
WHERE  id = '009277a371b8c3def40996a754085030'; 


לקחתי מתוך ה json את אובייקט ה breakdown - והכנסתי אותו בחזרה כ amounts:

[{"lob": "GL", "amounts": {"PREMIUM": {"amount": 423.17}}, "policyId": "policy_id", "breakdown": {"PREMIUM": {"amount": 423.17}}}] 


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

אנסה בצד דוגמה שגם שאילתת ה update תקינה:

UPDATE `payments` 
SET    `financial_attribution` = Json_insert(`financial_attribution`, '$[0].amounts', 
                                 financial_attribution -> '$[0].breakdown') 
; 

ואז הוסיף אותה ל db migrations של השינוי.

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

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



השלמות ליכולות ה json של MySQL 5.7


אם אתם זוכרים את הפוסט הקודם - הבטחתי לכם workarounds למחסור של MySQL 5.7 ב-2 פונקציות שימושיות בעבודה עם json.

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



קריאת הערך האחרון במערך שבתוך json


אני רוצה לקבל את השדה האחרון במערך שבתוך json:

SELECT JSON_EXTRACT(`from`,CONCAT("$[",JSON_LENGTH(`from`)-1,"]")) FROM `table`;


זה קצת תרגיל: אני מוצא את אורך המערך (במקרה שלנו, תחת תכונה בשם from) ואז מרכיב שאילתה בעזרת ()CONCAT - ומריץ אתה. הנה קלט לדוגמה שעליו תעבוד השאילתה:

{ from: ["a","b","c"], "to": [ "d", "e" ] }

התוצאה תהיה ״c״.

הנה דוגמה ב DB Fiddle שאפשר קצת ״לשחק״ איתה:


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




גרסה מאולתרת ל json_each - טיפול בכל איבר במערך שבתוך json


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

הנה דוגמה לשאילתה כזו:

select  n, 
        JSON_EXTRACT(`data`, concat('$.items[', n - 1, '].price')) as price 
from `my_table` 
  join numbers on (n <= JSON_LENGTH(`data`->'$.items') and n > 0) 
;

כאשר התוצאה נראית כך:


n הוא מספר האיבר ברשימה (אינדקס על בסיס 1), ו price הוא... המחיר.

והנתונים נראים כך:


עשינו join עם טבלה של מספרים (0-255 לרוב מספיקה) ואז, עבור כל מספר באורך המערך של ה items - ביצענו פעולת שליפה מתוך ה json על המקום הזה, בהתבסס על ״תרגיל״ ה CONCAT שהשתמשנו בו קודם לכן.

הכי-אלגנטי-בעולם? - לא.
עובד ושימושי - כן!

הנה אתם יכולים לשחק ב fiddle שיצרתי לקוד הזה: https://www.db-fiddle.com/f/dmA8af4CHJ3xkx4fzV99Zw/0


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

CREATE OR REPLACE VIEW generator_16 
AS SELECT 0 n UNION ALL SELECT 1  UNION ALL SELECT 2  UNION ALL 
   SELECT 3   UNION ALL SELECT 4  UNION ALL SELECT 5  UNION ALL 
   SELECT 6   UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL 
   SELECT 9   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL 
   SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
   SELECT 15 
; 

CREATE OR REPLACE VIEW numbers
AS SELECT ( hi.n * 16 + lo.n ) AS n
     FROM generator_16 lo, generator_16 hi
;


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

אפשר למצוא את Fiddle ממקוד של ה generator על מנת ״לשחק״ איתו: https://www.db-fiddle.com/f/jCRetSiTaKqz5SUiQQG8Py/0




סיכום


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


שיהיה בהצלחה!