קטגוריה: firebird

Firebird 3.0

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

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

לFirebird יש מספר תחבירי SQL, וחשוב להבין אותם לפני הבנה של התכונות החדשות. סוג התחבירים הם:

  • DSQL
  • ESQL
  • PSQL

DSQL – הם בעצם השאילתות שכותבים ומריצים בצורה דינאמית באמצעות API. המקדם D מייצג את המילה Dynamic.
ESQL – הם בעצם שאילתות עם preprocessor, כאלו שכותבים למשל דרך תוכנה שלנו. ההבדל בינה לבין DSQL היא שבשפה זו משתמשים בפקודה EXEC. הפירוש של המקדם E מייצג את המילה Embedded.
PSQL – השפה שבה כותבים stored procedure וטריגרים. המקדם של P מייצג את המילה Procedural.

בנוסף ישנה שפה בשם DDL – ‏Data Definition Language. זו השפה בה עושים פעולות כדוגמת create table או create database.

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

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

SQL – כלל השפות:

  • Merge Syntax
  • פונקציות window
  • תמיכה ב regex בביצוע SUBSTRING
  • נכנס סוג נתונים בשם Boolean
  • יכולת לשמור גרסאות עם RDB$RECORD_VERSION
  • cursor יציב

PSQL:

  • פונקציות SQL
  • פרוצדורות
  • טריגרים, פונקציות ופרוצדורות משפות חיצוניות
  • חבילות
  • חריגות עם פרמטרים
  • SQLSTAT במצב של WHEN
  • שימוש ב continue בתוך לולאות.
  • cursor יכול להחזיר התייחסות כמשתנה מסוג רשומה
  • cursor דו כיווני

DDL‏:

  • תמיכה במצב null של עמודה ו domain
  • היכולת לשנות קידוד ברירת המחדל של מסד הנתונים
  • הוספה של Identity Column – המקביל ל serial בPG ו Auto Increment של SQLITE ו MySQL
  • תחביר עבור RECREATE SEQUENCE/GENERATOR
  • טריגרים עבור DDL
  • תמיכה ב DATABASE LINGER

אבטחה:

  • תמיכה database encryption
  • תמיכה מורחבת יותר בהרשאות Object
  • הרשאות לעבודה עם DDL
  • הרשאות ברמת מסד הנתונים
  • תוספות לעבודה עם Roles

פיקוח:

  • הוספת יכולות נוספות לסטטיסטיקה אודות שאילתות ומסד הנתונים בכלל

אז מה זה כל הסעיפים האלו ? להמשיך לקרוא

Firebird וליברה אופיס

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

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

ביולי 2013, פרסמתי כי Base מקבל תמיכה בFirebird כחלק מפרוייקט SOC.

החל מגרסה 4.2, במידה ומפעילים תמיכה ביכולות נסיוניות, ניתן לקבל תמיכה בFirebird כמסד נתונים embedded עבור Base.
libreoffice base firebird בשביל לקבל תמיכה בדברים ניסיוניים בליברה, פשוט הולכים בתפריט ל Tools משם ל LibreOffice, משם ל Advanced ולוחצים על Enable experimental features.

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

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

לאחרונה, גם נראה כי מפתחי Kexi כבר מדברים על הוספת מנוע  embedded של Firebird, אפילו ניתן לראות כי זה מופיע ברשימת הדריברים במימוש.

ניתוח כושל והתמודדות עם מסד נתונים בעייתי

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

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

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

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

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

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

$ gfix -shut -user sysdba -password masterkey <database>.fdb

ואז להעזר ב gbak אשר מאפשר לעשות גיבוי "חם", כלומר בזמן שדברים בד"כ רצים, על ידי יצירת מצב של snapshot לדברים, אך ללא שימוש ב Garbage Collection:

$ gbak -b -g <database>.fdb

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

$ gbak -c database.gbak  db2.fdb

ב firebird למי שאינו יודע, יש טבלאות פנימיות, חלקן שומרות audit על כל פעולה, כולל חיבורים, למסד הנתונים, פעולה אחרונה, וכיוב' …
אך המידע שם לא הצליח לסייע לי.
אז ניסיתי לפנות ללוגים. ניתן לגרום לFb ליצור לוג פר חיבור משתמש, אך הסתבר כי הוא לא הגדיר כזה, ולכן לא היה ניתן בכלל לראות פעולות ישנות בלוגים.

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

Firebird פוגש את ליברה אופיס

פרוייקט הפיתוח GSOC מבית גוגל כמובן, הביא לכך שנכון לשבוע שעבר, יש דריבר רשמי לFirebird בתוך LibreOffice Base.

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

