יותר

כיצד אוכל לשנות ערכים באמצעות מילון או טבלת בדיקה?


אני קורא שורות (~ 20 שדות בשורה) ממסד נתונים באמצעות SearchCursor ומציב אותן במערך. לאחר מכן, אני עובר על המערך ומשתמש ב- InsertCursor כדי להכניס אותם למחלקת תכונות במסד נתונים אחר.

הבעיה, אני צריך לשנות ערכי שדה בנתוני המקור. לדוגמה, עמודה עשויה להכיל את המחרוזות "T", "true", "Yes" ו- "1" ויש להמיר אותן לערך מחרוזת של "TRUE" לפני שהיא נכתבת לעמודת היעד.

  • עשויים להיות ערכים מרובים בעמודת המקור שצריך למפות לערך יחיד ביעד. זו הדוגמה לעיל.
  • יתכנו מספר חיפושים בכל עמודה. לדוגמא, עמודה אחת עשויה להיות בערך מקור של "A" שהופכת ל" Z1 "ובאותה עמודה," B "הופכת ל" Z2", ועדיין באותה עמודה, "C" הופכת ל "Z1" (ערכי מקור מרובים הממופים לאותו ערך יעד).
  • ישנן עמודות רבות שיזדקקו לחיפושים שנוצרו. אני מעדיף שתהיה טבלת מילון / בדיקת מידע שונה עבור כל עמודה מכיוון שככל הנראה יהיו הבדלים עדינים בין העמודות והניסיון לעשות שימוש חוזר במילונים יקבל תסכול.

כיצד עלי לגשת לבעיה זו?


עדכן מספר 1

דוגמה באמצעות הצעות מאת @ mr.adam: זורק שגיאה על הקואם שורה [מפתח] .נמוך () בחיפוש (מפתח [1]):עם המסרTypeError: אובייקט int אינו ניתן לתאריך

lookup = {3: ("TRUE", ["t", "true", "1", "yes"]), 4: ("FALSE", ["f", "false", "0", " no "])} שורות = [] rows.append ((" abc "," 123 "," xyz "," True "," F ")) שורות.append ((" lmo "," 456 "," xyz "," 1 "," no ")) שורות. Append ((" tuv "," 456 "," xyz "," כן "," 0 ")) לשורה בשורות: למפתח, ערך בחיפוש. (): אם שורה [מפתח]. נמוך יותר () בחיפוש (מפתח [1]): שורה [מפתח] = חיפוש (מפתח [0]) לשורה בשורות: הדפסת שורה

עדכון מס '2

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


הייתי מכינה מילון שנראה בערך כך:

חיפושים = {"TRUE": ["t", "true", "1", "yes"], "FALSE": ["f", "false", "0", "no"]}

ואז ההיגיון יכול להיראות כך:

עבור שורה בשורות: עבור i בטווח (0, len (שורה)): עבור מפתח, ערך ב- lookup.iteritems (): אם str (שורה [i]). תחתון () בערך: שורה [i] = מפתח

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

