איך מספרים נשמרים באורקל? - ilDBA Portal

איך מספרים נשמרים באורקל?

31/07/2011 | פורסם על ידי

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

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

אז זהו, שזה לא ממש המצב.

באורקל, טיפוס המשתנה הנפוץ בעבודה עם מספרים הוא number. טיפוס זה הוא טיפוס בגודל משתנה ולא קבוע, כלומר, הוא לא תופס 4 או 8 בתים בצורה קבועה. מעבר לזה, המבנה הפנימי שלו שונה לחלוטין מ- integer או double או כל דבר אחר שאנחנו מכירים משפות תכנות. וגם לגבי הביצועים יש תפיסה מוטעית.

מה זה בכלל הטיפוס הזה number?

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

כמה מקום number תופס?

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

נתחיל מדוגמא פשוטה, המספרים 1, 1000 ו- 1001, ונבדוק כמה מקום כל מספר תופס בפועל (הרי אנחנו כבר יודעים ש- number הוא דינאמי). לצורך זה נשתמש בפונקציה vsize:

SQL> create table test_number(n number);
Table created.

SQL> insert into test_number values(1);
1 row created.

SQL> insert into test_number values(1000);
1 row created.

SQL> insert into test_number values(1001);
1 row created.

SQL> select n,vsize(n) from test_number;

N          VSIZE(N)
---------- ----------
1             2
1000          2
1001          3

אפשר לראות שהמספרים 1 ו- 1000 תופסים 2 בתים, אבל 1001 תופס 3 בתים.

איך number נשמר באורקל

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

SQL> select n,dump(n) from test_number;
N          DUMP(N)
---------- -------------------------
1          Typ=2 Len=2: 193,2
1000       Typ=2 Len=2: 194,11
1001       Typ=2 Len=3: 194,11,2

קודם כל נבין מה dump מחזיר לנו. הפלט שאנחנו מקבלים מ- dump כולל 3 חלקים: Typ שזה טיפוס המידע (במקרה שלנו הערך הוא 2 המייצג number), Len הוא גודל המידע בבתים, ואחרי הנקודתיים נקבל את המידע עצמו.

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

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

המידע שאנחנו מקבלים מ- dump מורכב משני חלקים:

  1. הבית הראשון (8bit) מורכב גם הוא משני חלקים, הביט השמאלי ביותר (most significant bit) הוא ביט הסימן. הוא יהיה 1 אם המספר חיובי ו- 0 אם הוא שלילי. שאר 7 הביטים מייצגים את המעריך (exponent) של המספר כדי לדעת היכן נמצאת הנקודה העשרונית.
  2. שאר הבתים מכילים את המספר עצמו בבסיס 100, כלומר כל בית מכיל 2 ספרות עשרוניות של המספר שלנו.

כדי להציג את זה ויזואלית, dump של מספר נראה ככה:

SEEEEEEE DDDDDDDD DDDDDDDD …..

כאשר הבית השמאלי מורכב מביט אחד S שהוא הסימן (1 חיובי, 0 שלילי), שאר הביטים של אותו בית (מסומנים ב- E) הם המעריך וכל שאר הבתים הם המידע (מסומנים ב- D).

מספרים חיוביים:

במספרים חיוביים נצטרך לבצע את השלבים הבאים:

  1. כדי לקבל את המעריך (exponent) האמיתי נצטרך להחסיר 64 מהמעריך (7 הביטים הימניים של הבית הראשון).
  2. נצטרך להחסיר 1 מכל בית המכיל מידע (כלומר כל בית חוץ מהראשון שהוא הסימן והמעריך).

דוגמא:

המספר 1001 מיוצג של ידי 3 בתים 194,11,2. הייצוג הבינארי של 194 הוא 11000010 כלומר המספר חיובי והמעריך הוא 2 (1000010 זה 66, נחסיר 64 ונקבל 2). הבית השני הוא 11, נחסיר 1 ונקבל 10. והבית השלישי הוא 2, נחסיר 1 ונקבל 1 (שזה בעצם 01). לכן, הספרות של המספר שלנו הן 1001 והמעריך 2, לכן המספר הוא 1001.

דוגמא נוספת:

המספר 111.222 מיוצג על ידי 194,2,12,23,21. ראינו כבר ש- 194 אומר שהמספר הוא חיובי עם מעריך 2. נחסיר מכל הבתים 1 ונקבל 01,11,22,20. כלומר הספרות הן 01112220 עם מעריך 2. מכאן שהמספר האמיתי שלנו הוא 0111.2220 שזה 111.222.

מספרים שליליים:

במספרים שליליים צריך לבצע עוד שני שלבים:

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

ודבר אחרון לגבי מספר שלילי, זה שהוא תמיד נגמר בבית 102.

דוגמא:

המספר 12300- מיוצג על ידי 60,100,78,102. 60 בבינארי זה 00111100, כלומר המספר שלילי. נבצע משלים ל- 1 למעריך ונקבל 1000011, כלומר 67. מכאן המעריך הוא 3. הבית האחרון הוא תמיד 102, משני הבתים האחרים שהם המידע נחסיר 1 ונקבל 99,77. נחסיר אותם מ- 100 ונקבל 01,23. כלומר הספרות הן 0123 עם מעריך 3, והמספר שלילי ולכן הוא 12300-.