על מנת לגרום לו לעבוד בקובץ odb, יש לשנות הגדרות של

EmbeddedDatabases/DefaultEmbeddedDatabase/Value

מהערך של

sdbc:embedded:hsqldb

לערך:

sdbc:embedded:firebird

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

הבלוג המקורי בנושא. קוד המקור בgit.
 

My first python application

It's that time of the thing again – I'm required to learn new technology due to a project requirement.
The requirement is to write something using django, but I do not know django or Python.

So I've started my first project using the Python language, just to have a feel for it.

My first project is to convert my (in)famous quote file into a database, so I choose Firebird db for the task, using Python driver named fdb. It is very robust open source RDBMS, that many people over look, and choose unreliable RDBMS known as MySQL/MariaDB instead (but why ?!).
Here is the DDL of my database, it's simple as you can see, but has so much abilities 🙂

My code is not perfect, and require a lot more optimization, and polishing, but I'm getting there using the help of my friend – Meir, who loves the idea that a Ruby dev like myself arriving into the python world 🙂

gbak ויכולותיו

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

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

יש לה הרבה יכולות כדוגמת:

  • המרה בין סביבה לסביבה (למשל Little/Big Endian,‏ 32 מול 64 ביט וכו)
  • דחיסת מידע וניקוי המידע שנשמר ממחיקות (למשל)
  • שינוי פעולות אבטחה, כדוגמת שינוי משתמש ו/או סיסמה למסד הנתונים
  • גיבוי למספר קבצים קטנים את המידע של מסד הנתונים
  • שדרוג בין גרסאות של השרת, ובכך להמיר דברים לפי הצורך

ועוד פעולות נוספות, כדוגמת שחזור אותו המידע 🙂

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

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

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

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

יצירת מסד נתונים בזמן ריצה

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

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

createdb

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

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

לאחר מכן, באירוע של הכפתור, אצור את הקוד הבא:

procedure TfrmDBCreate.btnCreateClick(Sender: TObject);
var Transaction : TSQLTransaction;
begin
  FBConnection.DatabaseName := edtDatabaseName.Text;
  FBConnection.CharSet      := 'UTF8';
  FBConnection.HostName     := edtHost.Text;
  FBConnection.UserName     := edtUserName.Text;
  FBConnection.Password     := edtPassword.Text;
  Transaction               := TSQLTransaction.Create(nil);
  FBConnection.Transaction  := Transaction;
  try
   FBConnection.CreateDB;
   FBConnection.ExecuteDirect('CREATE table test1 (name varchar(24) not null)');
   Transaction.Commit;
   MessageDlg('Info', 'The database was created.', mtInformation,
             [mbClose], -1);
  except
    on e : EIBDatabaseError do
     begin
       MessageDlg('Error', 'Could not create database : ' + LineEnding +
                  e.Message, mtError, [mbClose], -1);
     end;

     on e : Exception do
       begin
        MessageDlg('Error', 'Unknown error : ' + LineEnding + e.Message,
                 mtError, [mbClose], -1);
       end;
  end;
  Transaction.Free;
end;

קודם כל אנחנו מזינים לTIBConnection את הפרמטרים שהוזנו, כדוגמת קובץ מסד הנתונים, הכתובת של השרת, בנוסף החלטתי להשתמש ב UTF8 כקידוד למחרוזות.
בנוסף יצרתי רכיב עבור טרנזאקציות, הוא צריך להיות בשימוש לשאילתא שאריץ לאחר יצירת מסד הנתונים (כל השימוש בו).
בתוך try אני אומר למנהל החיבור למסד נתונים ליצור את מסד הנתונים. חשוב לדעת כי זה קיים בכל החיבורים שלנו למסדי נתונים המבוססים DataSet, ולא ייחודי ל Firebird.
לאחר מכן, החלטתי גם להציג כיצד ניתן ליצור בתוך אותו קוד טבלה, אז יצרתי טבלה בשם test1 עם שדה בשם name שהוא מסוג varchar ומסוגל לקבל עד 24 תווים.
נעשה על השאילת commit, ואנחנו מוכנים !

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

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

את קוד המקור תוכלו למצוא כאן
 

באג מעניין בFirebird

ביום שישי חברה המספקת שירותים למספר בנקים ומשרדים ממשלתיים ברוסיה, דיווחה על קריסה מאוד מעניינת של Firebird בשרת שלהם.

יש להם שרת בנראה ככה בשעות שנחשבות ל idle:

top - 03:20:39 up 10 days,  8:39,  7 users,  load average: 2.08, 1.87, 2.15
Tasks: 1732 total,   1 running, 1730 sleeping,   1 stopped,   0 zombie
Cpu(s): 11.9%us,  4.0%sy,  0.0%ni, 83.5%id,  0.0%wa,  0.0%hi,  0.6%si,  0.0%st
Mem:  529177288k total, 378587600k used, 150589688k free,   761532k buffers
Swap: 1073741816k total,   130612k used, 1073611204k free, 333281232k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
15840 t-mvv     20   0 33.3g 9.1g  25m S 209.9  1.8 932:23.24 java
15931 root      20   0  578m 226m 165m S 75.3  0.0 286:12.21 rdb_inet_server
16101 root      20   0  486m 198m 164m S 41.4  0.0  60:34.22 rdb_inet_server
15897 root      20   0  956m 509m 166m S 21.5  0.1 126:36.86 rdb_inet_server
46960 qemu      20   0 1365m 1.0g 2156 S  5.2  0.2 973:33.28 qemu-kvm
61680 qemu      20   0 1366m 1.0g 2536 S  4.6  0.2 934:21.36 qemu-kvm
24615 root      20   0  466m 112m  96m S  3.6  0.0   0:08.07 rdb_inet_server
...

[root <at> mvv bin]# ps aux | grep -c rdb_inet_server
719

Database is on a small FusionIO drive:

mount:
/dev/fiob on /mnt/db type ext2 (rw,noatime)

df -h:
/dev/fiob             587G  423G  135G  76% /mnt/db

ls -l:
-rw-rw---- 1 root root 453031493632 Feb 11 03:26 ncore-mvv.fdb

מסתבר שכאשר שרת מסד הנתונים מגיע להגבלה של 2 גיגה לנעילה (הגבלה של מערכת ההפעלה עד כמה שאני מבין) הוא קורס.
עכשיו בשביל להסביר לכם את הנתונים קצת יותר, בשעות ה idle היו כ 2,500 חיבורים פעילים למסד הנתונים שבצעו פעולות.

להמשך קריאה ואולי אף מעקב בעתיד.

קבלת רשימה דינאמית של העמודות של כל (חלק) הטבלאות במסד הנתונים

קראתי פוסט ממש מעניין בנושא שכתב אדם בשם Jiří Činčura :

"נשאלתי שאלה לפני שבוע. היא היתה פשוטה מאוד. במידה ואקבל רשימה של עמודות בצורה מסודרת, הייתי רוצה לסרוק את כל הטבלאות (עם מספר תנאים) עבור השמות האלו, ולקבל את התשובה חזרה. זה היה Firebird, אז מייד קפצתי לתוך טבלאות המערכת ויצרתי שאילתא 'on the fly' בתוך execute block, המוכר גם בשם anonymous stored procedure."

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

חדשות Firebird

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

החל מגרסה 5.3.9, התמיכה של PHP ב Firebird באמצעות PDO סוף כל סוף מתפקדת כמו שצריך, ועכשיו ניתן יהיה להשתמש ב binding למשל, ולא יהיו יותר בעיות בין אותיות קטנות וגדולות. גם הספירה של כמות השדות תהיה נכונה, ולא תציג פחות תוצאות ממה שיש באמת.

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

בנוסף, אפשר להתחיל להנות מהרצאות על Firebird ובכלל סרטונים על Firebird בערוץ SQLFirebird ב Youtube.

תהנו מהרצאה של Ann Harrison (אחת מהממציאים של מסד הנתונים המקורי):

קישור ל"מדוע firebird עדיף מOracle"

כותב הבלוג Backwards compatible, מנהל למעלה מ600 מסדי נתונים מבית אורקל, ו60 מסדי נתונים של Firebird, מסביר מדוע לדעתו Firebird הוא מסד נתונים שעדיף לכם לקחת עבור העסק שלכם, במקום אורקל.

Common Table Expression

בתקן SQL 99, נוספה תמיכה לביטוי רב עוצמה אשר קיבל את השם Common Table Expression או CTE בקיצור.

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

CTE בעצם מאפשר לנו ליצור מעין טבלה זמנית עבור code block של SQL. כלומר נגיד ויש select קבוע שאני רוצה עליו לבצע עוד select, אבל הselect המקורי מכיל כל מיני תנאים וכו', ויותר מזה, יכול להיות שאני רוצה להשתמש באותה שאילתא ביותר ממקום אחד, אז CTE בעצם נכנס לשימוש. הוא יודע להגיע ב"טעם" רגיל וב"טעם" שהוא רקורסיבי:

with Machines as (
  select id, type, name, ip
from Computers
where type in (1, 8, 34) and ip like '192.168%'
);

select user
from CompanyUsers cu
left join Machines on cu.machine = Machines.id;

עוד צורת שימוש שיש ל CTE היא בצורה רקורסיבית על המידע:

with recursive
  dept_year_budget as (
    select fiscal_year,
           dept_no,
           sum(projected_budget) as budget
    from proj_dept_budget
    group by fiscal_year, dept_no
  ),
  dept_tree as (
    select dept_no,
           head_dept,
           department,
           cast('' as varchar(255)) as indent
    from department
    where head_dept is null
    union all
    select d.dept_no,
           d.head_dept,
           d.department,
           h.indent || '  '
    from department d
         join dept_tree h on d.head_dept = h.dept_no
  )
select d.dept_no,
       d.indent || d.department as department,
       dyb_2008.budget as budget_08,
       dyb_2009.budget as budget_09
from dept_tree d
     left join dept_year_budget dyb_2008
       on d.dept_no = dyb_2008.dept_no
       and dyb_2008.fiscal_year = 2008
     left join dept_year_budget dyb_2009
       on d.dept_no = dyb_2009.dept_no
       and dyb_2009.fiscal_year = 2009

Would you like to be FB maintainer ?

Several months ago, I removed myself as Firebird package maintainer at Arch Linux (AUR). The reason was lack of time by my side, and a lot of work is still needed to be made with the packages.

So I removed myself, in order to allow other person to take charge of it, but no one raised the orphan packages (and they are looking for a warm home, with good parent. Really, they are good packages), and AUR does not have very good FB packages because of it.

Would YOU like to be the package maintainer ? To follow the Firebird community, in sickness and in health ? To fix issues, and make the best effort to make it work for everyone ?

ניהול מפתחות

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

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

אני מקווה כי 2 הקישורים האלו יעזרו לכם בנושא של מסדי נתונים.

עריכת הערך של Firebird בוויקיפדיה העברית

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

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

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

מבט ראשוני על Firebird 3.0

Firebird 3.0 עוד לא יצא, אבל יצאה מצגת המציגה מה הם השינויים העיקריים אשר אמורים להיות בגרסה זו.

הדגשים העיקריים של Firebird 3 הם:

  • תמיכה טובה יותר בריבוי מעבדים ו SMP בכלל, עם cache משותף
  • חידוש הארכיטקטורה לגרסאות הבאות

הדגשים המשניים של Firebird 3 הם:

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

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

עדכוני חבילות בArch Linux

קרו 2 דברים השבוע בכל הקשור לחבילות בArch Linux אליהם אני קשור:

  1. החבילה שלי של libfbclient עבור גרסה 2.5 של firebird הועברה מ AUR ל community
  2. עדכנתי את החבילה של firebird-superclassic

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

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

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

האם המפתחות שלכם יעילים ?

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

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

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

Firebird SQL מספק לנו יכולת של הבנת יעילות של מפתח על ידי יצירת סטטיסטיקה על כל מפתח שנוצר במסד הנתונים (הוא לא מסד הנתונים היחיד שעושה את זה, גם PostgreSQL ו MS-SQL עושים את זה עד כמה שאני יודע). כל מפתח מקבל שם ייחודי שאפשר למצוא אותו בטבלה בשם RDB$INDICES.

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

SET STATISTICS INDEX index_name;

כלומר ללכת לאינדקס שאנחנו רוצים (לפי השם ב RDB$INDICES ולא השם של השדה בטבלה) ולהגיד לו לאסוף מחדש את הסטטיסטיקה עליו.

ואם רוצים לעשות את זה עבור כל המפתחות בפעם אחת, אפשר פשוט ליצור בלוק ריצה כזה (או כ stored procedure): להמשיך לקרוא

Strawberry Perl תומך ב DBD-Interbase

מריוס פופה פרסם סרטון ווידאו (מאוד מצחיק לדעתי :)) וגם הסבר בFirebirdnews כיצד אפשר להשתמש בגרסאות הפיתוח האחרונות של DBD-Interbase בייחד עם Strawberry Perl, כך אפשר להנות גם מעבודה עם Firebird גם בWindows כאשר משתמשים בגרסה הזו של פרל ל windows.

שדה עם זהות

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

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

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

אז איך זה נראה ? התחביר היבש הוא כזה:

<column definition> ::= <name> <type> GENERATED BY DEFAULT AS IDENTITY <constraints>

בפועל, התחביר יראה בצורה הבאה:

create table objects (
  id integer generated by default as identity primary key,
  name varchar(15)
);

insert into objects (name) values ('Table');
insert into objects (name) values ('Book');
insert into objects (id, name) values (10, 'Computer');

select * from objects;
          ID NAME
============ ===============
           1 Table
           2 Book
          10 Computer

וההגבלות הן מאוד פשוטות: צריך מספר שיכול להתחיל ב0, כלומר:

smallint, integer, bigint, numeric(x, 0) , decimal(x, 0)

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

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

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

שדות בוליאניים ב firebird

גרסה 3 של Firebird הולכת בין היתר להכיל שדות מסוג Boolean בתוכם. זה הפיטצ'ר שהיה במקום השלישי מבחינת הקולות בבקשות לפיתוח Firebird – כאמור בגרסה 3 הוא מתקיים.

המפתח של התמיכה, השקיע המון מחשבה בנושא ולא יישם את התמיכה "על רגל אחת". ובכך הוא הכיר לנו טיפוס מסוג BOOLEAN, אשר יכול להכיל ערכים של TRUE, FALSE ו UNKNOWN/NULL (שניהם זהים בהתנהגות שלהם).

בנוסף, שדה מסוג BOOLEAN יכול להיות מפתח וכך אפשר לחפש לפיו, לחתוך לפיו, לסדר לפיו וכיוב'…

על מנת לחפש עם מפתח מסוג בוליאני, הוא יצר פעולה חדשה בשם IS כלומר:

field IS FALSE
field IS TRUE
field IS UNKNOWN

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

"field1 OR field2" and "NOT field1"

הוא חוקי לגמרי.

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

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

Firebird 2.5 שוחררה

בשעה טובה ומצולחת שוחררה היום (04.10.2010) גרסה חדשה של firebird : 2.5. הגרסה מכילה בתוכה בראש ובראשונה שכתוב מלא של מערכת ה threading של מסד הנתונים, אשר מאפשרת לעבוד טוב יותר מול SMP וזו הסיבה לגרסה הזו, אך זה לא כל השינויים שנמצא בגרסה הזו. הגרסה הזו ד"א היא עוד צעד (מאוד חשוב) לגרסה 3.

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

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

  1. תמיכה טובה יותר ב Audit ו trace – יש עוד יותר תעוד על מי ביצע איזו פעולה באיזה שלב ובאיזו צורה (נשמר במסד הנתונים עצמו כמו תמיד), כולל בזמן אמת, וכן אפשרי לצפייה פר חיבור (סשן) ספציפי.
  2. יכולת של משתמש ספציפי לדעת מה הוא עשה (עבודה עם audit).
  3. האצלת סמכויות של SYSDBA. כאשר המשתמש יכול במסד נתונים ספציפים לתת חלק מיכולותיו למשתמשים אחרים בהתאם לצורך.
  4. ביטול חיבורים בצורה אסינכרונית
  5. נוספה תמיכה לעבודה ב Regex עם תחביר של SIMILAR TO
  6. ניתן לשנות (ALTER TABLE) שדה שהוא Computed By
  7. טרנזאקציות אוטונומיות בPSQL (כלומר התחביר של טריגרים, Stored Procedures וכו')
  8. תמיכה טובה יותר לגישה של Stored Procedure תחת View
  9. תמיכה של GRANTED BY וGRANTED TO (וגם של REVOKE) בשביל לספק הרשאות עבור משתמשים אחרים (בדומה ל sudo ביוניקס).
  10. ביטול הרשאות כללי על ידי שימוש בתחביר של REVOKE ALL, ובכך לבטל בצורה מיידית את כל ההרשאות של משתמש מסויים
  11. תמיכה בתנאים של WHERE SOME_COL = ? OR ? IS NULL
  12. נוספה פונקציה חדשה עבור תמיכה בעבודה עם UUID התואמת לRFC4122
  13. נוספה האפשרות להוסיף למספר שלם בגודל 32 ו64 ביט, מספר הקסה דצימלי בצורה מילולית.
  14. נוספה יכולת הגדרה עבור ברירת מחדל של מסד הנתונים עצמו לCOLLATE.
  15. שינוי COLLATE על בסיס סוג קידוד השפה
  16. gbak משחזר טוב יותר קידוד שפה, כאשר הדגל של הקידוד לא קיים בגרסאות ישנות יותר
  17. תמיכה בחיבורים למסד נתונים אחר, גם אם הוא לא נמצא פיזית בשרת שאנחנו שייכים אליו כחלק משאילתת SQL.

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

להכרזה הרשמית: http://www.firebirdsql.org/pop/pop_pressRelease25.html

להורדה: http://www.firebirdsql.org/index.php?op=files&id=engine_250

מה שאפשר לעשות עם stored procedures

MindTheBird יצרו תחרות עבור Stored Procedures מעניינים. ופרסמו את שמות הזוכים בתחרות עם ה Stored Procedure שהם יצרו.

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

הזוכים יצרו את ה SP הבאים:

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

קצת סטטיסטיקות לגבי Firebird

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

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

בקשר לFlamerobin, הסביבה שהכי נפוצה בשבילו היא דווקא Windows

טיפ לעצמי: Jruby + Firebird Events

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

קוד הרובי:

#!/usr/bin/env jruby
require 'rubygems'
require 'java'
require 'date'

class Test
  def initialize
    @event_manager = org.firebirdsql.event.FBEventManager.new(Java::org.firebirdsql.gds.impl.GDSType.getType('PURE_JAVA'))
    @event_manager.setDatabase('/tmp/jtest.fdb')
    @event_manager.setUser('sysdba')
    @event_manager.setPassword('masterkey')
  end

  def run
    @event_manager.connect
    @event_manager.addEventListener('new_user', self)
    while (true)
      sleep(1)
    end
  end

  def eventOccurred(event)
    puts "[#{DateTime.now.to_s}] #{event.getEventName()}"
  end
end

test = Test.new
test.run

חשוב להבהיר כי למרות ש eventOccurred אינו חוקי כל כך ברובי, אבל הוא מאשר את זה בכל זאת, רק ה IDE שאני משתמש בו לא מאושר מזה כל כך 🙂

טיפ לעצמי: שימוש בjruby ו jdbc לעבודה עם firebird ו dbi

אני ממשיך בניסויים שלי עם jruby וכמובן FirebirdSQL. הרבה אנשים לא מבינים למה, אז התשובה היא פשוטה: אני מחפש כלים פשוטים, אמינים שעושים לי חיים קלים לתחזוקה ועבודה. השימוש ב JRuby הוא כאמור בגלל התמיכה שלו ב thread, אבל אם כבר משתמשים ב JVM, אז בואו נשתמש בזה איפה שאפשר להנות ממנו בכל מקום, ולכן השימוש שלי עם Firebird הוא באמצעות JDBC. בחרתי דווקא ב DBI ולא ב ActiveRecord בגלל שהתמיכה של ActiveRecord ב JDBC ממש לא עובדת לי כמו שצריך (ניסיתי עם עוד כמה מסדי נתונים), ואחרי יותר מידי שעות של מאבקים שבהם אפילו הצלחתי להרוס לגמרי את PosgreSQL (המסד נתונים הנוסף שניסיתי) בצורה שגם הסרה מלאהו התקנה מחודשת לא מתקנת, נשברתי ואני חוזר לעבוד עם DBI ו JDBC. כאן לקח לי מאוד מהר לגרום לדברים לעבוד כמו שצריך (פחות מ10 דקות במקום 8 שעות של אתמול והיום מאבק עם ActiveRecord).

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

#!/usr/bin/env jruby

require 'rubygems'
require 'java'
require 'dbi'

dbh = DBI.connect('DBI:Jdbc:firebirdsql:localhost:jtest',
'sysdba', 'masterkey', 'driver' => 'org.firebirdsql.jdbc.FBDriver')

begin
  puts dbh.select_one "SELECT name FROM users"
ensure
  dbh.disconnect if (not dbh.nil? && dbh.connected?)
end

וכאמור זה עובד כבר מפעם הראשונה שניסיתי.

טיפ לעצמי: Firebird Events, Java, JayBird

אני עושה ניסויים עם JRuby. הבעיה שלי היא שאין לי ברובי תמיכה באירועים של Firebird ואין לי זמן ללמוד להוסיף את התמיכה הזו לרובי, ולכן אני מנסה ללמוד לעבוד עם האירועים של JayBird לג'אווה. השימוש שלי ב JRuby אם מישהו סתם רצה לדעת הוא דווקא בגלל הצורך שלי להשתמש בThreads, ולצערי ברובי 1.8 הם עדיין ירוקים, ולכן אני נאלץ לעבוד עם JRuby.

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

הקוד של מסד הנתונים לבדיקה: להמשיך לקרוא

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

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

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

0.1+0.2 = ?

חידה קטנה: אם אני עושה בשפת מחשב (כולל מסדי נתונים) את החישוב הבא:

0.1+0.2

מה תהיה התוצאה ?

התשובה היא שזה תלוי.

במה זה תלוי ? ובכן זה תלוי במהדר/מפרש, וזה תלוי בסטנדרט שאותו מפרש/מהדר משתמש בו.

למעשה השפה היחידה עם 2 מהדרים שניסיתי שנתנה את התשובה 0.3 היתה פסקל על FPC (אין לי דלפי לנסות עליו).

מבחינת מסדי נתונים כל מה שניסיתי (שזה Firebird, MySQL, PosgreSQL) כולם נתנו תשובה זהה לFPC.

שאר השפות החליטו שמדובר בתוצאה של 0.30000000000000004

מהם שאר השפות ?

ובכן

C (gcc), Perl, Ruby, Python, Javascrupt (Firefox), PHP

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

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

התכוננו לביאת הציפור 2.5

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

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

העבודות צריכות להיות מוגשות עד ל15 למרץ וצריכות להיות מוגשות בפורמט ווקטורי או ברזולוציה גבוהה, כאשר הרזולוציה הנמוכה ביותר שתתקבל היא 300dpi.

העבודה חייבת לכלול את הלוגו של Firebird (אין כוונה ליצור לוגו חדש), אלא לציין את חגיגות העשור.

העבודה צריכה להיות מוגשת ב2 סגנונות:

  • סגנון צבע (עם כל הפרטים האפשריים של העבודה)
  • מונוכרום (engraved, laser burned וכו')

כמו כן, האומן צריך להסכים שעבודתו תתפרסם ותהיה נגישה לכל דורש על ידי הכללת העבודה כ public domain.

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

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

פונקציות חלון ב Firebird 3

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

גרסה 3 של firebird מספקת תמיכה בסיסית בתכונות האלו על ידי שימוש ב OVER.

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

שאילתא "רגילה" תראה בצורה הבאה: להמשיך לקרוא

מה מערכת הקבצים הטובה ביותר עבור Firebird ?

במסמך השוחרר השבוע על ידי Philippe Makowski ב IBPhonix המנסה להסביר קצת מידע על מערכות קבצים בלינוקס המתאימות לFirebird מראה מדידה לפי כלי בשם TPC בגרסאות שונות שלא באמת כזה פשוט למדוד ולמצוא מה מערכת הקבצים הטובה ביותר עבור Firebird בלינוקס.

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

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

אזהרה: מדריך זה מאוד ארוך (5 דפים מלאים עם תמונות וקוד).
טבלת authors

כמעט כל מתכנת מגיע לשלב שהוא (או היא) צריכים לטפל במסדי נתונים. כיום יש 3-4 גישות עבודה מקובלות עם מסדי נתונים:

  1. עבודה ישירה מול מסד נתונים ספציפי לפי API של היצרן
  2. עבודה עם ספרייה שמאגדת פונקציות דומות עבור מבחר מסדי נתונים
  3. מימוש עצמי של מסד נתונים (יש חברות בתעשייה שעושות טעויות כאלו)
  4. עבודה עם כלי ORM אשר מנסות להשכיח את העבודה שיש מסד נתונים ומנסה לספק יכולת לעבוד כמה שיותר בתחביר של השפה בה אנחנו עובדים.

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

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

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

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

תשובה לחידה

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

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

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

הערך הקודם פלוס הערך הקודם ושומרת אותו ב sequence בתור הערך הבא. כל זה, כל עוד הערך הוא לא 0 או ריק, כי אז הsequence מכיל את הערך 1.

התוצאה הסופית היא סדרה כזו: 1, 2, 4, 8, 16, 32, 64, 128, 512, 1024 … (דיברתי על 10 הערכים הראשונים).

הפעולה מתבצעת כאמור על ידי פעולת חיבור ולא כפל או חזקה (דיאגו).

במקרה הזה כמו שאפשר לראות, השתמשתי בID (כלומר האינדקס) של הטבלה בשביל להכיל את זה, אבל באותה מידה היה אפשר להכיל את זה על כל שדה מספרי אחר.

השימוש ב GEN_ID מספק את הדרך היחידה לגשת ל sequence בגלל שהsequnce חייב להיות מוגן מפני שינויים רנדומליים ורק שינויים שהתכוונו אליהם חייבים להתבצע בצורה שהיא transaction safe, כך שכל טרנזאקציה תוכל לספק ערך חד חד ערכי בלי קשר לשאר החיבורים והטרנזאקציות האחרות בנושא. זו אחת מהדרישות של מבחן ה ACID עבור מסדי נתונים, וכאמור Firebird עובר בציון של 100 את המבחן. הפונקציה ד"א מעלה את הערך של ה sequence בכמות שאנחנו מספקים לה בפרמטר השני, כך שאם הערך הוא 0, זה בסה"כ מחזיר את הערך של sequence ולא מבצע פעולת חיבור.

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

תודה ללזרוס שהביאני עד הלום

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

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

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

למעט שורת select אחת (נשאר לי עוד ליצור שורות של update, insert ו delete), אין לי ולו שורת קוד אחת שכתבתי, ועדיין יש לי ממשק גרפי שמאפשר לי את כל זה !

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

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

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

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

חידה: מה עושה הקוד הבא ?

יצרתי את הקוד הבא במסד נתונים שלי שעובד עם Firebird SQL, מה הקוד עושה ? למה נבחרה הגישה הזו בשביל לממש את הקוד ואילו תשובות אקבל בהזנת 10 ערכים ראשונים למסד הנתונים עם הקוד הזה ?

IF ((NEW.ID IS NULL) OR (NEW.ID = 0)) THEN
NEW.ID = GEN_ID(GEN_PERMISSIONS_ID, 1);
ELSE
NEW.ID = GEN_ID(GEN_PERMISSIONS_ID, GEN_ID(GEN_PERMISSIONS_ID, 0));

במידה ולא תפתרו את החידה כאן, אענה עליה בשבוע הבא 🙂

שרת סופר קלאסי

כמו שכמה מקוראי יודעים, מסד הנתונים של firebird מכיל 3 צורות גישה למסד הנתונים:

  1. גישת embedded – יש ספרייה משותפת שמקושרים אליה והיא אחראית על הדיבור עם מסד(י) הנתונים, והקוד שלנו נשאר זהה לחלוטין
  2. גישת שרת קלאסי – בנייה של שרת מבוסס תהליכים המתקשרים דרך ipc
  3. גישרת סופר שרת – שרת אחד שמאזין ומקבל בקשות ממש כמו מרבית שרתי מסדי הנתונים למינהם

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

ככה מדווחים באג

בחודש שעבר נשלח באג בקשר ל flamerobin. דיווח הבאג התבצע בצורה יוצאת דופן: דרך YouTube.

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

את הבאג עצמו, אפשר למצוא כאן.

מקור: FlameRobin

טיפ ב firebird – גיבוי חם

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

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

בשביל לגבות את מסד הנתונים בצורה רגילה נעשה את זה בצורה הבאה:

$ gbak -v -t -user SYSDBA -password "masterkey" 127.0.0.1:/path/to/db/data.fdb /path/to/backyp/data.fbk

מה שאמרנו ל gbak לעשות זה לתת לנו תיעוד של מה שהוא עושה (verbose) על ידי שימוש ב -v. אמרנו לו לשמור את מסד הנתונים בצורה שתאפשר גם להגר בין גרסה לגרסה (-t), סיפקנו את השם משתמש והסיסמה, כתובת השרת והמיקום למסד הנתונים ואז אמרנו לו איפה ובאיזה שם לשמור את הגיבוי.

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

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

$ ssh -C -f user@XXX.XXX.XXX.XXX -L 3052:localhost:3050 -N
$ gbak -t -v localhost/3052:
/path/to/db/data.fdb -user SYSDBA password masterkey /path/to/backyp/data.fbk

בואו אסביר קצת את הפקודת SSH:

אמרנו ל ssh לרוץ בצורה דחוסה (-C), ברקע (-f) ויצרנו מנהרה עם -L בפורט 3052 אצלנו במחשב כאשר ssh עצמו אינו מריץ שום shell או פקודה כלשהי (-N).

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

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

טיפ שני ב Firebird

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

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

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

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

אז לשם שינוי השם, אנחנו נשתמש ב 2 השאילתות הבאות:

UPDATE RDB$RELATIONS
SET RDB$RELATION_NAME='NEWNAME'
WHERE RDB$RELATION_NAME='OLDNAME';
COMMIT;

UPDATE RDB$RELATION_FIELDS
SET RDB$RELATION_NAME='NEWNAME'
WHERE RDB$RELATION_NAME='OLDNAME' and RDB$SYSTEM_FLAG=0;
COMMIT;

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

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

חשוב לדעת שאם השתמשנו בשאילתאות, stored procedure, triggers, view וכו' עם הטבלה הישנה, צריך לשנות גם שם את השם לטבלה החדשה, וזה כבר יכול להשתנות ידנית, ממש כמו בשאר מסדי הנתונים שאני מכיר לפחות.

טיפים ב Firebird חלק ראשון

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

select first skip

במידה וצריך להחזיר את ה10 רשומות הראשונות, אפשר להשתמש ב מילה השמורה של first בצורה הבאה:

select first 10 * from table;

ונקבל את ה10 רשומות ראשונות

במידה ונרצה להחזיר רק מהרשומה הרביעית, נשתמש ב select skip:

select skip  3 * from table;

ונקבל את הרשומה הרביעית ומעלה.

ניתן גם לשלב בין first לבין skip:

select first 10 skip 3 * from table;

ונקבל את 10 הרשומות הראשונות מהרשומה הרביעית ועד לרשומה ה13