Quiz: Tiefes PostgreSQL – Teil 2
Bist du ein SQL‑Hartnäckiger oder ein SQL‑Weichling?
Teil 2 von 2. Zurück zu Teil 1
Willkommen zu Teil 2 meines Deep Postres Quiz!
Dieses Quiz deckt eine Mischung aus bekannten und weniger bekannten PostgreSQL‑Features und Stolperfallen ab: JOIN, NULL, ANSI SQL, Transaktionen, Interna, Indexierung, Data Sampling … und mehr!
Viel Glück! 🍀
Welcher Ausdruck ist ❌ kein gültiger PostgreSQL-JOIN-Ausdruck?
Du kanntest CROSS JOIN, oder?
Hat dich JOIN ALL an eine andere Operation denken lassen, UNION ALL?
Die Antwort hier ist JOIN ALL ❌.
Die korrekten JOIN‑Typen sind:
INNER JOIN(Standard‑JOIN)LEFT JOIN(oderLEFT OUTER JOIN)RIGHT JOIN(oderRIGHT OUTER JOIN)FULL JOIN(oderFULL OUTER JOIN)CROSS JOIN(das kartesische Produkt, das eine spätereWHERE-Klausel einschränken kann)
Außer bei “Hängt von Nebeneffekten ab” Was passiert nach einem Fehler?
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;Wenn hier ein Fehler auftritt:
- Die gesamte Transaktion wird zurückgerollt
- Es werden keine Änderungen committed
- Die Transaktion wird als fehlgeschlagen markiert
Um teilweise zu committen:
BEGIN;UPDATE ...;SAVEPOINT my_save;UPDATE ...; -- ErrorROLLBACK TO my_save;COMMIT;Welche ON-Bedingung kann PostgreSQL für einen HASH JOIN verwenden?
SELECT *FROM students aJOIN grades bON /* What goes here? ⁉ */;Ein Hash-Join ist mit einer Gleichheitsbedingung (=) in der ON-Klausel möglich.
=ist die zentrale Prädikatform für Hash-Joins>und>=sind keine Hash‑Join‑PrädikateHASH JOINist keine gültige Syntax in PostgreSQL
Der Planner kann trotzdem einen Nested‑Loop‑ oder Merge‑Join wählen, abhängig von Tabellengröße, Statistiken, Indizes und Speichereinstellungen.
Was ist korrekt für case-sensitive Spaltennamen?
CREATE TABLE grades ( "Student Name" VARCHAR(100), 'Student Grade' INTEGER);In PostgreSQL:
- Doppelte Anführungszeichen (
") sind für Bezeichner (Tabellennamen, Spaltennamen) - Einfache Anführungszeichen (
') sind für Zeichenkettenliterale
Best Practices:
- Vermeide gemischte Groß‑ und Kleinschreibung oder Leerzeichen in Namen
- Verwende snake_case für Bezeichner
- Verwende zitierte Bezeichner nur, wenn es unbedingt nötig ist
Wie geben Sie einen Spaltennamen mit einem Punkt an?
CREATE TABLE teachers ( id INT GENERATED BY DEFAULT AS IDENTITY, first.name TEXT, -- How do you include the column: first.name? salary NUMERIC);PostgreSQL verwendet doppelte Anführungszeichen für das Quotieren von Bezeichnern:
- Doppelte Anführungszeichen
"..."für Bezeichner (Spaltennamen, Tabellennamen) - Einzelne Anführungszeichen
'...'für Zeichenkettenliterale - Die Form
first.namewird alstable_name.column_nameinterpretiert
Ohne Anführungszeichen würde ein Punkt im Spaltennamen als Trennzeichen für Schema/Tabellen angesehen! Außerdem werden alle nicht quotierten Bezeichner standardmäßig in Kleinbuchstaben umgewandelt.
Um Überraschungen zu vermeiden, sollte man snake_case verwenden und Sonderzeichen meiden.
Welche Syntax ist gültig, um im Mittel zufällig 10 % der Studenten zu entnehmen?
Das hier ist knifflig! Es enthält ungefähr 6 Fallen, darunter:
- Hohe‑Level‑Beschreibung + Syntax‑Fragmente. Testet, wie du unvollständige Informationen anpasst und zusammensetzt.
- Erfordert vertrautes Wissen über die
TABLESAMPLE‑Syntax, da keine derTABLESAMPLE‑Optionen die korrekte Syntax verwendet! (Unheimlich! Ich weiß! Weiter so, ich glaube an dich!!! ❤️) - Das
ROW_NUMBER() OVER (ORDER BY RAND())undORDER BY RANDOM() > 10sind weitere falsche Fährten. Sie sehen aus, als könnten sie korrekt sein, sind es aber nicht.RAND()gibt es nicht. UndRANDOM() > 10ist ein boolescher Ausdruck, der immer false ist, weilRANDOM()immer im Bereich0.0‑1.0liegt. Ein weiteres Problem:ORDER BY RANDOM() > 10würde nach einem booleschen Wert sortieren, nicht nach einer Zufallszahl. Aber das> 10wirkt wie ein Prozentsatz, oder? BERNOULLIist gültig,SAMPLETABLEhingegen nicht.WHERE RANDOM() >= 0.1ist ein Trick!RANDOM()liefert einen Wert im Bereich0.0 <= x < 1.0, sodass>= 0.1etwa 90 % der Zeilen zurückgibt, nicht 10 %.
Bezüglich der TABLESAMPLE‑Methode unterstützt PostgreSQL zwei Stichprobenverfahren:
BERNOULLI: Jede Zeile hat gleiche WahrscheinlichkeitSYSTEM: Block‑basiertes Sampling (schneller, aber weniger zufällig)
Um mehr über Sampling zu erfahren, sieh dir diesen Artikel von Render an.
Beispiel:
-- Sample 10% of rowsSELECT * FROM students TABLESAMPLE BERNOULLI (10);
-- For repeatable results, use REPEATABLE:SELECT * FROM studentsTABLESAMPLE BERNOULLI (10) REPEATABLE (42);Ebenfalls erwähnenswert, dass TABLESAMPLE berichten zufolge nicht sehr zufällig ist. Wenn du eine noch zufälligere Stichprobe fester Größe brauchst, erwäge ORDER BY RANDOM() LIMIT 10. Beachte jedoch, dass das 10 Zeilen zurückgibt, nicht 10 %, und bei großen Tabellen langsam sein kann.
Es gibt auch einige Drittanbieter‑Erweiterungen, die bessere zufällige Stichprobenmethoden bieten, aber das liegt hier außerhalb des Rahmens! 😅
Was bewirkt diese Beschwörung?
CREATE INDEX idx_active_studentsON students(last_name)WHERE status = 'active';Dieser Trick heißt Partial Index.
Sie sind nützlich, um Speicherplatz zu sparen und Abfragen zu beschleunigen, wenn typischerweise nur ein Teil der Zeilen abgefragt wird.
Der Abfrageplaner kann diesen Index berücksichtigen, wenn er beweisen kann, dass die Abfragebedingungen status = 'active' implizieren. Der Wortlaut muss nicht immer identisch sein, aber die Schlussfolgerungen des Planers sind begrenzt; ein Parameter kann den Nachweis zur Planungszeit verhindern. Ein geeigneter Index wird nicht zwangsläufig ausgewählt.
Erinnerung: Postgres unterstützt keine „query hints“ wie andere RDBMSs. Der Abfrageplaner entscheidet, wann ein passender Index verwendet wird.
Gut gemacht! Du hast in mehreren Bereichen von PostgreSQL tief gegraben! 🐘
Ich hoffe, du hast etwas Neues gelernt oder zumindest eine Punktzahl, mit der du prahlen kannst! 🏆
Mehr Nervenkitzel gefällig? Sieh dir meine Quiz‑Sammlung für endlosen* Spaß an!
