====== Datenbanksysteme I ====== ===== Allgemein ===== ==== Probleme ==== * Fehlende Datenunabhängigkeit (änderung des Dateiformats) * Redundanz (u.a. Änderungsanomalien) * Schnittstellen (Jeder kocht sein eigenes Süppchen) * Mehrbenutzer System * Datenverlust bei Systemabsturz/deffekt * Zugriffkontrolle ==== Aufbau ==== * DB-Anwendung * DBS * DBMS * DB | Anwendungen (mehrere) || ^ Externe Ebene | Views (mehrere) | ^ | ↓↓ Logische Datenunabhängigkeit ↓↓ | ^ Konzeptionelle Ebene | | ^ | ↓↓ Physische Datenunabhängigkeit ↓↓ | ^ Interne Ebene | Speicherformat | ==== Anforderungen ==== * **Integration** //einheitlicher// Zugriff auf //alle// Daten einer Anwendung * **Operationen** auf den Daten (ändern, löschen, ...) * **Data Dictionary** Schema anschauen * **Benutzersicheten** views * **Konsistenzüberwachung** bei Änderung * **Zugriffskontrolle** * **Transaktionen** * **Synchronisation** (Mehrbenutzersystem) ==== Sprachen ==== * **D**ata **D**efinition **L**anguage * **D**ata **M**anipulation **L**anguage ==== Datenmodelleigenschaften ==== * //Objekte// der Datenbank * //Beziehungen// zwischen verschiedenen Objekten * //Integrität//sbedingugen * Angebotenen //Operationen// (zum Abfragen) ==== Datenmodelle ==== * **Hierarchisches ~** * **Netzwerk ~** (Art linked list, was den parent im link Ring beinhaltet) * **Relationales ~** * **Objektorientiertes ~** * **Objekt-Relationales ~** ==== Verbindung zur Datenbank ==== * API * DSL ===== Mathe ===== ==== Begriffe ==== * Domain * = Typ * Kann auch Liste Sein * endlich * unendlich (nicht in DB Darstellbar) * z.B. Int, Sting, Date, {rot, gel, käsekuchen} * Relation = Ausprägung eines Relationsschemata = Menge = {} * Tupel = Zeile = Ausprägung einer Relation = () * Grad = Stelligkeit = Elemente im Tupel * Relationsschema: Über //eine// Tabelle * DB-Schema: Über //alle// Tabellen ==== Schlüssel ==== === Eigenschaften === - Eindeutig \\ $t_1 \ne t_2 \Rightarrow \pi_S(t_1) \ne \pi_S(t_1)$ \\ Unterschiedliche Tupel ⇒ Unterschiedliche Schlüssel - Minimal \\ $\text{Eindeutig} T \wedge T \subseteq S \Rightarrow T = S$ \\ Keine Teilmenge des Schlüssels erfüllt die 1. Eigenschaft (Minimal bedeutet //nicht//: Die wenigsten Attribute === Arten === * Superschlüssel: Nur 1. Eigenschaft erfüllt * Schlüsselkandidat: 1. und 2. Eigenschaft erfüllt * Primärschlüssel: Ein beliebiger aber fester Schlüsselkandidat ==== Relationsschemata ==== === geordnet === ^ Schema | R = (id:Integer, Name:String) | ^ Ausprägung | r = {(1, Alice), (2, Bob), (42, Eve)} | === ungeordnet (mit Domänenabbildung) === ^ Schema | R = {id, Name} mit \\ dom(id) = Integer, dom(Name) = String | ^ Ausprägung | r = {t1, t2, t3} mit \\ t1(id) = 1, t1(Name) = Alice, \\ t2(id) = 2, t2(Name) = Bob, \\ t3(id) = 42, t3(Name) = Eve | ===== Relationale Algebra ===== ^ Formel ^ Name ^ Iden- \\ tisch ^ Duplikat- \\ elimi- \\ nation ^ SQL ^ Kommentar ^ ^ $A \cup B$ | Vereinigung | X | X | ''UNION'' \\ ''UNION ALL'' | {{:users:skruppy:ext:uni:5:dbs:union.png?35|}} Duplikatelimination in SQL nur bei ''UNION'' | ^ $A - B$ | Differenz | X | | ''EXCEPT'' \\ ''MINUS'' | {{:users:skruppy:ext:uni:5:dbs:except.png?35|}} | ^ $A \times B$ | Kreuzprodukt \\ Kartesisches Produkt | | | | | ^ $\sigma_F(A)$ | Selektion | | | ''WHERE'' | | ^ $\pi_{a, b, \dots}(A)$ | Projektion | | X | ''SELECT'' | | ^ $A \cap B$ | Durchschnitt | X | | ''INTERSECT'' | {{:users:skruppy:ext:uni:5:dbs:intersect.png?35|}} | ^ $A \div B$ | Quotient | | | | Allquantor. Die Tupel aus A, die alle Attribute aus jedem B Tupel gleich haben, ohne die B Attribute. | ^ $A \bowtie B$ | Natural Join | | | ''**NATURAL JOIN** t'' | Inner-Join (Tupel ohne Partner gehen verloren) \\ Vergleich //aller// gleichbenannten | ^ $A \underset{a = b}{\bowtie} B$ | Equi Join | | X | ''JOIN t **USING(**id**)**'' | Inner-Join (Tupel ohne Partner gehen verloren) | ^ $A \underset{a \Theta b}{\bowtie} B$ | Theta Join | | | ''JOIN t **ON** f'' | Inner-Join (Tupel ohne Partner gehen verloren) \\ Θ = Vergleichsoperator | Identisch * Relationale Algebra: //Typ// und //Name// jedes Attributs muss übereinstimmen (Schemata identisch) * SQL: //Typ// jedes Attributs muss kompatibel sein (nur die Position ist maßgebend) ==== Relationale Algebra und SQL ==== * Für jeden relationalen Ausdruck existiert ein SQL statement (SQL ist relational vollständig) * SQL Projektion entfernt nicht immer Duplikate implizit (Explizites ''DISTINCT'' bei umsetzung!!) * SQL kann mehr: Sortieren, Aggregation ===== Relationen-Kalkül ===== t ∈ Schema ⇔ Schema(t) t[A] ⇔ t.A Ψ(r | t): Ersetze //t// in Ψ(r | t) mit dem konkreten Tupel //r// * Relationale algebra \\ prozedual (wie) * Relationen-Kalkül \\ deklarativ (was) * //Tupel//kalkül: Variable = ein Tupel * //Bereichs//kalkül: Variable = einfacher Typ Quantoren sind nur im Relationenkalkül möglich. Variable ist ... * frei: keinem ∃ oder ∀ zugeordnet * gebunden: einem ∃ oder ∀ zugeordnet * Zuordnungszustand kann sich ändern Es ist möglich unendlich (nicht speicherbare) Relationen zu beschreiben. \\ Eine Relation ist //sicher// wenn alle Vaiablen //x// einer (gespeicherten) Relation angehören //Schema(x)//. ^ Tupelkalkül ^ Bereichskalkül ^ ^ Alle Großstädte in Bayern ^^ | Schema(t) = Schema(Städte) \\ {t %%|%% Städte(t) ∧ f[Land] = Bayern ∧ t[SEinw] ≥ 500000} | | ^ In welchem Land liegt Passau ^^ | Schema(t) = (Land:String) \\ {t %%|%% (∃ u ∈ Städte)(u.Sname = Passau ∧ u.Land = t.Land} | $\{ x_3 \mid \exists x_1, x_2 : (\text{Städte}(x_1, x_2, x_3) \wedge x_1 = \text{Passau}) \}$ | | | $\{ x_3 \mid \exists x_2 : (\text{Städte}(\text{Passau}, x_2, x_3)) \}$ | ^ CDU-regierte Städte ^^ | Schema(t) = Schema(Städte) \\ {t %%|%% Städte(t) ∧ (∃ u ∈ Länder)(u.Lname = t.Land ∧ u.Partei = CDU) } | $\{x_1 \mid \exists x_2, x_3, y_2 : (\text{Städte}(x_1, x_2, x_3) \wedge \text{Länder}(x_3, y_2, \text{CDU}))\}$ | ^ SPD alleinregierte Länder ^^ | Schema(t) = SChema(Länder) \\ {t %%|%% Länder(t) ∧ (∀ u ∈ Länder)(u.LName = t.LName ⇒ u.Partei = SPD} | $\{x_1 \mid \exists x_2 : (\text{Länder}(x_1, x_2, \text{SPD}) \wedge \not \exists y_3 : \text{Länder}(x_1, x_2, y_3) \wedge y_3 \ne \text{SPD} \}$ | | Schema(t) = SChema(Länder) \\ {t %%|%% Länder(t) ∧ (∀ u ∈ Länder)(u.LName = t.LName ⇒ u.Partei = SPD} | | ===== SQL ===== ==== Typen ==== | ''integer'' | ''integer4'' | ''int'' | | | ''smallint'' | ''integer2'' | | | | ''float(''//p//'')'' | ''float'' | | Bits der mantisse (nicht Exponent) | | ''decimal(''//p//'', ''//q//'')'' | ''numeric(''//p//'', ''//q//'')'' | | Exakte Komma Zahlen. p Stellen gesamt, davon q Nachkommastellen. | | ''character(''//n//'')'' | ''char(''//n//'')'' | | | | ''character varying(''//n//'')'' | ''varchar(''//n//'')'' | | | | ''date'' | | | | | ''time'' | | | | | ''timestamp'' | | | | http://www.postgresql.org/docs/9.2/static/datatype-numeric.html ==== Constrains ==== * ''NOT NULL'' * ''PRIMARY KEY'' * ''UNIQUE'' * ''REFERENCES ''//t//''(''//a//'')'' * ''DEFAULT ''//w// * ''CHECK ''//f// ==== Integritätsbedingungen ==== * ''PRIMARY KEY (''//a1//'', ''//a2//'', ...)'' * ''UNIQUE (''//a1//'', ''//a2//'', ...)'' * ''FOREIGN KEY (''//a1//'', ''//a2//'', ...) REFERENCES ''//t//''(''//b1//'', ''//b2//'', ...)'' * ''CHECK ''//f// ==== Schlüssel ==== * Schlüsselkandidat * ''UNIQUE'' * ''UNIQUE (''//a1//'', ''//a2//'', ...)'' * Primärschlüssel * ''PRIMARY KEY'' * ''PRIMARY KEY (''//a1//'', ''//a2//'', ...)'' * Fremdschlüssel * ''REFERENCES ''//t//''(''//a//'')'' * ''FOREIGN KEY (''//a1//'', ''//a2//'', ...) REFERENCES ''//t//''(''//b1//'', ''//b2//'', ...)'' ==== Fremdschlüssel Zusätze ==== Folgende sachen können am Ende einer ''REFERENCES'' Angabe stehen * ''ON DELETE SET NULL'' \\ Wenn das Referenzierte gelöscht wird, wird dieser auf ''NULL'' gesetzt * ''ON DELETE CASCADE'' \\ Wenn das Referenzierte gelöscht wird, wird auch dieser gelöscht * ''ON UPDATE CASCADE'' \\ Wenn das Referenzierte geändert wird, wird auch dieser geändert ==== Bla ==== | ''//a// + //b//'' | ''//a// - //b//'' | ''//a// %%*%% //b//'' | ''//a// %%/%% //b//'' | | ''//a// **=** //b//'' | ''//a// **<>** //b//'' | | | | ''//a// < //b//'' | ''//a// > //b//'' | ''//a// %%<=%% //b//'' | ''//a// >= //b//'' | | ''//a// IS NULL'' | ''//a// IS NOT NULL'' | | ''//a// IN (...)'' | | | | | ''//a// AND //b//'' | ''//a// OR //b//'' | ''//a// NOT //b//'' | | | ''//s1// %%||%% //s2//'' | ''CHAR_LENGTH(//s//)'' | ''SUBSTRING(s FROM pos [FOR len])'' | ''//a// LIKE %%'...'%%'' | * ''%'' 0...n beliebige Zeichen * ''_'' 1 beliebiges Zeichen CREATE TABLE name ( name typ constraints, name typ constraints, integritätsbedingungen ) DROP TABLE name ALTER TABLE name ADD ( name typ constraints, name typ constraints ) ALTER TABLE name DROP ( name, name ) ALTER TABLE name MODIFY ( name typ constraints, name typ constraints ) SELECT [DISTINCT] *, t.*, t.a, 42, 32 AS Foo -- Hier AS FROM t, Unisinn u -- KEIN AS WHERE INSERT INTO name [(a1, a2)] VALUES (v11, v21), (v12, v22) INSERT INTO name (a1, a2) (SELECT ...) UPDATE name SET a1=v1, a2=v2 [WHERE ...] DElETE FROM name [WHERE ...] === Mengen Operationen === == Join == | ''**NATURAL JOIN** t'' | Natural Join | $A \bowtie B$ | Vergleich //aller// gleichbenannten | | ''JOIN t **USING(**id**)**'' | Equi Join | $A \underset{a = b}{\bowtie} B$ | | | ''JOIN t **ON** f'' | Theta Join | $A \underset{a \Theta b}{\bowtie} B$ | Θ = Vergleichsoperator | * inner * outer * left * right * full ^ Join Art ^ Verlust//freie// \\ Seite ^^ NULL ^^ ^ ::: ^ L ^ R ^ L ^ R ^ | ''[INNER] JOIN'' | | | | | | ''LEFT [OUTER] JOIN'' | ✓ | | | ✓ | | ''RIGHT [OUTER] JOIN'' | | ✓ | ✓ | | | ''FULL [OUTER] JOIN'' | ✓ | ✓ | ✓ | ✓ | == Quantoren == WHERE EXISTS (SELECT ...) -- Ergebnis Form egal WHERE NOT EXISTS (SELECT ...) -- Ergebnis Form egal WHERE ... a Θ ALL (SELECT ...) -- Ergebnis genau ein Attribut, aber mehre Tupel WHERE ... a Θ SOME/MANY (SELECT ...) -- Ergebnis genau ein Attribut, aber mehre Tupel WHERE ... a IN (SELECT ...) -- Ergebnis genau ein Attribut, aber mehre Tupel == Grouping == GROUP BY x HAVING SUM(y) > 42 keine Aggregartfunktionen in ''WHERE'' In ''SELECT'' nur erlaubt * Groupierte Attribute * Aggregatfunktionen * ''COUNT'' * ''SUM'' * ''AVG'' * ''MAX'' * ''MIN'' In ''SELECT'' //nicht// erlaubt * %%*%% * An groupierte Elemente gejointe Elemente, die selbst nicht groupiert sind. \\ Abhilfe: * Auch nach denen groupieren * ''MAX(x)'' ^ Befehl ^ Zähle ^^ ^ ::: ^ NULL ^ doppelte ^ | ''COUNT(**DISTINCT** a)'' | | | | ''COUNT([ALL] a)'' | | ✓ | | ''COUNT(**%%*%%**)'' | ✓ | ✓ | == Order == ORDER BY a [ASC/DESC], b [ASC/DESC], ... * '' ASC'': 0, 1, 2, ... (default) * ''DESC'': 9, 8, 7, ... == Weitere == //Typ// jedes Attributs muss kompatibel sein * Nur die Position ist maßgebend * Länge bei Strings egal * Genauigkeit bei Zahlen egal [Im Gegensatz zur relationalen Algebra, wo //Typ// und //Name// jedes Attributs übereinstimmen muss (Schemata identisch)] | $A \cup B$ | Vereinigung | ''UNION [CORRESPONDING]'' | {{:users:skruppy:ext:uni:5:dbs:union.png?35|}} **mit** Duplikatseliminierung | | | Vereinigung | ''UNION ALL [CORRESPONDING]'' | {{:users:skruppy:ext:uni:5:dbs:union.png?35|}} **ohne** Duplikatseliminierung | | $A - B$ | Differenz | ''EXCEPT [CORRESPONDING]'' \\ ''MINUS [CORRESPONDING]'' | {{:users:skruppy:ext:uni:5:dbs:except.png?35|}} | | $A \cap B$ | Durchschnitt | ''INTERSECT [CORRESPONDING]'' | {{:users:skruppy:ext:uni:5:dbs:intersect.png?35|}} | SELECT ... UNION/UNION ALL/EXCEPT/MINUS/INTERSECT [CORRESPONDING] SELECT ... * ''CORRESPONDING'' beschränkt Ergebniss auf gleiche Namen. Die Position ist dann egal. * Besser: Explizite Auswahl/Sortierung mit ''SELECT'' * Tip: Explizites ''NULL'' in ''SELECT'' bei fehlenden Werten. === Beispiele === Finde Paare mit gleicher Eigenschaft SELECT DISTINCT t1.name, t2.name FROM Foo t1, Foo t2 WHERE t1.attrib = t2.attrib AND t1.name < t2.name -- Macht aus (AA, AB, BA, BB) : (AB)