lookups = {fieldindexnumber: ("TRUE", ["t", "true", "1", "yes"]), fieldindexnumber: ("FALSE", ["f", "false", "0", " no "]), שדה אינדקס מספר: (" לא ידוע ", [" u "]), # וודא שהאובייקט השני בכפולת הוא רשימה []}

אז פשוט שנה את מבנה הלולאה ל:

עבור שורה בשורות: עבור מפתח, ערך ב- lookup.iteritems (): אם שורה [מפתח]. נמוך יותר () בערך [1]: שורה [מפתח] = ערך [0]

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

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


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

תרגומים = {# שדה 1: 0: {"TRUE": ["t", "true", "1", "yes"], "FALSE": ["f", "false", "0", " לא "]}, שדה שני #: 1: {" Z1 ": [" A "," C "]," Z2 ": [" B "]} # וכו '}

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

def translate (in_value, translation_dict): out_value = in_value for k, v in translation_dict.iteritems (): if out_value in v: out_value = k break חזרה out_value

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

לשורה בשורות: עבור i ב xrange (len (שורה)): שורה [i] = תרגם (שורה [i], תרגומים [i])

לאחר מכן השורות יעודכנו וזמינות לשימוש עם שלךInsertCursor.


המלצה נוספת: במקום להעתיק את השורות לזיכרון, לשנות אותן ואז להשתמש ב-InsertCursorהייתי עושה את כל זה בזמן-אמת, כך:

עם arcpy.da.InsertCursor (out_table, [field_list]) כמו ic: עם arcpy.da.SearchCursor (in_table, [field_list]) כמו sc: עבור שורה ב- sc: עבור i ב xrange (len (שורה)): שורה [ i] = תרגם (שורה [i], תרגומים [i]) ic.insertRow (שורה)

הערות

המחלקה הגנרית מילון & ltTKey, TValue & gt מספקת מיפוי ממערכת מקשים למערכת ערכים. כל תוספת למילון מורכבת מערך ומפתח המשויך לו. אחזור ערך באמצעות המפתח שלו הוא מהיר מאוד, קרוב ל- O (1), מכיוון שהמילון & ltTKey, TValue & gt מיושם כטבלת hash.

מהירות האחזור תלויה באיכות אלגוריתם הגיבוב מהסוג שצוין עבור TKey.

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

מילון & ltT Key, TValue & gt דורש יישום שוויוני כדי לקבוע אם המקשים שווים. באפשרותך לציין יישום של הממשק הגנרי IEqualityComparer & ltT & gt באמצעות קונסטרוקטור שמקבל פרמטר השוואה אם ​​אינך מציין יישום, נעשה שימוש בשוואת השוויון הגנרית המוגדרת כברירת מחדל EqualityComparer & ltT & gt.Default. אם סוג TKey מיישם את הממשק הגנרי System.IEquatable & ltT & gt, משווה השוויון המוגדר כברירת מחדל משתמש בהטמעה זו.

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

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

.NET Framework בלבד: עבור אובייקטים גדולים מאוד של מילון & ltTKey, TValue & gt, תוכלו להגדיל את הקיבולת המרבית ל -2 מיליארד אלמנטים במערכת 64 סיביות על ידי הגדרת המאפיין המאופשר של רכיב התצורה & ltgcAllowVeryLargeObjects & gt לאמיתי בסביבת זמן הריצה.

לצורכי ספירה, כל פריט במילון מתייחס כמבנה KeyValuePair & ltTKey, TValue & gt המייצג ערך ומפתח שלו. סדר החזרת הפריטים אינו מוגדר.

הצהרת ה- foreach של שפת C # (עבור כל אחד ב- C ++, עבור כל אחד ב- Visual Basic) מחזירה אובייקט מסוג האלמנטים באוסף. מכיוון שהמילון & ltTKey, TValue & gt הוא אוסף של מקשים וערכים, סוג האלמנט אינו סוג המפתח או סוג הערך. במקום זאת, סוג האלמנט הוא KeyValuePair & ltTKey, TValue & gt מסוג המפתח וסוג הערך. לדוגמה:

הצהרת ה- foreach היא עטיפה סביב המונה, המאפשרת רק לקרוא מהאוסף, ולא לכתוב אליו.

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


1 תשובה 1

אתה צריך לחפור קצת כדי לראות כיצד המילון מיושם ב- C # - זה לא מובן מאליו כמו HashMap (טבלת hash) או TreeMap (עץ ממוין) (או ConcurrentSkipListMap - רשימת דלגים).

אם אתה נכנס לסעיף "הערות":

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

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

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

באשר ליעילות בדיקה / מכיל שונים?

  • הליכה ברשימה לא ממוינת: O (N)
  • חיפוש בינארי של מערך ממוין: O (יומן N)
  • עץ ממוין: O (יומן N)
  • טבלת חשיש: O (1)

עבור רוב האנשים, שולחן החשיש הוא מה שהם רוצים.

יתכן שתגלה כי ה- SortedDiction הוא מה שאתה רוצה במקום זאת:

המחלקה הגנרית SortedDictionary & ltTKey, TValue & gt היא עץ חיפוש בינארי עם אחזור O (log n), כאשר n הוא מספר האלמנטים במילון. מבחינה זו, זה דומה למחלקה הגנרית SortedList & ltTKey, TValue & gt. לשתי המחלקות יש מודלים של אובייקטים דומים, ולשניהם אחזור O (log n).

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

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


שיטות הרחבה

מנסה להסיר את הערך עם המפתח שצוין מהמילון.

מנסה להוסיף את המפתח והערך שצוינו למילון.

יוצר מערך בלתי משתנה מהאוסף שצוין.

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

בונה מילון בלתי משתנה המבוסס על שינוי כלשהו של רצף.

מונה והופך רצף ומייצר מילון בלתי משתנה לתכניו.

מונה והופך רצף ומייצר מילון בלתי משתנה לתכניו באמצעות משווה המקשים שצוין.

מונה והופך רצף ומייצר מילון בלתי משתנה לתכניו באמצעות מפתח השוואות והערכים שצוינו.

מונה רצף ומייצר מערך חשיש בלתי משתנה מתוכנו.

מונה רצף, מייצר ערכת hash בלתי ניתנת לשינוי מתכניה ומשתמש במשווה השוויון שצוין לסוג הסט.

מונה רצף ומייצר רשימה בלתי ניתנת לשינוי של תוכנו.

מונה והופך רצף ומייצר מילון ממוין בלתי משתנה של תוכנו.

מונה והופך רצף ומייצר מילון ממוין בלתי משתנה של תוכנו באמצעות משווה המקשים שצוין.

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

מונה רצף ומייצר מערך ממוין בלתי משתנה של תוכנו.

מונה רצף, מייצר מערך ממוין בלתי משתנה של תוכנו ומשתמש בהשוואה שצוינה.

מחזירה טבלת נתונים המכילה עותקים של אובייקטים DataRow, בהתחשב באובייקט קלט IEnummerable & ltT & gt כאשר הפרמטר הכללי T הוא DataRow.

מעתיק אובייקטים של DataRow לטבלת הנתונים שצוינה, בהתחשב בקלט IEnummerable & ltT & gt כאשר הפרמטר הכללי T הוא DataRow.

מעתיק אובייקטים של DataRow לטבלת הנתונים שצוינה, בהתחשב בקלט IEnummerable & ltT & gt כאשר הפרמטר הכללי T הוא DataRow.

מפעיל פונקציית צבירה על פני רצף.

מפעיל פונקציית צבירה על פני רצף. ערך הזרע שצוין משמש כערך הצבר הראשוני.

מפעיל פונקציית מצבר על רצף. ערך הזרע שצוין משמש כערך הצבר הראשוני, והפונקציה שצוינה משמשת לבחירת ערך התוצאה.

קובע אם כל האלמנטים ברצף מספקים תנאי.

קובע אם רצף מכיל רכיבים כלשהם.

קובע אם אלמנט כלשהו ברצף עומד בתנאי.

מוסיף ערך לסוף הרצף.

מחזיר את הקלט שהוקלד כ- IEnummerable & ltT & gt.

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

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

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

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

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

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

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

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

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

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

מעביר את האלמנטים של מספר IE למספר שצוין.

משרשר שני רצפים.

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

קובע אם רצף מכיל אלמנט מוגדר באמצעות IEqualityComparer & ltT & gt שצוין.

מחזיר את מספר האלמנטים ברצף.

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

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

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

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

מחזיר אלמנטים מובחנים מרצף באמצעות IEqualityComparer & ltT & gt שצוין כדי להשוות ערכים.

מחזיר את האלמנט באינדקס שצוין ברצף.

מחזיר את האלמנט באינדקס שצוין ברצף או בערך ברירת מחדל אם האינדקס נמצא מחוץ לטווח.

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

מייצר את ההפרש המוגדר של שני רצפים באמצעות IEqualityComparer & ltT & gt שצוין כדי להשוות ערכים.

מחזיר את האלמנט הראשון ברצף.

מחזיר את האלמנט הראשון ברצף העונה על תנאי שצוין.

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

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

מקבץ את רכיבי הרצף על פי פונקציית בורר מקשים שצוינה.

מקבץ את אלמנטים של רצף על פי פונקציית בורר מקשים מוגדרת ומשווה את המקשים באמצעות משווה שצוין.

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

מקבץ את רכיבי הרצף על פי פונקציית בורר מקשים. מקלידים מושווים באמצעות משווה ואלמנטים של כל קבוצה מוקרנים באמצעות פונקציה מוגדרת.

מקבץ את רכיבי הרצף לפי פונקציית בורר מקשים שצוינה ויוצר ערך תוצאה מכל קבוצה והמפתח שלה.

מקבץ את רכיבי הרצף לפי פונקציית בורר מקשים שצוינה ויוצר ערך תוצאה מכל קבוצה והמפתח שלה. משווים את המקשים באמצעות משווה שצוין.

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

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

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

מתאם בין האלמנטים של שני רצפים המבוססים על שוויון מפתח ומקבץ את התוצאות. IEqualityComparer & ltT & gt מוגדר משמש להשוואת מפתחות.

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

מייצר את הצומת הקבוע של שני רצפים באמצעות IEqualityComparer & ltT & gt שצוין כדי להשוות ערכים.

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

מתאם בין האלמנטים של שני רצפים בהתבסס על מקשים תואמים. IEqualityComparer & ltT & gt מוגדר משמש להשוואת מפתחות.

מחזיר את האלמנט האחרון ברצף.

מחזיר את האלמנט האחרון ברצף העונה על תנאי שצוין.

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

מחזיר את האלמנט האחרון ברצף העונה על תנאי או ערך ברירת מחדל אם לא נמצא רכיב כזה.

מחזירה Int64 המייצג את מספר האלמנטים הכולל ברצף.

מחזירה Int64 המייצג כמה אלמנטים ברצף מספקים תנאי.

מחזירה את הערך המרבי ברצף כללי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את הערך העשרוני המרבי.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את הערך הכפול המרבי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את ערך Int32 המרבי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את ערך Int64 המרבי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את הערך העשרוני המרבי המותר.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את הערך המרבי הכפול המבטל.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את ערך Int32 המרבי המבטל.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את ערך Int64 המרבי המותר.

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

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

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף כללי ומחזיר את הערך המרבי המתקבל.

מחזיר את הערך המינימלי ברצף כללי.

קורא לפונקציית שינוי בכל אלמנט ברצף ומחזיר את הערך העשרוני המינימלי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את הערך הכפול המינימלי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את ערך Int32 המינימלי.

קורא לפונקציית טרנספורמציה בכל אלמנט ברצף ומחזיר את ערך ה- Int64 המינימלי.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את הערך העשרוני המינימלי המבטל.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את הערך הכפול המינימלי המבטל.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את ערך Int32 המינימלי לביטול.

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף ומחזיר את ערך ה- Int64 המינימלי לביטול.

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

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

קורא לפונקציית טרנספורמציה על כל אלמנט ברצף כללי ומחזיר את הערך המינימלי שהתקבל.

מסנן את האלמנטים של מספר IE על סמך סוג מוגדר.

ממיין את מרכיבי הרצף בסדר עולה לפי מפתח.

ממיין את מרכיבי הרצף בסדר עולה באמצעות משווה שצוין.

ממיין את רכיבי הרצף בסדר יורד לפי מפתח.

ממיין את מרכיבי הרצף בסדר יורד באמצעות משווה שצוין.

מוסיף ערך לתחילת הרצף.

הופך את סדר האלמנטים ברצף.

מקרין כל אלמנט ברצף לצורה חדשה.

מקרין כל אלמנט ברצף לצורה חדשה על ידי שילוב אינדקס האלמנט.

מקרין כל אלמנט ברצף ל- IEnummerable & ltT & gt ומשטיח את הרצפים המתקבלים לרצף אחד.

מקרין כל אלמנט ברצף ל- IEnummerable & ltT & gt, ומשטח את הרצפים המתקבלים לרצף אחד. האינדקס של כל אלמנט מקור משמש בצורה המוקרנת של אותו אלמנט.

מקרין כל אלמנט ברצף ל- IEnumerable & ltT & gt, משטח את הרצפים המתקבלים לרצף אחד ומפעיל פונקציה של בורר תוצאות על כל אלמנט בו.

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

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

קובע אם שני רצפים שווים על ידי השוואת האלמנטים שלהם באמצעות IEqualityComparer & ltT & gt שצוין.

מחזיר את האלמנט היחיד ברצף, וזורק חריג אם אין בדיוק אלמנט אחד ברצף.

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

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

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

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

מחזיר אוסף אינספור חדש שמכיל את האלמנטים מהמקור כאשר אלמנטים הספירה האחרונים של אוסף המקור הושמטו.

עוקף אלמנטים ברצף כל עוד תנאי מוגדר נכון ואז מחזיר את האלמנטים הנותרים.

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

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

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

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

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

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

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

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

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

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

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

מחזירה מספר מוגדר של אלמנטים רציפים מתחילת הרצף.

מחזירה אוסף אינספור חדש המכיל את רכיבי הספירה האחרונים מהמקור.

מחזיר אלמנטים מרצף כל עוד תנאי מוגדר נכון.

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

יוצר מילון & ltTKey, TValue & gt מ- IEnummerable & ltT & gt על פי פונקציית בורר מקשים שצוינה.

יוצר מילון & ltTKey, TValue & gt מ- IEnummerable & ltT & gt על פי פונקציית בורר מקשים מוגדרת ומשווה מקשים.

יוצר מילון & ltTKey, TValue & gt ממספר IEnummerable & ltT & gt בהתאם לפונקציות בורר המקשים והבורר של האלמנטים שצוינו.

יוצר מילון & ltTKey, TValue & gt מ- IEnummerable & ltT & gt על פי פונקציית בורר מקשים מוגדרת, משווה ופונקציה לבחירת רכיבים.

יוצר HashSet & ltT & gt מ- IEnummerable & ltT & gt באמצעות המשווה להשוואת מקשים.

יוצר Lookup & ltTKey, TElement & gt מ- IEnummerable & ltT & gt על פי פונקציית בורר מקשים שצוינה.

יוצר Lookup & ltTKey, Tlement & gt מ- IEnummerable & ltT & gt על פי פונקציית בורר מקשים מוגדרת ומשווה מקשים.

יוצר Lookup & ltTKey, TElement & gt מ- IEnummerable & ltT & gt בהתאם לפונקציות בורר המקשים והבורר האלמנטים שצוינו.

יוצר Lookup & ltTKey, TElement & gt מ- IEnummerable & ltT & gt על פי פונקציית בורר מקשים שצוינה, משווה ופונקציה לבחירת רכיבים.

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

מייצר את האיחוד הקבוע של שני רצפים באמצעות IEqualityComparer & ltT & gt שצוין.

מסנן רצף ערכים המבוסס על פרדיקט.

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

מייצר רצף של צמרות עם אלמנטים משני הרצפים שצוינו.

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

מאפשר הקבלה של שאילתה.

מאפשר הקבלה של שאילתה.

מחזיר אוסף של אלמנטים המכילים את אבותיו של כל צומת באוסף המקור.

מחזירה אוסף מסונן של אלמנטים המכיל את אבותיו של כל צומת באוסף המקורות. רק אלמנטים שיש להם XName תואם כלולים באוסף.

מחזירה אוסף של צמתי הצאצאים של כל מסמך ורכיב באוסף המקור.

מחזירה אוסף של אלמנטים המכילים את האלמנטים הצאצאים של כל אלמנט ומסמך באוסף המקור.

מחזירה אוסף מסונן של אלמנטים המכיל את האלמנטים הצאצאים של כל אלמנט ומסמך באוסף המקור. רק אלמנטים שיש להם XName תואם כלולים באוסף.

מחזיר אוסף של אלמנטים צאצאים של כל אלמנט ומסמך באוסף המקור.

מחזיר אוסף מסונן של רכיבי הצאצא של כל רכיב ומסמך באוסף המקור. רק אלמנטים שיש להם XName תואם כלולים באוסף.

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

מחזיר אוסף של צמתי הילד של כל מסמך ורכיב באוסף המקור.


שינוי צבירה באינפורמטיקה עם דוגמה

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

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

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

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

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

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

שלב 2 - צור מיפוי חדש "m_ sum_sal_deptwise".

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

שלב 3 במיפוי,

שלב 4 גרור ושחרר עמודות SAL & amp DEPTNO ממוקדמות המקור (SQ_EMP) לשינוי הצבירה

שלב 5 - לחץ פעמיים על טרנספורמציית הצבירה כדי לפתוח את המאפיינים שלה, ואז

שלב 6 - בחלון הביטוי

שלב 7 - בחלון עריכת טרנספורמציה, בחר באפשרות "GroupBy" על ידי סימון תיבת הסימון מול העמודה deptno ולחץ על Ok (על ידי בחירת group by לעומת deptno, אנו מורים ל- Informatica לקבץ משכורות לפי deptno)

שלב 8 - קשר את העמודות deptno ו- sum_sal מהפיכת צובר לטבלת היעד

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


מפתחות פונדקאיות

According to the Webster’s Unabridged Dictionary, a surrogate is an “artificial or synthetic product that is used as a substitute for a natural product.” Thatýs a great definition for the surrogate keys we use in data warehouses. A surrogate key is an artificial or synthetic key that is used as a substitute for a natural key.

Actually, a surrogate key in a data warehouse is more than just a substitute for a natural key. In a data warehouse, a surrogate key is a necessary generalization of the natural production key and is one of the basic elements of data warehouse design. Let’s be very clear: Every join between dimension tables and fact tables in a data warehouse environment should be based on surrogate keys, not natural keys. It is up to the data extract logic to systematically look up and replace every incoming natural key with a data warehouse surrogate key each time either a dimension record or a fact record is brought into the data warehouse environment.

In other words, when we have a product dimension joined to a fact table, or a customer dimension joined to a fact table, or even a time dimension joined to a fact table, the actual physical keys on either end of the joins are not natural keys directly derived from the incoming data. Rather, the keys are surrogate keys that are just anonymous integers. Each one of these keys should be a simple integer, starting with one and going up to the highest number that is needed. The product key should be a simple integer, the customer key should be a simple integer, and even the time key should be a simple integer. None of the keys should be:

  • Smart, where you can tell something about the record just by looking at the key
  • Composed of natural keys glued together
  • Implemented as multiple parallel joins between the dimension table and the fact table so-called double or triple barreled joins.

If you are a professional DBA, I probably have your attention. If you are new to data warehousing, you are probably horrified. Perhaps you are saying, “But if I know what my underlying key is, all my training suggests that I make my key out of the data I am given.” Yes, in the production transaction processing environment, the meaning of a product key or a customer key is directly related to the record’s content. In the data warehouse environment, however, a dimension key must be a generalization of what is found in the record.

As the data warehouse manager, you need to keep your keys independent from the production keys. Production has different priorities from you. Production keys such as product keys or customer keys are generated, formatted, updated, deleted, recycled, and reused according to the dictates of production. If you use production keys as your keys, you will be jerked around by changes that can be, at the very least, annoying, and at the worst, disastrous. Suppose that you need to keep a three-year history of product sales in your large sales fact table, but production decides to purge their product file every 18 months. What do you do then? Let’s list some of the ways that production may step on your toes:

  • Production may reuse keys that it has purged but that you are still maintaining, as I described.
  • Production may make a mistake and reuse a key even when it isn’t supposed to. This happens frequently in the world of UPCs in the retail world, despite everyone’s best intentions.
  • Production may re-compact its key space because it has a need to garbage-collect the production system. One of my customers was recently handed a data warehouse load tape with all the production customer keys reassigned!
  • Production may legitimately overwrite some part of a product description or a customer description with new values but not change the product key or the customer key to a new value. You are left holding the bag and wondering what to do about the revised attribute values. This is the Slowly Changing Dimension crisis, which I will explain in a moment.
  • Production may generalize its key format to handle some new situation in the transaction system. Now the production keys that used to be integers become alphanumeric. Or perhaps the 12-byte keys you are used to have become 20-byte keys.
  • Your company has just made an acquisition, and you need to merge more than a million new customers into the master customer list. You will now need to extract from two production systems, but the newly acquired production system has nasty customer keys that don’t look remotely like the others.

The Slowly Changing Dimension crisis I mentioned earlier is a well-known situation in data warehousing. Rather than blaming production for not handling its keys better, it is more constructive to recognize that this is an area where the interests of production and the interests of the data warehouse legitimately diverge. Usually, when the data warehouse administrator encounters a changed description in a dimension record such as product or customer, the correct response is to issue a new dimension record. But to do this, the data warehouse must have a more general key structure. Hence the need for a surrogate key.

There are still more reasons to use surrogate keys. One of the most important is the need to encode uncertain knowledge. You may need to supply a customer key to represent a transaction, but perhaps you donýt know for certain who the customer is. This would be a common occurrence in a retail situation where cash transactions are anonymous, like most grocery stores. What is the customer key for the anonymous customer? Perhaps you have introduced a special key that stands for this anonymous customer. This is politely referred to as a “hack.”

If you think carefully about the “I don’t know” situation, you may want more than just this one special key for the anonymous customer. You may also want to describe the situation where “the customer identification has not taken place yet.” Or maybe, “there was a customer, but the data processing system failed to report it correctly.” And also, “no customer is possible in this situation.” All of these situations call for a data warehouse customer key that cannot be composed from the transaction production customer keys. Don’t forget that in the data warehouse you must provide a customer key for every fact record in the schema shown in Figure 1. A null key automatically turns on the referential integrity alarm in your data warehouse because a foreign key (as in the fact table) can never be null.

The “I don’t know” situation occurs quite frequently for dates. You are probably using date-valued keys for your joins between your fact tables and your dimension tables. Once again, if you have done this you are forced to use some kind of real date to represent the special situations where a date value is not possible. I hope you have not been using January 1, 2000 to stand for “I don’t know.” If you have done this, you have managed to combine the production key crisis with the Year 2000 crisis.

Maybe one of the reasons you are holding on to your smart keys built up out of real data is that you think you want to navigate the keys directly with an application, avoiding the join to the dimension table. It is time to forget this strategy. If the fifth through ninth alpha characters in the join key can be interpreted as a manufacturer’s ID, then copy these characters and make them a normal field in the dimension table. Better yet, add the manufacturer’s name in plain text as a field. As the final step, consider throwing away the alphanumeric manufacturer ID. The only reason the marketing end users know these IDs is that they have been forced to use them for computer requests.

Holding onto real date values as keys is also a strategic blunder. Yes, you can navigate date keys with straight SQL, thereby avoiding the join, but you have left all your special calendar information marooned in the date dimension table. If you navigate naked date keys with an application, you will inevitably begin embedding calendar logic in your application. Calendar logic belongs in a dimension table, not in your application code.

You may be able to save substantial storage space with integer-valued surrogate keys. Suppose you have a big fact table with a billion rows of data. In such a table, every byte wasted in each row is a gigabyte of total storage. The beauty of a four-byte integer key is that it can represent more than 2 billion different values. That is enough for any dimension, even the so-called monster dimensions that represent individual human beings. So we compress all our long customer IDs and all our long product stock keeping units and all our date stamps down to four-byte keys. This saves many gigabytes of total storage.

The final reason I can think of for surrogate keys is one that I strongly suspect but have never proven. Replacing big, ugly natural keys and composite keys with beautiful, tight integer surrogate keys is bound to improve join performance. The storage requirements are reduced, and the index lookups would seem to be simpler. I would be interested in hearing from anyone who has harvested a performance boost by replacing big ugly fat keys with anonymous integer keys.

Having made the case for surrogate keys, we now are faced with creating them. Fundamentally, every time we see a natural key in the incoming data stream, we must look up the correct value of the surrogate key and replace the natural key with the surrogate key. Because this is a significant step in the daily extract and transform process within the data staging area, we need to tighten down our techniques to make this lookup simple and fast.


Transform

transform, metamorphose, transmute, convert, transmogrify, transfigure mean to change a thing into a different thing. transform implies a major change in form, nature, or function. transformed a small company into a corporate giant metamorphose suggests an abrupt or startling change induced by or as if by magic or a supernatural power. awkward girls metamorphosed into graceful ballerinas transmute implies transforming into a higher element or thing. attempted to transmute lead into gold convert implies a change fitting something for a new or different use or function. converted the study into a nursery transmogrify suggests a strange or preposterous metamorphosis. a story in which a frog is transmogrified into a prince transfigure implies a change that exalts or glorifies. joy transfigured her face


About the Author

Siddharth Teotia is a software engineer at Dremio and a contributor to Apache Arrow project. Previously, Siddharth was on the database kernel team at Oracle, where he worked on storage, indexing, and the in-memory columnar query processing layers of Oracle RDBMS. He holds an MS in software engineering from CMU and a BS in information systems from BITS Pilani, India. During his studies, Siddharth focused on distributed systems, databases, and software architecture.


תוכן

The first part of an ETL process involves extracting the data from the source system(s). In many cases, this represents the most important aspect of ETL, since extracting data correctly sets the stage for the success of subsequent processes. Most data-warehousing projects combine data from different source systems. Each separate system may also use a different data organization and/or format. Common data-source formats include relational databases, XML, JSON and flat files, but may also include non-relational database structures such as Information Management System (IMS) or other data structures such as Virtual Storage Access Method (VSAM) or Indexed Sequential Access Method (ISAM), or even formats fetched from outside sources by means such as web spidering or screen-scraping. The streaming of the extracted data source and loading on-the-fly to the destination database is another way of performing ETL when no intermediate data storage is required.

An intrinsic part of the extraction involves data validation to confirm whether the data pulled from the sources has the correct/expected values in a given domain (such as a pattern/default or list of values). If the data fails the validation rules, it is rejected entirely or in part. The rejected data is ideally reported back to the source system for further analysis to identify and to rectify the incorrect records.

In the data transformation stage, a series of rules or functions are applied to the extracted data in order to prepare it for loading into the end target.

An important function of transformation is data cleansing, which aims to pass only "proper" data to the target. The challenge when different systems interact is in the relevant systems' interfacing and communicating. Character sets that may be available in one system may not be so in others.

In other cases, one or more of the following transformation types may be required to meet the business and technical needs of the server or data warehouse:

  • Selecting only certain columns to load: (or selecting null columns not to load). For example, if the source data has three columns (aka "attributes"), roll_no, age, and salary, then the selection may take only roll_no and salary. Or, the selection mechanism may ignore all those records where salary is not present (salary = null).
  • Translating coded values: (לְמָשָׁל, if the source system codes male as "1" and female as "2", but the warehouse codes male as "M" and female as "F")
  • Encoding free-form values: (לְמָשָׁל, mapping "Male" to "M")
  • Deriving a new calculated value: (לְמָשָׁל, sale_amount = qty * unit_price)
  • Sorting or ordering the data based on a list of columns to improve search performance data from multiple sources (לְמָשָׁל, lookup, merge) and deduplicating the data
  • Aggregating (for example, rollup — summarizing multiple rows of data — total sales for each store, and for each region, etc.)
  • Generating surrogate-key values or pivoting (turning multiple columns into multiple rows or vice versa)
  • Splitting a column into multiple columns (לְמָשָׁל, converting a comma-separated list, specified as a string in one column, into individual values in different columns)
  • Disaggregating repeating columns
  • Looking up and validating the relevant data from tables or referential files
  • Applying any form of data validation failed validation may result in a full rejection of the data, partial rejection, or no rejection at all, and thus none, some, or all of the data is handed over to the next step depending on the rule design and exception handling many of the above transformations may result in exceptions, e.g., when a code translation parses an unknown code in the extracted data

The load phase loads the data into the end target, which can be any data store including a simple delimited flat file or a data warehouse. [5] Depending on the requirements of the organization, this process varies widely. Some data warehouses may overwrite existing information with cumulative information updating extracted data is frequently done on a daily, weekly, or monthly basis. Other data warehouses (or even other parts of the same data warehouse) may add new data in a historical form at regular intervals — for example, hourly. To understand this, consider a data warehouse that is required to maintain sales records of the last year. This data warehouse overwrites any data older than a year with newer data. However, the entry of data for any one year window is made in a historical manner. The timing and scope to replace or append are strategic design choices dependent on the time available and the business needs. More complex systems can maintain a history and audit trail of all changes to the data loaded in the data warehouse. [6]

As the load phase interacts with a database, the constraints defined in the database schema — as well as in triggers activated upon data load — apply (for example, uniqueness, referential integrity, mandatory fields), which also contribute to the overall data quality performance of the ETL process.

  • For example, a financial institution might have information on a customer in several departments and each department might have that customer's information listed in a different way. The membership department might list the customer by name, whereas the accounting department might list the customer by number. ETL can bundle all of these data elements and consolidate them into a uniform presentation, such as for storing in a database or data warehouse.
  • Another way that companies use ETL is to move information to another application permanently. For instance, the new application might use another database vendor and most likely a very different database schema. ETL can be used to transform the data into a format suitable for the new application to use.
  • An example would be an Expense and Cost Recovery System (ECRS) such as used by accountancies, consultancies, and legal firms. The data usually ends up in the time and billing system, although some businesses may also utilize the raw data for employee productivity reports to Human Resources (personnel dept.) or equipment usage reports to Facilities Management.

The typical real-life ETL cycle consists of the following execution steps:

  1. Cycle initiation
  2. Build reference data
  3. Extract (from sources)
  4. Transform (clean, apply business rules, check for data integrity, create aggregates or disaggregates)
  5. Stage (load into staging tables, if used) (for example, on compliance with business rules. Also, in case of failure, helps to diagnose/repair)
  6. Publish (to target tables)

ETL processes can involve considerable complexity, and significant operational problems can occur with improperly designed ETL systems.

The range of data values or data quality in an operational system may exceed the expectations of designers at the time validation and transformation rules are specified. Data profiling of a source during data analysis can identify the data conditions that must be managed by transform rules specifications, leading to an amendment of validation rules explicitly and implicitly implemented in the ETL process.

Data warehouses are typically assembled from a variety of data sources with different formats and purposes. As such, ETL is a key process to bring all the data together in a standard, homogeneous environment.

Design analysis [7] should establish the scalability of an ETL system across the lifetime of its usage — including understanding the volumes of data that must be processed within service level agreements. The time available to extract from source systems may change, which may mean the same amount of data may have to be processed in less time. Some ETL systems have to scale to process terabytes of data to update data warehouses with tens of terabytes of data. Increasing volumes of data may require designs that can scale from daily batch to multiple-day micro batch to integration with message queues or real-time change-data-capture for continuous transformation and update.

ETL vendors benchmark their record-systems at multiple TB (terabytes) per hour (or

1 GB per second) using powerful servers with multiple CPUs, multiple hard drives, multiple gigabit-network connections, and much memory.

In real life, the slowest part of an ETL process usually occurs in the database load phase. Databases may perform slowly because they have to take care of concurrency, integrity maintenance, and indices. Thus, for better performance, it may make sense to employ:

  • Direct path extract method or bulk unload whenever is possible (instead of querying the database) to reduce the load on source system while getting high-speed extract
  • Most of the transformation processing outside of the database
  • Bulk load operations whenever possible

Still, even using bulk operations, database access is usually the bottleneck in the ETL process. Some common methods used to increase performance are:

    tables (and indices): try to keep partitions similar in size (watch for null values that can skew the partitioning)
  • Do all validation in the ETL layer before the load: disable integrity checking ( disable constraint . ) in the target database tables during the load
  • Disable triggers ( disable trigger . ) in the target database tables during the load: simulate their effect as a separate step
  • Generate IDs in the ETL layer (not in the database)
  • Drop the indices (on a table or partition) before the load - and recreate them after the load (SQL: drop index . create index . )
  • Use parallel bulk load when possible — works well when the table is partitioned or there are no indices (Note: attempting to do parallel loads into the same table (partition) usually causes locks — if not on the data rows, then on indices)
  • If a requirement exists to do insertions, updates, or deletions, find out which rows should be processed in which way in the ETL layer, and then process these three operations in the database separately you often can do bulk load for inserts, but updates and deletes commonly go through an API (using SQL)

Whether to do certain operations in the database or outside may involve a trade-off. For example, removing duplicates using distinct may be slow in the database thus, it makes sense to do it outside. On the other side, if using distinct significantly (x100) decreases the number of rows to be extracted, then it makes sense to remove duplications as early as possible in the database before unloading data.

A common source of problems in ETL is a big number of dependencies among ETL jobs. For example, job "B" cannot start while job "A" is not finished. One can usually achieve better performance by visualizing all processes on a graph, and trying to reduce the graph making maximum use of parallelism, and making "chains" of consecutive processing as short as possible. Again, partitioning of big tables and their indices can really help.

Another common issue occurs when the data are spread among several databases, and processing is done in those databases sequentially. Sometimes database replication may be involved as a method of copying data between databases — it can significantly slow down the whole process. The common solution is to reduce the processing graph to only three layers:

This approach allows processing to take maximum advantage of parallelism. For example, if you need to load data into two databases, you can run the loads in parallel (instead of loading into the first — and then replicating into the second).

Sometimes processing must take place sequentially. For example, dimensional (reference) data are needed before one can get and validate the rows for main "fact" tables.

A recent [update] development in ETL software is the implementation of parallel processing. It has enabled a number of methods to improve overall performance of ETL when dealing with large volumes of data.

ETL applications implement three main types of parallelism:

  • Data: By splitting a single sequential file into smaller data files to provide parallel access : allowing the simultaneous running of several components on the same data stream, e.g. looking up a value on record 1 at the same time as adding two fields on record 2
  • Component: The simultaneous running of multiple processes on different data streams in the same job, e.g. sorting one input file while removing duplicates on another file

All three types of parallelism usually operate combined in a single job or task.

An additional difficulty comes with making sure that the data being uploaded is relatively consistent. Because multiple source databases may have different update cycles (some may be updated every few minutes, while others may take days or weeks), an ETL system may be required to hold back certain data until all sources are synchronized. Likewise, where a warehouse may have to be reconciled to the contents in a source system or with the general ledger, establishing synchronization and reconciliation points becomes necessary.

Data warehousing procedures usually subdivide a big ETL process into smaller pieces running sequentially or in parallel. To keep track of data flows, it makes sense to tag each data row with "row_id", and tag each piece of the process with "run_id". In case of a failure, having these IDs help to roll back and rerun the failed piece.

Best practice also calls for checkpoints, which are states when certain phases of the process are completed. Once at a checkpoint, it is a good idea to write everything to disk, clean out some temporary files, log the state, etc.

As of 2010 [update] , data virtualization had begun to advance ETL processing. The application of data virtualization to ETL allowed solving the most common ETL tasks of data migration and application integration for multiple dispersed data sources. Virtual ETL operates with the abstracted representation of the objects or entities gathered from the variety of relational, semi-structured, and unstructured data sources. ETL tools can leverage object-oriented modeling and work with entities' representations persistently stored in a centrally located hub-and-spoke architecture. Such a collection that contains representations of the entities or objects gathered from the data sources for ETL processing is called a metadata repository and it can reside in memory [8] or be made persistent. By using a persistent metadata repository, ETL tools can transition from one-time projects to persistent middleware, performing data harmonization and data profiling consistently and in near-real time. [9]

Unique keys play an important part in all relational databases, as they tie everything together. A unique key is a column that identifies a given entity, whereas a foreign key is a column in another table that refers to a primary key. Keys can comprise several columns, in which case they are composite keys. In many cases, the primary key is an auto-generated integer that has no meaning for the business entity being represented, but solely exists for the purpose of the relational database - commonly referred to as a surrogate key.

As there is usually more than one data source getting loaded into the warehouse, the keys are an important concern to be addressed. For example: customers might be represented in several data sources, with their Social Security Number as the primary key in one source, their phone number in another, and a surrogate in the third. Yet a data warehouse may require the consolidation of all the customer information into one dimension.

A recommended way to deal with the concern involves adding a warehouse surrogate key, which is used as a foreign key from the fact table. [10]

Usually, updates occur to a dimension's source data, which obviously must be reflected in the data warehouse.

If the primary key of the source data is required for reporting, the dimension already contains that piece of information for each row. If the source data uses a surrogate key, the warehouse must keep track of it even though it is never used in queries or reports it is done by creating a lookup table that contains the warehouse surrogate key and the originating key. [11] This way, the dimension is not polluted with surrogates from various source systems, while the ability to update is preserved.

The lookup table is used in different ways depending on the nature of the source data. There are 5 types to consider [11] three are included here:

Type 1 The dimension row is simply updated to match the current state of the source system the warehouse does not capture history the lookup table is used to identify the dimension row to update or overwrite Type 2 A new dimension row is added with the new state of the source system a new surrogate key is assigned source key is no longer unique in the lookup table Fully logged A new dimension row is added with the new state of the source system, while the previous dimension row is updated to reflect it is no longer active and time of deactivation.

By using an established ETL framework, one may increase one's chances of ending up with better connectivity and scalability. [ צורך בציטוט ] A good ETL tool must be able to communicate with the many different relational databases and read the various file formats used throughout an organization. ETL tools have started to migrate into Enterprise Application Integration, or even Enterprise Service Bus, systems that now cover much more than just the extraction, transformation, and loading of data. Many ETL vendors now have data profiling, data quality, and metadata capabilities. A common use case for ETL tools include converting CSV files to formats readable by relational databases. A typical translation of millions of records is facilitated by ETL tools that enable users to input csv-like data feeds/files and import it into a database with as little code as possible.

ETL tools are typically used by a broad range of professionals — from students in computer science looking to quickly import large data sets to database architects in charge of company account management, ETL tools have become a convenient tool that can be relied on to get maximum performance. ETL tools in most cases contain a GUI that helps users conveniently transform data, using a visual data mapper, as opposed to writing large programs to parse files and modify data types.

While ETL tools have traditionally been for developers and IT staff, the new trend is to provide these capabilities to business users so they can themselves create connections and data integrations when needed, rather than going to the IT staff. [12] Gartner refers to these non-technical users as Citizen Integrators. [13]

Extract, load, transform (ELT) is a variant of ETL where the extracted data is loaded into the target system first. [14] The architecture for the analytics pipeline shall also consider where to cleanse and enrich data [14] as well as how to conform dimensions. [4]

Cloud-based data warehouses like Amazon Redshift, Google BigQuery, and Snowflake Computing have been able to provide highly scalable computing power. This lets businesses forgo preload transformations and replicate raw data into their data warehouses, where it can transform them as needed using SQL.

After having used ELT, data may be processed further and stored in a data mart. [15]