הבנו, אבל זה נורא מוזר, מה ההגיון?

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

  1. אם אורקל היו משתמשים במספר כמו בשפת תכנות (integer, long, double וכו'), היתה תלות מלאה במערכת ההפעלה, כלומר, מספרים במערכות 32bit היו שונים ממספרים במערכות 64bit וגם בין מוערכות הפעלה שונות, והיתה בעיה אמיתית להעביר מידע בין מערכות שונות (גם ב- export/import מה שהיום אפשר לעשות תמיד ובין כל מערכות ההפעלה).
  2. בנוסף, במודל של שפות התכנות, המספר הכי גדול שהיינו יכולים לייצר הוא מספר בן 10 ספרות (במערכות 32bit) או 19 ספרות (במערכות 64bit), בעוד שבמודל הנוכחי אפשר להגיע עד מספרים בעלי 38 ספרות. יכול להיות שמספרים בעלי 19 ספרות הם מספיק גדולים, אבל מספרים בעלי 10 ספרות בלבד הם כנראה לא.
  3. ודבר אחרון, וזה מה שטום קייט ענה לי כששאלתי אותו את השאלה הזאת, הוא דיוק. אם משתמשים ב- float או double קיים איבוד של מידע, חלק קטן מהמספר עלול ללכת לאיבוד (לדוגמא המספר 1 הוא לא באמת מיוצג כ- 1 אלא 0.999999999 שמתורגם ל- 1 כשמציגים אותו). במערכות פיננסיות למשל, הדבר הזה עלול לגרום להפסדים של כסף וזה ממש לא מומלץ. מצד שני, קראתי לאחרונה שגם ב- number של אורקל עלול להיות אובדן של מידע במספרים במקרים מסויימים. אתם מוזמנים להסתכל ב- Oracle Magazine האחרון (יולי-אוגוסט 2011) בעמוד 61 או בלינק הבא, תחת הכותרת "What is 1/19":

    http://www.oraclemagazine-digital.com/oraclemagazine/20110708?pg=64#pg64

ביצועים

ובסופו של דבר הגענו לנושא הביצועים. כפי שפתחתי את הפוסט הזה, יש אנשים שחושבים שעמודה מספרית יעילה יותר כי היא יותר טבעית למעבד. זה באופן עקרוני נכון, אבל במקרה שלנו ראינו שאורקל משתמשים במודל שהוא לא ממש מספרי ולא ממש טבעי למעבד (וגם לנו). בסיס הנתונים נדרש לבצע הרבה מניפולציות על מנת לבצע השוואות וחישובים מתמטיים. מכאן שההבדל בביצועים כנראה לא יהיה משמעותי וכך גם הגודל. למשל המספר 1234 מיוצג על ידי 194,13,35 ולעומתו, הטקסט 1234 מיוצג על ידי 49,50,51,52. המספר קטן מהטקסט רק בבית אחד, והשוואה של מספר אחד לשני כנראה לא יותר יעילה מהשוואה בין טקסט אחד לאחר.

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

לא מאמינים לי? תנסו בעצמכם.

מקורות מידע

כל מה שהסברתי פה לגבי מבנה של מספרים באורקל נמצא ב- My Oracle Support, ב- Note מספר 1007641.6.

את בדיקות הביצועים עשיתי לבד.

כרגיל, מקווה שנהנתם, למרות שהיה ארוך וטכני מהרגיל.

נתראה ברשומה הבאה !

לירון אמיצי.

<

p style="direction: rtl;">ניתן ליצור קשר עם לירון דרך עמוד האודות שלו: אודות

The following two tabs change content below.
ירון אמיצי הוא סמנכ"ל שירותי מומחה בחברת בריליקס ו-DBA בכיר בעל נסיון של למעלה מ- 15 שנים. ללירון תואר Oracle Ace ומתמחה בנושאי ביצועים, תשתיות, פתרונות זמינות גבוהה, גיבויים ושחזורים. ללירון יש גם בלוג עצמאי בכתובת: https://amitzil.wordpress.com

3 תגובות ל- “איך מספרים נשמרים באורקל?”

commenter

מאמר מקצועי מאוד ובהיר גם ל-"אורחים" בתחום ולא רק DBAים ותיקים.
נהניתי והחכמתי – תודה לירון.

commenter

תודה אייל,

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

לירון

david Itshak | 25/09/2011 בשעה 02:07
commenter

ראו את ההרצאה האחרונה שלי בכנס DBA צפון
When ODAC ,Oracle Sever 11GR2, Win HPC Server 2008 Come together…
Oracle & ilOUG DBA North Forumhttp://www.iloug.org.il/DBA_NorthForum.php AGENDA•A background on HPC architecture
יש לי מספר שקפים בנושא :
תחת:
BINARY_FLOAT and BINARY_DOUBLE performance of NUMBER data type-1

השאר תגובה:

שם (חובה):
אימייל (לא יפורסם) (חובה):
תגובה (חובה):

*



מאמרים קשורים

Baruch Osoveskiy

תיקון מהיר לדיסק איטי

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

OS Background operations

אורי לרנר בטיפ קצר ושימושי על העברת פעולות לרקע במערכת [...]
רשימת

רשימת הפיצ'רים החדשים של אורקל 12.1

אורקל פרסמו את הספרות הרשמית לגרסה 12.1 שיצאה לאחרונה וזמינה להורדה. בין שאר הספרים (החשובים כל אחד שלעצמו), פורסם הספר המסקרן ביותר בעיני – Oracle Database 12c Release 1 (12.1) New Features. זהו ספר שראוי שכל DBA [...]
גרסת

גרסת אורקל 12c זמינה להורדה

בשעה טובה ולאחר המתנה סופר ארוכה, גרסת אורקל 12c (גרסה 12.1) זמינה סוף סוף להורדה רשמית מהאתר של אורקל. הגרסה החדשה מנסה לתת פתרונות לעולם ה"ענן" – ומוסיפה פיצ'רים חדשים שבאים לתת מענה בדיוק [...]
Copyright 2019 ilDBA Portal. Brought to you by Brillix - Israel Leading DBA company. Sponsored by: DBSnaps - Database Video Tutorialss
Website Security Test
%d בלוגרים אהבו את זה: