חידון: Postgres מעמיק: חלק 2
האם אתה SQL פלדה? או SQL רך?
חלק 2 מתוך 2. חזרה לחלק 1
ברוכים הבאים לחלק 2 של חידון ה-Postgres המעמיק שלי!
חידון זה מכסה תערובת של תכונות PostgreSQL מוכרות ופחות מוכרות, לצד מלכודות נפוצות: JOIN, NULL, ANSI SQL, טרנזקציות, פנימיות, אינדקסים, דגימת נתונים… ועוד!
בהצלחה! 🍀
איזה מהבאים אינו ❌ ביטוי JOIN חוקי ב-PostgreSQL?
ידעת על CROSS JOIN, נכון?
האם JOIN ALL גרם לך לחשוב על פעולה אחרת, UNION ALL?
התשובה כאן היא JOIN ALL ❌.
סוגי ה-JOIN הנכונים הם:
INNER JOIN(ברירת המחדל)LEFT JOIN(אוLEFT OUTER JOIN)RIGHT JOIN(אוRIGHT OUTER JOIN)FULL JOIN(אוFULL OUTER JOIN)CROSS JOIN(מכפלה קרטזית, אלא אם סעיףWHEREמאוחר יותר מסנן אותה)
למעט ‘תלוי בתופעות לוואי’ מה קורה לאחר שגיאה?
BEGIN;UPDATE students SET status = 'alumni' WHERE grade = 12;UPDATE students SET graduation_date = CURRENT_DATE WHERE grade = 12;UPDATE students SET grade = 'GRADUATED'; -- 🚨 Error: type mismatchCOMMIT;כאשר מתרחשת שגיאה כאן:
- כל הטרנזקציה כולה מתגלגלת אחורה
- לא מתבצע commit לשינויים
- הטרנזקציה מסומנת כנכשלה
כדי לבצע commit חלקי:
BEGIN;UPDATE ...;SAVEPOINT my_save;UPDATE ...; -- ErrorROLLBACK TO my_save;COMMIT;באיזה תנאי ON יכול PostgreSQL להשתמש עבור HASH JOIN?
SELECT *FROM students aJOIN grades bON /* What goes here? ⁉ */;חיבור Hash אפשרי עם תנאי שוויון (=) בסעיף ON.
=הוא צורת הפרדיקט המפתח עבור חיבורי Hash>ו->=אינם פרדיקטים של חיבור HashHASH JOINאינו תחביר תקין ב-PostgreSQL
המתכנן עדיין עשוי לבחור בלולאה מקוננת או חיבור מיזוג בהתאם לגודל הטבלה, סטטיסטיקות, אינדקסים והגדרות זיכרון.
מה נכון עבור שמות עמודות תלויי רישיות?
CREATE TABLE grades ( "Student Name" VARCHAR(100), 'Student Grade' INTEGER);ב-PostgreSQL:
- מרכאות כפולות (
\") מיועדות למזהים (שמות טבלאות, שמות עמודות) - מרכאות בודדות (
') מיועדות לליטרלים של מחרוזות
שיטות עבודה מומלצות:
- הימנע משילוב רישיות או רווחים בשמות
- השתמש ב-snake_case עבור מזהים
- השתמש במזהים מצוטטים רק כשבהחלט הכרחי
איך מציינים שם עמודה המכיל נקודה?
CREATE TABLE teachers ( id INT GENERATED BY DEFAULT AS IDENTITY, first.name TEXT, -- How do you include the column: first.name? salary NUMERIC);PostgreSQL משתמש במרכאות כפולות לציטוט מזהים:
- מרכאות כפולות
"..."עבור מזהים (שמות עמודות, שמות טבלאות) - מרכאות בודדות
'...'עבור מחרוזות מילוליות - הצורה
first.nameמתפרשת כ-table_name.column_name
ללא מרכאות, נקודה בשם עמודה תתפרש כמפריד סכמה/טבלה! בנוסף, כל המזהים ללא מרכאות מומרים לאותיות קטנות כברירת מחדל.
כדי להפחית הפתעות, עדיף להשתמש ב-snake_case ולהימנע משימוש בתווים מיוחדים.
מהו התחביר התקף לדגימה אקראית של כ־10% מהסטודנטים?
השאלה הזו מסובכת! היא כוללת בערך 6 מלכודות, חלקן:
- תיאור ברמה גבוהה + שברי תחביר. בודקת איך אתה מסתגל ומרכיב מידע חלקי.
- דורשת היכרות עם תחביר
TABLESAMPLE, מכיוון שאף אחת מהאפשרויות שלTABLESAMPLEלא משתמשת בתחביר הנכון! (מרושע, אני יודע! תמשיך, אני מאמין בך!!! ❤️) ROW_NUMBER() OVER (ORDER BY RAND())ו-ORDER BY RANDOM() > 10הם עוד הסחות דעת. הם נראים כאילו הם יכולים להיות נכונים, אבל הם לא.RAND()לא קיים. ו-RANDOM() > 10הוא ביטוי בוליאני שתמיד יהיה false כיRANDOM()תמיד בטווח0.0-1.0. בעיה נוספת:ORDER BY RANDOM() > 10ימיין לפי ערך בוליאני, לא לפי מספר אקראי. אבל ה-> 10הזה בהחלט הרגיש כמו אחוז, נכון?BERNOULLIתקין, אבלSAMPLETABLEלא.WHERE RANDOM() >= 0.1היא מלכודת!RANDOM()מחזירה ערך בטווח0.0 <= x < 1.0, אז>= 0.1תחזיר בערך 90% מהשורות, לא 10%.
לגבי שיטת TABLESAMPLE, PostgreSQL תומך בשתי שיטות דגימה:
BERNOULLI: לכל שורה הסתברות שווהSYSTEM: דגימה ברמת בלוק (מהירה יותר אבל פחות אקראית)
למידע נוסף על דגימה, עיין במאמר זה מ-Render.
דוגמה:
-- Sample 10% of rowsSELECT * FROM students TABLESAMPLE BERNOULLI (10);
-- For repeatable results, use REPEATABLE:SELECT * FROM studentsTABLESAMPLE BERNOULLI (10) REPEATABLE (42);כדאי גם לציין, ש-TABLESAMPLE דווח כלא אקראי במיוחד. אם אתה צריך דגימה יותר אקראית בגודל קבוע, שקול להשתמש ב-ORDER BY RANDOM() LIMIT 10. אבל שים לב שזה מחזיר 10 שורות, לא 10%, ויכול להיות איטי בטבלאות גדולות.
ישנן גם הרחבות צד שלישי המספקות שיטות דגימה אקראיות טובות יותר, אבל זה מחוץ לתחום של זה! 😅
מה הלחש הזה עושה?
CREATE INDEX idx_active_studentsON students(last_name)WHERE status = 'active';הטריק הזה נקרא Partial Index.
הם שימושיים להקטנת השימוש בדיסק ולהאצת שאילתות כאשר רק תת-קבוצה של שורות נשאלת בדרך כלל.
המתכנן יכול להשתמש באינדקס כאשר הוא מוכיח שתנאי השאילתה גורר את תנאי האינדקס. בדיקות ההסקה של המתכנן מוגבלות; תנאי עם פרמטר עשוי שלא להוכיח את התנאי בזמן התכנון. הזכאות לשימוש אינה מבטיחה שהאינדקס ייבחר.
תזכורת: פוסטגרס לא תומך ב’רמזי שאילתות’ כמו RDBMSs אחרים. מתכנן השאילתות יחליט מתי להשתמש באינדקס(ים) המתאימים.
מה עושה EXPLAIN ANALYZE עבור הצהרות UPDATE?
EXPLAIN ANALYZEUPDATE studentsSET grade = grade + 1WHERE status = 'active';EXPLAIN ANALYZE מבצע בפועל את השאילתה! היזהר בעת ניתוח פעולת כתיבה, במיוחד הצהרות UPDATE, DELETE ו-INSERT. ייתכן שתצטרך להריץ פעולות ניקוי לאחר כל EXPLAIN ANALYZE כדי לקבל תוצאות ניתנות לשחזור.
שיטות מומלצות:
- השתמש ב-
EXPLAIN(ללא ANALYZE) עבור UPDATE/DELETE/INSERT - עטף שינויים בטרנזקציות:
BEGIN;EXPLAIN ANALYZE ...;ROLLBACK;כל הכבוד! התעמקת בכמה תחומים של PostgreSQL! 🐘
אני מקווה שלמדת משהו חדש, או לפחות קיבלת ציון להתפאר בו! 🏆
רוצה עוד ריגושים בחיים? בדוק את אוסף החידונים שלי לכיף אינסופי*!
