<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document>
   <head>
      <pagetitle>Scriptum zur Vorlesung Datenbanken</pagetitle>
      <metatags description="Scriptum zur Einführungsvorlesung Datenbanken" keywords="Datenbanken Modellierung E3R Entity Relationship Normalform SQL" url="http://www.jeckle.de/vorlesung/datenbanken/script.html">
         <nocache/>
         <robots revisit-after="10 days"/>
         <css/>
      </metatags>
   </head>
   <body>
      <navigation titleimage="datenbanken.png" length="131">
         <navup reference="Vorlesung Datenbanken" destinationuri="index.html"/>
         <navseparator/>
         <navpage reference="1 Motivation und Einführung" destinationuri="#Motivation"/>
         <navpage reference="1.1 Begriffsbestimmung: Was ist eine          Datenbank?" destinationuri="#Begriffsbildung"/>
         <navpage reference="1.2 Anforderungen an          Datenbanksysteme" destinationuri="#Anforderungen"/>
         <navpage reference="1.3 Typen von          Datenbankmanagementsystemen" destinationuri="#Typen"/>
         <navpage destinationuri="#Entwurf" reference="2 Entwurf einer Datenbank"/>
         <navpage reference="2.1 Graphischer Entwurf des konzeptuellen Schemas mit dem Entity-Relationship             Modell" destinationuri="#GraphischerEntwurf"/>
         <navpage reference="2.2 Ableitung logischer             Relationenstrukturen" destinationuri="#Ableitung"/>
         <navpage reference="2.3 Algebraischer Entwurf mit der             Normalformentheorie" destinationuri="#NF"/>
         <navpage reference="3 Arbeiten mit einer Datenbank" destinationuri="#Arbeiten"/>
         <navpage reference="3.1 Codd'sche Regeln und Eigenschaften relationaler Systeme" destinationuri="#Codd"/>
         <navpage reference="3.2 Implementierung des logischen Modells mit SQL-DDL" destinationuri="#SQL-DDL"/>
         <navpage reference="3.3 Der Anfrageteil von SQL" destinationuri="#Anfragen"/>
         <navpage reference="3.4 Der Datenmanipulationsteil von SQL" destinationuri="#Manipulate"/>
         <navseparator/>
         <navdown reference="Empfohlene Literatur" destinationuri="index.html#lit"/>
      </navigation>
      <topic>Hinweis</topic>
      <p>Aufgrund der verfügbaren Menge guter einführender (auch deutschsprachiger) Datenbankliteratur verzichtet das
      vorliegende Scriptum darauf den in der Literatur
      verfügbaren Stoff nochmals aufzubereiten, sondern versammelt
      die Definitionen, Beispiele und Anmerkungen der Vorlesungen
      in einer übersichtlichen Zusammenstellung.<br/>
      Für die vertiefende ausführliche lehrbuchartige Darstellung
      des Stoffes sei auf die <a external="yes" href="index.html#lit">empfohlene
      Literatur</a> verwiesen.</p>
      <region numbered="yes">
         <topic name="Motivation">Motivation und Einführung</topic>
         <subtopic name="Begriffsbildung">Begriffsbestimmung: Was ist eine Datenbank?</subtopic>
         <p>Motivation für die Einführung einer Datenbank anstatt
        selbsterstellter Verwaltungs- und Zugriffsroutinen:</p>
         <ul>
            <li>Daten-Programm-Unabhängigkeit.<br/>
            Die verwalteten Daten sollen unabhängig vom sie verarbeiteten Programm gespeichert und zugreifbar sein.<br/>
            Dies wäre zwar in einem ersten Schritt auch durch die Verwendung des Dateisystems möglich, allerdings würde
            hierfür ein Programm zur Abbildung der Programmdaten auf die Dateistrukturen benötigt, welches
            selbst wieder eine Abhängigkeitsbeziehung zwischen Daten und Programm --- nun eben dem Abbildungsprogramm --- darstellen würde.</li>
            <li>Flexible Speicherung.<br/>
            Datenbankmanagementsysteme speichern die verwalteten
            Daten deutlich flexibler als selbsterstellte Routinen
            und sind somit hinsichtlich der Zukunftsfähigkeit
            effizienter.</li>
            <li>Verwaltungsfunktionen.<br/>
            Datenbankmanagementsysteme bieten in der Regel eine
            Reihe über die reine Datenverwaltung hinausgehende
            Funktionen wie Backup-Recovery, Integritätssicherung,
            Synchronisation gleichzeitiger Zugriffe
            oder
            Transaktionskontrolle an, die nicht selbständig
            implementiert werden müssen.</li>
         </ul>
         <subsubtopic>Grundlegende Begriffe</subsubtopic>
         <definition id="Daten" term="Daten">
            Daten sind durch die Maschine verarbeitbare Einheiten.
        </definition>
         <definition id="Information" term="Information">
            Daten die Bedeutung für den Empfänger besitzen.<br/>
            Nach <name>Shannon</name> ermißt sich der Wert einer
            Information durch den Zuwachs der durch den
            Adressaten nach Kenntnis der Information
            beantwortbaren Ja/Nein-Fragen.
        </definition>
         <p>Mehr zum
        Unterschied zwischen <em>Daten</em> und
        <em>Information</em>:</p>
         <ul>
            <li>
               <a external="yes" href="http://surjo.bei.t-online.de/seb.htm">Homepage des Arbeitskreises <em>Bildung</em>, einem Zusammenschluß von Stipendiaten der Friedrich Naumann Stiftung</a>
            </li>
            <li>
               <a external="yes" href="http://www.foebud.org/pgp/html/node36.html">Glossar der deutschsprachigen Anleitung zu PGP</a>
            </li>
         </ul>
         <definition id="Datenbank" term="Datenbank">
        Eine Datenbank (engl. <em>
               <keyword>data
        base</keyword>
            </em>) ist ein integrierter, persistenter
        Datenbestand einschließlich aller relevanten Informationen
        über die dargestellten Information (sog. <keyword>Metainformation</keyword>, d.h. Integritätsbedingungen und
        Regeln), der einer Gruppe von Benutzern in nur einem
        Exemplar zur Verfügung steht und durch ein <a href="#DBMS">DBMS</a>
        verwaltetet wird.
        </definition>
         <definition id="DBMS" term="Datenbankmanagementsystem (DBMS)">
            Ein Datenbankmanagementsystem
            (<keyword>DBMS</keyword>) ist die Gesamtheit aller Programme
            zur Erzeugung, Verwaltung und Manipulation einer <a href="#Datenbank">Datenbank</a>.<br/>
            Im Deutschen wird auch der Begriff
            <em>
               <keyword>Datenbankverwaltungssystem</keyword>
            </em>
            (<keyword>DBVS</keyword>) synonym verwendet.
        </definition>
         <example name="DBMS" caption="Am Markt verfügbare DBM-Systeme">
            <p>Beispiele verfügbarer DBMS:</p>
            <sl>
               <li>
                  <a external="yes" href="http://www.oracle.com/ip/deploy/database/oracle9i/">Oracle
            9i</a> des Herstellers <a external="yes" href="http://www.oracle.com">Oracle</a>
               </li>
               <li>
                  <a external="yes" href="http://www-3.ibm.com/software/data/ims/">IMS</a>, <a external="yes" href="http://www-3.ibm.com/software/data/db2/">DB2</a>
            und <a external="yes" href="http://www-3.ibm.com/software/data/informix/">Informix</a>
            von <a external="yes" href="http://www.ibm.com">IBM</a>
               </li>
               <li>
                  <a external="yes" href="http://www.mysql.com">MySQL</a> des
            gleichnamigen Herstellers</li>
               <li>
                  <a href="http://www.microsoft.com/sql/default.asp" external="yes">SQLServer</a> und
            <a external="yes" href="http://www.microsoft.com/office/access/">Access</a>
            des Herstellers <a external="yes" href="http://www.microsoft.com">Microsoft</a>
               </li>
               <li>Die DBMS-Produkte des Herstellers <a external="yes" href="http://www.sybase.com">Sybase</a>
               </li>
               <li>
                  <a external="yes" href="http://www3.ca.com/Solutions/ProductFamily.asp?ID=126">IDMS</a>
            von <a external="yes" href="http://ca.com/">Computer
            Associates</a>
               </li>
            </sl>
         </example>
         <definition id="RDBMS" term="Relationales DBMS">
            Ein relationales Datenbankmanagementsystem
            (<keyword>RDBMS</keyword>) ist ein <a href="#DBMS">DBMS</a>, welches intern gemäß dem
            <a href="#Relation">relationalen</a>  <a href="#Modell">Modell</a> organisiert ist.
        </definition>
         <example caption="Am Markt verfügbare RDBM-Systeme">
            <p>Bei den genannten DBMS <em>MySQL</em>,
        <em>SQLServer</em>, <em>Access</em>, <em>DB2</em> und <em>Oracle</em>
        handelt es sich um relationale Systeme, bzw.
        Weiterentwicklungen davon.</p>
         </example>
         <definition id="Relation" term="Relation">
            Eine Relation R(A<sub>1</sub>, A<sub>2</sub> ...
            A<sub>n</sub>) ist eine benannte Menge von
            <em>n</em>-Tupeln, wobei ein <em>n</em>-Tupel eine
            Anordnung von <em>n</em> atomaren, d.h. einfachen
            (nicht weiter zerlegbaren) Attributen A<sub>1</sub>, A<sub>2</sub> ...
            A<sub>n</sub> ist.
        </definition>
         <example name="RelEx" caption="Relationen">
            <p>Die Relation <em>Person</em> mit den Attributen
            <em>Vorname</em>, <em>Nachname</em> und
            <em>Geburtsdatum</em>.<br/>
            Werteausprägungen davon:<br/>
            Person<sub>1</sub>("Meier", "Schorsch", "1955-10-01")<br/>
            Person<sub>2</sub>("Huber", "Franz", "1945-08-03")<br/>
            ...</p>
            <p>Die Relation <em>Student</em> mit den Attributen
            <em>Name</em>, <em>Matrikelnummer</em>,
            <em>Semester</em> und
            <em>regelmäßigerMensabesucher</em>.<br/>
            Werteausprägungen davon:<br/>
            Student<sub>1</sub>("Meier Schorsch", "08154711", "WIB 1", "true")<br/>
            Student<sub>2</sub>("Müller Xaver", "73619452", "BCM 4", "false")<br/>
            ...</p>
         </example>
         <definition id="Tabelle" term="Tabelle">
            Eine Tabelle unterscheidet sich von einer <a href="#Relation">Relation</a> darin, daß ein Tupel
            mehrfach auftreten darf; eine Tabelle ist mathematisch
            keine Menge.
        </definition>
         <example name="TabEx" caption="Tabelle">
            <p>Die Tabelle <em>Student</em> mit den Attributen
            <em>Name</em>, <em>Matrikelnummer</em>,
            <em>Semester</em> und
            <em>regelmäßigerMensabesucher</em>.<br/>
            Werteausprägungen davon:<br/>
            Student<sub>1</sub>("Meier Schorsch", "08154711", "WIB 1", "true")<br/>
            Student<sub>2</sub>("Müller Xaver", "73619452", "BCM 4",
            "false")<br/>
            Student<sub>3</sub>("Müller Xaver", "73619452", "BCM 4", "false")<br/>
            ...</p>
            <p>Man beachte, daß der dritte Eintrag doppelt
            vorkommt, d.h. in all seinen Wertbelegungen mit dem
            zweiten übereinstimmt.</p>
         </example>
         <definition id="Modell" term="Modell">
            Ein Modell bildet einen existierenden Sachverhalt
            deskriptiv nach oder nimmt einen Zukünftigen
            präskriptiv voraus.<br/>
            Teilweise wird der Begriff
            <em>
               <keyword>Schema</keyword>
            </em> synonym gebraucht.
        </definition>
         <example name="ModellEx" caption="Modelle">
            <p>Deskriptive Modelle: Modelleisenbahn, Stadtplan,
            Photo.<br/>
            Präskriptive Modelle: Bauplan eines Hauses, Skizze
            eines Gemäldes, maßstäblich verkleinerte Skulptur als
            Vorbild.</p>
         </example>
         <definition id="Datenbanksprache" term="Datenbanksprache">
            Eine Sprache die zur Erzeugung oder Interaktion mit
            den Daten bzw. zu deren Verwaltung eingesetzt
            wird.<br/>
            Es werden unterschieden:<br/>
            <ul>
               <li>
                  <keyword>Data Definition Language</keyword> (<keyword>DDL</keyword>).<br/>
                Zur Erzeugung eines Daten<a href="#Modell">modells</a>.</li>
               <li>
                  <keyword>Data Manipulation Language</keyword>
                (<keyword>DML</keyword>).<br/>
                Zur Modifikation der verwalteten Daten.</li>
               <li>
                  <keyword>Data Retrieval Language</keyword>
                (<keyword>DRL</keyword>).<br/>
                Zur Anfrage der in einer <a href="#Datenbank">Datenbank</a> gespeicherten
                Daten.</li>
               <li>
                  <keyword>Data Control Language</keyword>
                (<keyword>DCL</keyword>).<br/>
                Zur Festlegung und Kontrolle von
                Zugriffsberechtigungen.</li>
            </ul>
         </definition>
         <example name="DBSprEx" caption="Die Datenbanksprache SQL">
            <p>Im Verlauf der Vorlesung wird mit <em>SQL</em> die bekannteste Sprache
            im Umfeld relationaler DBMS eingeführt.<br/>
            Beispiel einer SQL-Anfrage:<br/>
               <code>SELECT FNAME, BDATE FROM EMPLOYEE ORDERED BY
            BDATE</code>
            </p>
         </example>
         <subsubtopic>3-Schema-Architektur</subsubtopic>
         <illustration id="3SchemaArch" width="550" caption="3-Schema-Architektur" gfx="db/3SchemaArch.gif"/>
         <p>Die <illustrationLink ref="3SchemaArch"/> stellt die
        3-Schema-Architektur dar, welche die drei zentralen
        Modelltypen des Datenbankentwurfsprozesses miteinander in
        Beziehung setzt.</p>
         <definition id="konzSchema" term="Konzeptuelles Schema">
            Ein konzeptuelles Schema ist ein <a href="#Modell">Modell</a>, welches den relevanten
            Realitätsausschnitt (auch
            <em>
               <keyword>Miniwelt</keyword>
            </em>, <em>
               <keyword>Diskursbereich</keyword>
            </em> oder
            <em>
               <keyword>Universe of Discourse</keyword>
            </em>
            genannt) in Struktur und Inhalt beschreibt.
        </definition>
         <definition id="logSchema" term="Logisches Schema">
            Ein logisches Schema ist ein <a href="#Modell">Modell</a>, welches
            paradigmenspezifisch aus einem <a href="#konzSchema">konzeptuellen
            Schema</a> abgeleitet wurde.
        </definition>
         <example name="logSchEx" caption="Relationen sind ein logisches Schema">
            <p>Die Definition von Relationen als mathematisches
            Konzept zur Datenstrukturierung stellt ein logisches
            Schema dar.<br/>
            Beispielsweise die Festlegung der Struktur der <em>Person</em> oder
            des <em>Student</em>en in <exampleLink ref="RelEx"/>.</p>
         </example>
         <definition id="phySchema2" term="Physisches Schema">
            Ein physisches Schema ist ein implementierungsspezifisches <a href="#Modell">Modell</a>, welches aus einem <a href="#logSchema">logischen Schema</a> abgeleitet
            wurde.
        </definition>
         <definition id="Datenunabh" term="Datenunabhängigkeit">
            Die Formulierung einer Modellschicht (d.h. eines Datenmodells)
            ist von den darunter- bzw. darüberliegenden
            Modellschichten dann datenunabhängig, wenn Änderungen
            in den <gerquot>umgebenden</gerquot> Modellschichten
            sich nicht auf die betrachtete Modellschicht
            auswirken.
        </definition>
         <p>Der Vorgang der <em>Ableitung</em> zwischen den
        verschiedenen Modelltypen der 3-Schema-Architektur sollte
        hierbei idealerweise (aus Gründen der Überprüfbarkeit,
        Nachvollziehbarkeit, Wiederholbarkeit und
        Qualitätssicherung) durch einen deterministischen
        Algorithmus erfolgen.</p>
         <p>Die <illustrationLink ref="3SchemaArch"/> zeigt rechts
        neben den Modelltypen symbolhaft typische graphische
        Veranschaulichungen der jeweiligen Modellausprägungen.</p>
         <subtopic name="Anforderungen">Anforderungen an Datenbanksysteme</subtopic>
         <p>Allgemein: Speicherung, Verwaltung und Kontrolle der Daten sowie Organisation des u.U. gleichzeitig erfolgenden Zugriffs.<br/>
        Spezieller:</p>
         <ul>
            <li>Redundanzfreie Datenspeicherung.<br/>
            Von dieser Forderung kann bewußt aus Gründen der
            Geschwindigkeitsoptimierung abgewichen werden.</li>
            <li>Gewährleistung von Integritätsbedingungen und
            Einhaltung von Regeln.</li>
            <li>Daten-Programm-Unabhängigkeit.</li>
         </ul>
         <p>Wünschenswerte Eigenschaften:</p>
         <ul>
            <li>Leistungsfähigkeit</li>
            <li>Skalierbarkeit</li>
            <li>Benutzerfreundlichkeit</li>
            <li>Flexibilität</li>
            <li>... spezifische Anforderungen, die sich aus der
            Anwendungssituation ergeben</li>
         </ul>
         <subtopic name="Typen">Typen von Datenbankmanagementsystemen</subtopic>
         <p>Datenbanken werden heute vielfälltig in Wirtschaft,
        Technik und Wissenschaft eingesetzt.<br/>
        Für verschiedene Anwendungsgebiete und Strukturen der
        verwalteten Daten haben sich daher spezifische DBMS-(Unter-)Typen
        herausgebildet, die diese Anwendungsfelder besonders gut
        unterstützen:</p>
         <ul>
            <li>
               <b>Deduktive Datenbanken</b>
               <br/>
            Ein um eine Menge von Regeln (Deduktionskomponenten)
            erweitertes Datenmodell welches logische Schlüsse auf Basis der
            hinterlegten Fakten ziehen kann.</li>
            <li>
               <b>Multimedia Datenbanken</b>
               <br/>
            Ein System, welches sich besonders zur Verwaltung
            großer Bild-, Audio- oder Videodaten eignet.</li>
            <li>
               <b>Objektdatenbanken</b>
               <br/>
            Ein System zur Speicherung von Strukturen gemäß dem
            logischen Objektmodell.</li>
            <li>
               <b>Geographische Datenbanken</b>
               <br/>
            Ein System das sich besonders zur Verwaltung
            geographischer Daten (z.B. Landkarten) eignet.</li>
            <li>
               <b>XML-Datenbanken</b>
               <br/>
            Ein System zur Speicherung gemäß dem logischen Modell
            des XML Information Sets.</li>
            <li>
               <b>Aktive Datenbanken</b>
               <br/>
            Ein System zur selbständigen Reaktion auf externe
            Ereignisse.</li>
            <li>
               <b>Temporale Datenbanken</b>
               <br/>
            Ein System, welches neben den reinen Datenbeständen
            auch die Zeit des Datenzustandes mitverwaltet.</li>
         </ul>
      </region>
      <topic>Exkurs</topic>
      <p>
         <a href="MySQLStart.html">Erste Gehversuche mit dem RDBMS
      MySQL</a>
      </p>
      <region numbered="yes">
         <topic name="Entwurf">Entwurf einer Datenbank</topic>
         <subtopic name="GraphischerEntwurf">Graphischer Entwurf des konzeptuellen Schemas mit dem Entity-Relationship Modell</subtopic>
         <p>Seit der wirkungsmächtigen Erstveröffentlichung des
        <em>Entity Relationship Modells</em> (ERM) durch <name>P.
        Chen</name> 1976 kommt dieser Modellierungssprache zur
        Erstellung des konzeptuellen Schemas die uneingeschänkt
        größte Bedeutung in der Praxis zu.<br/>
        In der Folgezeit wurden verschiedene Weiterentwicklungen
        des ursprünglichen ERM vorgeschlagen, die das
        Originalmodell in verschiedenen Richtungen erweitern.
        Hierunter fallen die Einführung von Konstrukten zur
        Abbildung hierarchischer Beziehungen ebenso wie
        Primitive zur Darstellung von
        Aggregationsbeziehungen.<br/>
        Die Graphik der <illustrationLink ref="ERHistory"/> zeigt
        eine Auswahl verschiedener Entwicklungen rund um das
        initiale ERM sowie einige zentrale Weiterentwicklungen.
        Innerhalb der Abbildung ist unterhalb des Namens der
        Modellierungssprache (sofern vorhanden, bei
        Weiterentwicklungen ohne eigenständige Namensgebung ist zur Unterscheidung vom Vorgängermodell
        ein geklammertes Pluszeichen angetragen) der Autor sowie
        das Jahr der Erstveröffentlichung dargestellt.</p>
         <illustration id="ERHistory" width="550" caption="Entwicklungslinien des ER-Modells" gfx="db/ERHistory.gif"/>
         <p>Im oberen Bereich der Abbildung ist das
        <em>Semantically Enriched Extended Entity Relationship
        Model</em> (E<sup>3</sup>R) dargestellt, welches im Rahmen
        dieser Vorlesung behandelt wird.<br/>
        Es stellt eine kompatible Entwicklung dar, die versucht
        die datenorientierten Aspekte der ER-Nachfolgemodelle mit
        denen der semantischen Datenmodellierung zu vereinigen.</p>
         <p>Die Grundkonzepte des E<sup>3</sup>R-Modells sind:</p>
         <definition id="E" term="Entität">
            Eine Entität ist ein eindeutig identifizierbares und
            daher wohlunterscheidbares <gerquot>Ding</gerquot>.<br/>
				Im graphischen <E3R/>-Modell werden Entitäten durch benannte Rechecke dargestellt, die im Zentrum den unterstrichenen Namen der Entität, gefolgt vom -- in Klammern angegebenen -- Namen des Entitätstypen, tragen.
        </definition>
         <p>Anmerkung: Der Begriff <em>Ding</em> wird hierbei in
        seiner Bedeutung als Synonym von <em>Seiendes,
        Gegenstand</em> oder <em>Objekt</em> gebraucht. Die
        philosophische Terminologie detailliert den Begriff
        zusätzlich hinsichtlich seiner Verwendung zur Beschreibung
        raumzeitlicher Gegenstände mit festgelegten
        charakteristischen (substantiellen) und zufällig
        anhaftenden Eigenschaften (Akzidenzien) aus.</p>
         <example name="E-Bsp" caption="Beispiele für Entitäten">
            <ul>
               <li>Die Tafel direkt vor ihnen.</li>
               <li>Sie selbst.</li>
               <li>Dieser Hörsaal.</li>
            </ul>
         </example>
         <definition id="ET" term="Entitätstyp">
            Ein Entitätstyp ist eine ungeordnete und duplikatfreie
            Sammlung von als logische zusammengehörig betrachteten
            <a href="#E">Entitäten</a>.<br/>
				Im graphischen <E3R/>-Modell werden Entitätstypen durch benannte Rechtecke dargestellt.
				Der Name eines Entitätstyps muß dabei schemaweit eineindeutig sein.
        </definition>
         <example name="ET-Bsp" caption="Beispiele für Entitätstypen">
            <ul>
               <li>Tafel.</li>
               <li>Person.</li>
               <li>Student.</li>
            </ul>
         </example>
         <illustration id="ETGfx" width="550" caption="Graphische Darstellung von Entitäten und Entitätstypen" gfx="db/EET.gif"/>
         <p>Soll ein Hinweis auf eine spätere physische
        Realisierung (d.h. die gewählte Form der Abspeicherung von
        <a href="#E">Entitäten</a> in der Datenbank) gegeben werden, so kann einem
        <a href="#ET">Entitätstypen</a> ein <a href="#RT">Repräsentationstyp</a> zugeordnet werden, bzw. einer
        <a href="#E">Entität</a> eine <a href="#R">Repräsentation</a>.</p>
         <definition id="RT" term="Repräsentationstyp">
            Ein Repräsentationstyp führt einen physischen Typ in das <a href="#konzSchema">konzeptuelle Schema</a> ein,
            der zur technischen Implementierung eines durch ihn annotierten <a href="#ET">Entitätstypen</a>
            herangezogen werden kann.<br/>
            Als Repräsentationstypen sind beliebige atomare (d.h.
            in ihrer Semantik nicht weiter verlustfrei zerlegbare)
            Datentypen eines logischen oder physischen Modells
            zugelassen.
        </definition>
         <example name="RT-Bsp" caption="Beispiele für Repräsentationstypen">
            <ul>
               <li>Integer</li>
               <li>Datum</li>
               <li>Money</li>
               <li>String</li>
            </ul>
         </example>
         <definition id="R" term="Repräsentation">
            Eine Repräsentation ist eine Ausprägung genau eines <a href="#RT">Repräsentationstypen</a>.
        </definition>
         <example name="R-Bsp" caption="Beispiele für Repräsentationen">
            <p>Der zugehörige Repräsentationstyp ist in Klammern
            angegeben.</p>
            <ul>
               <li>42 (Integer)</li>
               <li>
                  <current value="year"/>-<current value="month"/>-<current value="day"/> (Datum)</li>
               <li>99,95 (Money)</li>
               <li>"Hallo Welt!" (String)</li>
            </ul>
         </example>
         <p>Die graphische Darstellung erfolgt durch benannte
        Rechtecke. <a href="#R">Repräsentationen</a> werden unterstrichen mit der
        geklammerten nachfolgenden Angabe des <a href="#RT">Repräsentationstypen</a>
        dargestellt.<br/>
            <a href="#RT">Repräsentationstypen</a> werden durch eine gerichtete Kante mit unterbrochener
        Linienführung mit dem durch sie
        repräsentierten <a href="#ET">Entitätstypen</a> verbunden.</p>
         <illustration id="Rep" width="550" caption="Repräsentation und Repräsentationstyp" gfx="db/rep.gif"/>
         <p>Das Beispiel der <illustrationLink ref="ident"/> zeigt
        verschiedene Beispiele für die Verknüpfung von
        Entitätstypen mit ihren zugehörigen
        Repräsentationstypen.<br/>
        Im Teilbeispiel (1) wird der Entitätstype
        <code>Name</code> unmittelbar durch den
        Repräsentationstypen <code>String</code> repräsentiert,
        d.h. die spätere physische Realisierung des Entitätstypen
        <code>Name</code> wird durch den Datentyp
        <code>String</code> erfolgen.<br/>
        Teilbeispiel (2) zeigt eine transitive Repräsentation
        (genaugenommen eine transitive Repräsentation erster
        Ordnung). Hier ist der Entitätstyp <code>Person</code>, welcher selbst über keinen Repräsentationstypen verfügt,
        in eindeutiger Weise (d.h. über einen Assoziationstyp der
        ausschließlich über Kardinalitsintervalle von
        <code>1:1</code> verfügt (nach Maßgabe der <a href="#anmKI">Anmerkung zur Struktur der
        Kardinalitätsintervalle</a> kann es sich daher nur um
        einen binären Assoziationstypen handeln)) mit dem
        Entitätstypen <code>Name</code> verknüpft, der über die
        Repräsentation <code>String</code> verfügt.<br/>
        Abschließend zeigt das Teilbeispiel (3) die transitive
        eindeutige Assoziierung des Entitätstypen
        <code>Person</code> mit dem Entitätstypen
        <code>Personalausweis</code> durch den Assoziationstypen
        <code>Identifikation</code>, wobei
        <code>Personalausweis</code> seinerseits in eindeutiger
        Weise mit der durch <code>Integer</code> repräsentierten
        Erfassungsnummer assoziiert ist.</p>
         <illustration id="ident" width="550" caption="Identifizierende Repräsentationen" gfx="db/ident.gif"/>
         <definition id="A" term="Assoziation">
            Eine Assoziation ist eine benannte n-äre Beziehung (n&gt;1) zwischen
            <a href="#E">Entitäten</a>.<br/>
            Die Semantik jeder durch eine Assoziation verbundenen
            <a href="#E">Entität</a> wird durch Angabe einer innerhalb einer
            Assoziation für jede verbundene Entität eindeutigen
            Rolle konkretisiert.<br/>
				Im graphischen <E3R/>-Modell wird eine Assoziation durch eine Raute dargestellt, die durch ungerichtete Kanten mit Entitäten verbunden ist. Im Zentrum wird der Name der Assoziation, gefolgt vom in Klammern geschriebenen Namen des <a href="#AT">Assoziationstypen</a> plaziert. Zusätzlich sind die beiden Namen unterstrichen dargestellt.
        </definition>
         <definition id="AT" term="Assoziationstyp">
            Ein Assoziationstyp ist eine duplikatfreie ungeordnete Sammlung von logisch als zusammengehörig betrachteten
            <a href="#A">Assoziationen</a>.<br/>
            Jede zu einem Assoziationstypen beitragende <a href="Rolle">Rolle</a> wird
            durch ein <a href="#KI">Kardinalitätsintervall</a> ergänzt.<br/>
				Im graphischen <E3R/>-Modell wird ein Assoziationstyp durch eine Raute dargestellt, die durch ungerichtete Kanten mit Entitätstypen verbunden ist. Im Zentrum des Assoziationstypen wird sein schemaweit eineindeutiger Name plaziert.
        </definition>
         <example name="AT-Bsp" caption="Beispiele für Assoziationstypen">
            <ul>
               <li>Arbeitsverhältnis.</li>
               <li>Ehe.</li>
               <li>Verwandschaft.</li>
            </ul>
         </example>
         <definition id="KI" term="Kardinalitätsintervall">
            Ein Kardinalitätsintervall legt die Anzahl derjenigen
            <a href="#E">Entitäten</a> fest, die mit einer die <a href="#Rolle">Rolle</a>
            einnehmenden
            <a href="#E">Entität</a> zu einem Zeitpunkt innerhalb einer <a href="#A">Assoziation</a>
            verbunden sein können.<br/>
            Das Intervall wird in der Schreibweise
            <gerquot>i:j</gerquot> angegeben, wobei <em>i</em>
            eine beliebige natürliche Zahl oder die Null ist und
            <em>j</em> eine beliebige natürliche Zahl oder das
            Symbol <em>n</em> ist. Zusätzlich gilt: i&lt;=j.
        </definition>
         <example name="KI-Bsp" caption="Beispiele für Kardinalitätsintervalle">
            <ul>
               <li>0:1.</li>
               <li>3:7.</li>
               <li>0:n.</li>
               <li>1:n.</li>
               <li>99:n.</li>
            </ul>
         </example>
         <p>Ungültig hingegen sind:</p>
         <ul>
            <li>7:0 (Obergrenze kleiner als Untergrenze).</li>
            <li>-5:7 (-5 ist keine natürliche Zahl.)</li>
            <li>n:8 (<em>n</em> ist nicht als Untergrenze
            erlaubt.)</li>
         </ul>
         <p>
            <a name="anmKI">Allgemein</a> gilt: Für <em>n</em>-äre <a href="#AT">Assoziationstypen</a> gilt
        die Einschränkung, daß die Maximalkardinalität
        die ein <a href="#ET">Entitästyp</a> zu einem <em>n</em>-ären
        <a href="#AT">Assoziationstypen</a> beitragen darf größer gleich <em>n</em>-1
        ist.</p>
         <illustration id="Ass" width="502" caption="Assoziationen und Assoziationstypen" gfx="db/Ass.gif"/>
         <p>Zentrales Konzept des E<sup>3</sup>R-Modells ist die Idee der Rolle,
        welche als hauptinformationstragendes Konstrukt fungiert:</p>
         <definition id="Rolle" term="Rolle">
            Eine Rolle die durch einen <a href="#ET">Entitätstypen</a> innerhalb eines <a href="#AT">Assoziationstypen</a>
            eingenommen wird charakterisiert die konkrete Verwendung von <a href="#E">Entitäten</a>
            des gegebenen Typs im Kontext
            der <a href="#A">Assoziationen</a> die zum betrachteten <a href="#AT">Assoziationstyp</a> zusammengefaßt werden.
        </definition>
         <p>Anmerkung: Für den relationalen
        Datenbankentwurf ist es notwendig, daß jeder im konzeptuellen Schema
        modellierte <a href="#ET">Entitätstyp</a> entweder über einen <a href="#RT">Repräsentationstyp</a>
        verfügt oder über eine <em>Namenskonvention</em>, d.h.
        eine binäre <a href="#AT">Assoziationstyp</a> deren <a href="#KI">Kardinalitätsintervalle</a>
        ausschließlich auf 1:1 festgelegt sind, die den
        Entitätstyp direkt oder transitiv mit einem mit
        Repräsentation versehenen Entitätstypen verbindet.</p>
         <p>Gleichzeitig wird durch die Rolle der Brückenschlag
        zwischen natürlicher Sprache und formaler graphischer
        Darstellung im E<sup>3</sup>R-Modell ermöglicht.<br/>
        So lassen sich die Sätze</p>
         <ul>
            <li>Jede Person arbeitet optional für mehrere
            Firmen.</li>
            <li>Jede Firma beschäftigt ein oder mehrere
            Personen.</li>
         </ul>
         <p>in das nachfolgende konzeptuelle Schema überführen:</p>
         <illustration id="role" width="342" caption="Vollständiges konzeptuelles Schema" gfx="db/role.gif"/>
         <p>Zusätzlich zeigt das konzeptuelle Schema der
        <illustrationLink ref="role2"/> die Mächtigkeit des
        Rollenkonzepts zur Darstellung verschiedener
        Informationszusammenhänge.<br/>
        So enthält das abgebildete konzeptuelle Schema die drei
        verschiedenen Assoziationstypen <code>Abhaltung</code>,
        <code>Lieblingskurs</code> und <code>Befähigung</code>
        welche ausschließlich Rollen enthalten die durch die beiden dargestellten
        Entitätstypen <code>Referent</code> und <code>Kurs</code>
        gespielt werden.</p>
         <illustration id="role2" width="550" caption="Verschiedene Rollen" gfx="db/rolle2.gif"/>
         <definition id="hET" term="Hybrider Entitäts-Assoziationstyp">
            Ein hybrider Entitäts-Assoziationstyp vereinigt das Sprachelement des <a href="#ET">Entitätstyps</a>
            und des <a href="#AT">Assoziationstyps</a> in sich und bewahrt die Semantik beider Konstrukte.
        </definition>
         <illustration id="hET-Bsp" width="550" caption="Hybrider Entitäts-Assoziationstyp" gfx="db/het.gif"/>
         <p>Abbildung <illustrationLink ref="het-Bsp2"/> stellt die Informationsstruktur einer Adresse dar.<br/>
        Dabei zeigt das konzeptuelle Schema die Verwendung der
        hybriden Entitäts-Assoziationstypen. So können jedem
        <code>Straßennamen</code> beliebig viele
        <code>Hausnummer</code>n zugeordnet werden und umgekehrt.
        Jeweils zwei dieser Angaben zusammen bilden die
        <code>Straße</code>.<br/>
        Jedem <code>Ortsnamen</code> kann über mehrere
        <code>Postleitzahlen</code> verfügen, ebenso kann dieselbe
        Postleitzahl mehreren gleich benannten Orten zugeordnet
        werden (Beispiel: Ortsteile). <code>Postleitzahl</code>
        und <code>Ortsname</code> zusammen bilden den
        <code>Ort</code>.<br/>
        Aus der Kombination von <code>Straße</code> und
        <code>Ort</code> wird eine <code>Adresse</code> gebildet.
        Dabei kann jede <code>Straße</code> (=Kombination aus
        <code>Straßenname</code> und <code>Hausnummer</code>)
        mehreren Orten (=Kombination aus <code>Ortsname</code> und
        <code>Postleitzahl</code>) und umgekehrt zugeordnet
        sein.</p>
         <p>Das Beispiel unterstreicht die alleinige Bildbarkeit
        hybrider Entitäts-Assoziationstypen beim vorliegen von
        Kardinalitätsintervallen, die alle über ein Maximum größer
        1 verfügen.<br/>
        Vgl. hierzu Aussagen der <a href="#anmKI">Anmerkung zur
        Bildung von Kardinalitätsintervallen</a>
         </p>
         <illustration id="het-Bsp2" width="550" caption="Informationsstruktur Adresse" gfx="db/adresse.gif"/>
         <subsubtopic name="adv">Weiterführende Konzepte</subsubtopic>
         <definition id="Spez" term="Spezialisierungsassoziationstyp">
            Ein Spezialisierungsassoziationstyp ist eine
            duplatfreie ungeordnete Sammlung von logisch als
            zusammengehörig betrachteten <a href="#A">Assoziationen</a>.Zu den in der Menge
            enthaltenen Assoziationen tragen der zu
            spezialisierende <a href="#ET">Entitätstyp</a> (der
            sog. <em>Super-</em> oder <em>Obertyp</em>) und der
            spezialisierende (entsprechend als sog. <em>Sub-</em>
            oder <em>Untertyp</em> bezeichnet) Rollen bei.<br/>
            Die Rolle des Supertyps ist hierbei auf <em>wird
            spezialisiert zu</em> fixiert, als
            Kardinalitätsintervalle sind ausschließlich
            <code>0:1</code>, <code>0:n</code>, <code>1:1</code>
            und <code>1:n</code> zulässig.<br/>
            Die Rolle des Subtyps ist auf <em>ist Spezialisierung
            von</em> mit dem Kardinalitätsintervall
            <code>1:n</code>fixiert.<br/>
            Jeder Spezialisierungsassoziationstyp wird durch ein
            Distinktionsmerkmal charakterisiert, das expliziert
            hinsichtlich welchen Merkmals die Spezialisierung
            gebildet wird.<br/>
            Die Verknüpfung durch einen
            Spezialisierungsassoziationstyp bewirkt, daß alle
            Assoziations- und Repräsentationstypen, die für den
            Supertyp definiert sind auch automatisch für alle
            Subtpyen definiert werden.
        </definition>
         <illustration id="GfxSpez" width="600" caption="Spezialisierung" gfx="db/spez.gif"/>
         <p>Die <illustrationLink ref="GfxSpez"/> zeigt die
        Spezialisierung des Entitätstypen <code>Person</code>
        hinsichtlich des Distinktionsmerkmals
        <code>Vertrag</code>. Dabei
        gilt: Jede Person kann nur genau einmal
        (<code>1:1</code>) hinsichtlich ihres (Arbeits-)Vertrages zu
        <code>Angestellter</code> oder <code>Arbeiter</code> spezialisiert
        werden.</p>
         <p>
            <illustrationLink ref="GfxSpez"/> zeigt ferner, daß die spezialisierten Entitätstypen  <code>Angestellter</code> und <code>Arbeiter</code> über zusätzliche, d.h. für den Obertyp <code>Person</code> nicht definierte, Eigenschaften (<code>Gehalt</code> bzw. <code>Stundenlohn</code>) verfügen.</p>
         <p>
            <b>Zur Pragmatik des Spezialisierungsassoziationstyps</b>:<br/>
		  Spezialisierungsassoziationstypen sollten ausschließlich dann eingesetzt werden, wenn es sich um <gerquot>echte</gerquot> Spezialisierungen handelt. Eine <em>echte Spezialisierung</em> liegt immer dann vor, wenn jeder spezialisierte Entitätstyp über Assoziationstypen verfügt, die der allgemeinere Obertyp nicht besitzt.</p>
         <p>Gilt dieses Kriterium nicht, d.h. können für die spezialisierten Entitätstypen keine zusätzlichen Eigenschaften gebildet werden, dann solte die Spezialisierung <em>nicht vorgenommen</em> werden.<br/>
		  In diesem Falle bietet sich die Überführung der unnötigen Spezialisierung eine Eigenschaft des (vermeintlichen) Obertypen an. Zusätzlich sollte ein Entitätstyp zur Aufnahme derjenigen Information gebildet werden, für welche die  Darstellung als Spezialisierungsassoziationstyp intendiert war.<br/>
		  Dieser neue Entitätstyp kann geeignet mit einem Repräsentationstyp versehen werden, um die unterscheidende (distingierende) Information darzustellen.<br/>
		  Die einzelnen Schritte sind in <illustrationLink ref="GfxSpez2"/> beispielhaft zusammengestellt.</p>
         <illustration id="GfxSpez2" width="591" caption="Auflösung einer unechten Spezialisierung" gfx="db/spez2.png"/>
         <definition id="Metainformation" term="Metainformation">
            Informationsanteile eines Modells, die nicht direkt in
            das logische Schema übernommen werden, sondern in
            konsistenzgarantierende Regeln oder Applikationscode
            abgebildet werden.
        </definition>
         <p>Die <illustrationLink ref="meta1"/> veranschaulicht die
        Nutzung des Spezialisierungsassoziationstyps zur
        Formulierung von Metainformation. Im Beispiel wird
        gefordert, daß jeder <code>Abteilungsleiter</code> auch
        gleichzeitig als Mitarbeiter der durch ihn geleiteten
        Abteilung erfaßt sein muß.</p>
         <p>
            <em>Hinweis</em>: Metainformation muß nicht zwingend
        semantisch irreduzibel erfaßt werden, wie die ---
        eigentlich illegale Bildung der beiden hybriden
        Entitäts-Assoziationstypen <code>Abteilungsleitung</code>
        und <code>Abteilungsmitgliedschaft</code> zeigt.</p>
         <illustration id="meta1" width="550" caption="Metainformation" gfx="db/meta1.gif"/>
         <p>Das konzeptuelle Schema der <illustrationLink ref="meta2"/> zeigt ein Beispiel für konsistenzgarantierende
        Metainformation, die nicht durch E<sup>3</sup>R-Syntax
        ausdrückbar ist und daher in textueller Form annotiert
        wird.</p>
         <illustration id="meta2" width="550" caption="Metainformation" gfx="db/meta2.gif"/>
         <subsubtopic name="Phasenmodell">Phasenmodell der Erstellung eines
        konzeptuellen Schemas mit E<sup>3</sup>R</subsubtopic>
         <p>E<sup>3</sup>R ist eine Notation und Methode zur
        Entwicklung des konzeptuellen Schemas für jede beliebige
        Art von Kommunikationssituationen.</p>
         <p>
            <b>Phase 0</b> ist die Vorbereitungsphase, die von der
        Idee, ein E<sup>3</sup>-Schema für einen <a href="#konzSchema">Realitätsausschnitt</a> zu erstellen,
        über die Auswahl der Beteiligten bis zu ihrer Ausbildung
        in den Techniken zur Darstellung von Information und in
        der Vorgehensweise der Analyse reicht.</p>
         <p>Es folgt die Festlegung des Informationsbereichs
        (<b>Phase 1</b>). Hier werden die für den gewünschten
        Anwendungsbereich relevanten Entitäten und Assoziationen
        gesammelt und zu Entitäts- und Assoziationstypen
        zusammengefaßt. Eine große Hilfe dabei sind verbale
        Beschreibungen der in der Datenbank zu verwaltenden
        Information, kommentierte Listen mit Daten des betrachteten
        Informationsbereichs oder ähnliches. Das Ergebnis ist eine
        erste, grobe Struktur der relevanten Information.</p>
         <p>Diese Struktur wird in <b>Phase 2</b> immer weiter
        verfeinert, wobei man für jeden Entitätstyp entweder
        direkt oder transitiv eine Repräsentation definiert.<br/>
        Dann werden alle relevanten Eigenschaften, die eine
        Entität eines Typs haben kann, in Form von semantisch
        irreduzibel formulierten Assoziationstypen beschrieben.
        Dabei treten erfahrungsgemäß neue, zuvor nicht
        berücksichtigte Entitätstypen auf.</p>
         <p>Deshalb wird die Phase 2 solange inkrementell iteriert,
        bis keine neuen Entitätstypen mehr identifiziert werden zu
        denen noch Repräsentation zu definieren oder durch Assoziationstypen anzubinden
        sind.</p>
         <p>Bis zu diesem Punkt standen strukturelle, formale
        Gesichtspunkte im Vordergrund. In <b>Phase 3</b> treten
        diese zurück; nun stehen semantische Gesetzmäßigkeiten im
        Vordergrund, soweit diese nicht bereits in den Phasen 1
        und 2 erkannt und behandelt worden sind.</p>
         <p>Ziel der Phase 3 ist es, die bis dato erstellte
        Informationsbeschreibung geeignet zu ergänzen um auch
        alle nicht durch die E<sup>3</sup>R-Notation darstellbaren
        Konsistenzregeln zu erfassen.<br/>
        Zusätzlich kann die E<sup>3</sup>R-Notation zur
        Formulierung von Metainformation auf einer höheren
        Modellebene angewendet werden.</p>
         <p>
            <b>Hinweis</b>: Es kann beim Erstellen des
        konzeptuellen Schemas durchaus vorkommen, daß sich das
        Ergebnis der vorausgegangenen Phase als unvollständig
        herausstellt. In diesem Fall ist es unbedingt notwendig,
        in diese Phase zurückzukehren und dann mit dem
        korrigierten Ergebnis dieser Phase weiterzuarbeiten. Dies
        ist kein Wegwerfen der bisher geleisteten Arbeit, denn
        meist genügen einige wenige Streichungen und
        Ergänzungen.<br/>
        Bleibt diese Regel unberücksichtigt, so nimmt begibt man
        sich der Möglichkeit wichtige Eigenschaften der
        Information im konzeptuellen Schema eindeutig
        festzuhalten. Dabei spricht das Verhältnis zwischen der
        gewonnen Exaktheit und dem zusätzlichen Aufwand sehr
        zugunsten der exakten und sauberen Lösung.</p>
         <p>Resultat der korrekten Anwendung des Phasenmodelles ist
        ein <em>vollständiges konzeptuelles Schema</em> als
        Voraussetzung der Umsetzbarkeit in beliebige logische
        Strukturen.</p>
         <definition id="vollstCS" term="Vollständiges konzeptuelles Schema">
            Ein vollständiges konzeptuelles Schema ist ein
            <E3R/>-Schema in dem alle Entitäts- und Assoziationstypen, sowie alle Rollen
            benannt sind. Darüberhinaus ist jede Rolle mit einem
            korrekten Kardinalitätsintervall versehen, sowie jedem
            Entitätstypen direkt oder transitiv ein
            Repräsentationstyp zugeordnet.<br/>
            Sofern Metainformation existiert, ist diese auch in
            adäquater Weise dargestellt.
        </definition>
         <subsubtopic>Fallstudie:
        Fächerdatenbank</subsubtopic>
         <p>Der Fachbereich möchte die Belegung der
        Fächer in einer Datenbank abspeichern; hierfür
        gelten folgende semantische Regeln:</p>
         <p>Die vorgesehenen Fächer haben eine feste Nummer, die
        sich niemals ändert sowie eine einen längeren Titel.
        Zusätzlich sind sie von einem Fachbereich entweder für einen
        speziellen Studiengang (z.B.
        <em>WIB</em>) oder allen Studiengängen angeboten, dann
        gilt die Zuordnung <em>FH</em>. Gleichzeitig kann jedes
        Wahlfach einem Fächerblock (z.B. <em>Consulting</em> oder
        <em>Informatik</em>) zugeordnet sein.</p>
         <p>Die in einem bestimmten Semester angebotenen Fächer
        erhalten eine Veranstaltungsnummer, die nur für dieses Semester
        gilt. Dazu wird der jeweilige Dozent angegeben und die
        Art der Lehrveranstaltung (<em>Vorlesung</em>,
        <em>Seminar</em>, <em>Praktikum</em> etc.) sowie ihr Umfang in Semesterwochenstunden.<br/>
        Die Notenbildung in jedem Fach kann durch eine oder
        mehrere Prüfungsleistungen erfolgen (z.B.
        <em>Leistungsnachweis</em>, <em>Schein</em>,
        <em>Prüfung</em>, etc.), die in unterschiedlichen Prozentsätzen gewichtet werden.
        Jede Prüfung findet zu einem festgelegten Datum in einem Raum zu einer Uhrzeit statt
        und wird durch mindestens einen Dozenten beaufsichtigt. Zusätzlich soll die Dauer der
        Prüfungsleistung vermerkt werden.</p>
         <p>Ein Student ist durch eine eindeutige Matrikelnummer
        gekennzeichnet. Zusätzlich wird sein Studiengang gespeichert.</p>
         <illustration id="uniVerw" width="550" caption="Konzeptuelles Schema der Fallstudie" gfx="db/uniVerw.gif"/>
         <subtopic name="Ableitung">Ableitung logischer Relationenstrukturen</subtopic>
         <subsubtopic name="RelGrundBegr">Erweiterung der Grundbegriffe des
        Relationenmodells</subsubtopic>
         <definition id="Superschluessel" term="Superschlüssel">
            Ein Superschlüssel <em>SK</em> ist eine nicht-leere Teilmenge von Attributen
            einer <a href="#Relation">Relation</a> für die gilt,
            daß zwei verschiedene Tupel <em>t<sub>1</sub>
            </em> und
            <em>t<sub>2</sub>
            </em> dieser Relation keine gleiche
            Wertbelegung aufweisen.
        </definition>
         <p>Der Superschlüssel definiert damit eine
        <keyword>Eindeutigkeitkeitseinschränkung</keyword>, nach
        der zwei Tupel allein über die Betrachtung der im
        Superschlüssel zusammengefaßten Attribute unterscheidbar
        sind.</p>
         <example name="SuperschluesselEx" caption="Beispiele für Superschlüssel">
            <p>Gegeben sei die Relation <em>Mitarbeiter</em>:<br/>
               <code>
                  <pre>+---------+-------------+--------------+-------------------+
| Vorname | Nachname    | Geburtsdatum | Persausweisnummer |
+---------+-------------+--------------+-------------------+
| Xaver   | Obermüller  | 1970-03-04   | 134975459         |
| Rosi    | Hinterhuber | 1973-06-02   | 781367519         |
| Rosi    | Obermüller  | 1963-11-03   | 783148384         |
| Hans    | Hinterhuber | 1970-03-04   | 977554422         |
+---------+-------------+--------------+-------------------+
</pre>
               </code>
            </p>
            <p>Mögliche Superschlüssel dieser Relation
        sind:</p>
            <ul>
               <li>
                  <code>(Vorname, Nachname, Personalausweisnummer)</code>
               </li>
               <li>
                  <code>(Nachname, Geburtsdatum, Personalausweisnummer)</code>
               </li>
               <li>
                  <code>(Geburtsdatum, Personalausweisnummer)</code>
               </li>
               <li>...</li>
            </ul>
         </example>
         <definition id="Schluessel" term="Schüssel">
            Ein Schlüssel <em>K</em> ist ein <a href="#Superschluessel">Superschlüssel</a>, der sofern
            man ein Attribut aus ihm entfernt nicht mehr
            eindeutigkeitseinschränkend wirkt.
        </definition>
         <example name="SchluesselEx" caption="Beispiele für Schlüssel">
            <p>Der einzige Schlüssel der Relation <a href="#SuperschluesselEx">Mitarbeiter</a> ist
        <code>Personalausweisnummer</code>.</p>
         </example>
         <p>
            <em>Anmerkungen</em>:</p>
         <ul>
            <li>Die Menge aller Attribute einer Relation ist immer
            Superschlüssel.</li>
            <li>Jeder Schlüssel ist auch ein Superschlüssel.<br/>
            Der Umkehrschluß gilt nicht, da Schlüssel eine schärfere Forderung darstellt.</li>
            <li>Jeder Schlüssel ist zwingend eine minimal
            identifizierende Attributkombination.</li>
         </ul>
         <p>Häufig tritt es in der Praxis auf, daß sich in einer
        Relation mehr als ein Schlüssel finden läßt. Jeder dieser
        möglichen gleichwertigen Schlüssel wird daher als
        <em>
               <keyword>Schlüsselkandidat</keyword>
            </em> bezeichnet.</p>
         <example name="SuperschluesselEx" caption="Beispiele für Superschlüssel">
            <p>Gegeben sei die Relation <em>Lagerverwaltung</em>:<br/>
               <code>
                  <pre>+------------+---------------+-----------------+-------+
| Lagerplatz | Produktnummer | Produktname     | Menge |
+------------+---------------+-----------------+-------+
| 7952       | 7946          | Wusch Superfein | 3     |
| 7412       | 9854          | Blitzbank Extra | 5     |
| 7894       | 6542          | Maiengrün natur | 7     |
| 9461       | 8954          | Gelber Gigant   | 5     |
+------------+---------------+-----------------+-------+
</pre>
               </code>
            </p>
            <p>Die Relation enthält folgende Schlüsselkandidaten.</p>
            <ul>
               <li>
                  <code>Lagerplatz</code>
               </li>
               <li>
                  <code>Produktnummer</code>
               </li>
               <li>
                  <code>Produktname</code>
               </li>
            </ul>
         </example>
         <definition id="Primaerschluessel" term="Primärschüssel">
            Ein Primärschlüssel <em>P</em> ist ein <a href="#Schluessel">Schlüssel</a>, der als
            identifizierendes Merkmal ausgewählt wurde.
        </definition>
         <p>In der <a href="MySQLStart.html#demodbstruct">graphischen
        Darstellung der Demo-DB</a> sind die Primärschlüssel durch
        Unterstreichung der beitragenden Attribute
        hervorgehoben.</p>
         <p>Zur Wahrung der Konsistenz innerhalb einer relationalen
        Datenbank wird üblicherweise u.a. das Mittel der
        <em>referentiellen Integrität</em> eingesetzt, um gleicher
        Wertinhalte in Attributen (derselben oder verschiedener Relationen)
        aufeinander abzustimmen.</p>
         <definition id="RefInt" term="Referentielle Integrität">
            Attributwerte einer durch referentielle Integrität
            verknüpften Relation müssen auch in der verknüpften
            Relation existieren.
        </definition>
         <example name="RefIntEx" caption="Beispiel für referentielle Integrität">
            <illustration id="RefIntGfx" width="455" caption="Über Fremdschlüssel verknüpfte Relationen" gfx="db/Auto.gif"/>
            <p>Das Attribut <code>Persausw.</code> der Relation
<code>Auto</code> verweist auf den Primärschlüssel gleichen Namens
der Relation <code>Person</code>.<br/> Als Konsequenz dürfen für
<code>Persausw.</code> in <code>Auto</code> nur Werte definiert
werden, die sich bereits  im Attribut <code>Persausw.</code> von
<code>Person</code> finden.</p>
         </example>
         <p>Die Prüfung von Primärschlüsselwerten erfordert u.U. eine
    Reihe zusätzlicher Datenbankzugriffe. Zu ihrer Beschleunigung
    können zusätzliche Speicherbereiche, sog. <em>Indexe</em>
    angelegt werden.</p>
         <definition id="Index" term="Index">
    Ein Index ist ein zusätzlicher Speicherbereich der in der
    Datenbank verwaltet wird um den lesenden Zugriff auf einzelne
    Tupel zu beschleunigen.
</definition>
         <p>In der Konsequenz der Beschleunigung der lesenden Zugriffe
    durch zusätzlichen Speicherplatz verringert sich die
    Geschwindigkeit der schreibenden Zugriffe (Erzeugung,
    Aktualisierung und Löschung) etwas.</p>
         <example name="Indexexample" caption="Geschwindigkeitsverhalten mit/ohne Index">
            <p>Die Tabelle <code>tab</code> besteht aus zwei
            Attributen <code>UUID1</code> und <code>UUID2</code>,
            wobei ersteres duplikatfrei indexiert wird.</p>
            <table border="1">
               <tr>
                  <td>
                     <center>
                        <b>Aktion</b>
                     </center>
                  </td>
                  <td>
                     <center>
                        <b>Dauer ohne Index [sec]</b>
                     </center>
                  </td>
                  <td>
                     <center>
                        <b>Dauer mit Index [sec]</b>
                     </center>
                  </td>
               </tr>
               <tr>
                  <td>Einfügen von 10.000.000 Tupeln<br/>
                     <code>INSERT INTO tab VALUES (...)</code>
                  </td>
                  <td>1812</td>
                  <td>2025</td>
               </tr>
               <tr>
                  <td>Auswahl aller Tupel<br/>
                     <code>SELECT COUNT(*) FROM tab WHERE UUID1&lt;&gt;
                    "X"</code>
                     <br/>
                    (<code>UUID1</code> enthält niemals den Wert
                    <code>X</code> daher werden alle Tupel
                    selektiert)</td>
                  <td>2100</td>
                  <td>1800</td>
               </tr>
               <tr>
                  <td>Auswahl genau eines Tupels<br/>
                     <code>SELECT UUID2 FROM tab WHERE UUID1="..."</code>
                  </td>
                  <td>0,422</td>
                  <td>0,028</td>
               </tr>
               <tr>
                  <td>Aktualisierung genau eines Tupels<br/>
                     <code>UPDATE tab SET UUID2="Z" WHERE
                    UUID1="..."</code>
                  </td>
                  <td>0,415</td>
                  <td>0,033</td>
               </tr>
               <tr>
                  <td>Aktualisierung keines Tupels, jedoch vollständige Durchsuchung eines Attributs.<br/>
                     <code>UPDATE tab SET UUID2="Z" WHERE
                    UUID1&lt;&gt;"X"</code>
                  </td>
                  <td>0,395</td>
                  <td>0,014</td>
               </tr>
               <tr>
                  <td>Löschung eines Tupels<br/>
                     <code>DELETE FROM tab WHERE UUID1="..."</code>
                  </td>
                  <td>0,431</td>
                  <td>0,043</td>
               </tr>
               <tr>
                  <td>Löschung keines Tupels, jedoch vollständige Durchsuchung eines Attributs.<br/>
                     <code>DELETE FROM tab WHERE UUID1="x"</code>
                  </td>
                  <td>0,037</td>
                  <td>0,008</td>
               </tr>
            </table>
         </example>
         <p>Die Erstellung des Index nimmt, bei in der Tabelle
        gehaltenen 10.000.000 Tupeln 363,063 Sekunden in
        Anspruch.</p>
         <definition id="NULL" term="NULL-Wert">
    Fehlende Attributwerte in einer Relation werden durch den
    gesonderten Datenbankeintrag <code>NULL</code> dargestellt.
</definition>
         <p>Für die Wertbelegung <code>NULL</code> stellt das DBMS sicher,
daß sie nicht mit der Ziffer 0 oder dem leeren String
kollidiert.</p>
         <subsubtopic name="alg">Der Algorithmus</subsubtopic>
         <p>Zentrale Zielsetzung der Erstellung des konzeptuellen
        Schemas ist die Möglichkeit von ihm ausgehend
        unterschiedliche logische Modelle, die später in die physische Implementierungssicht abgebildet werden,
        ableiten zu können.<br/>
        Dieser Abschnitt stellt einen Algorithmus vor, der es erlaubt aus dem mit <E3R/> formulierten konzeptuellen
        Schema logische Strukturen gemäß dem Relationenmodell abzuleiten.</p>
         <p>Dabei operiert der Algorithmus ausschließlich auf der
        graphischen Repräsentation des konzeptuellen Schemas und
        kann daher auch von entsprechend ausgebildeten
        Fachexperten manuell durchgeführt werden.<br/>
        Der durch den Algorithmus abgeleitete logische
        Datenbankentwurf orientiert sich an festgelegten
        Gütekriterien um einen redundanzfreien und somit
        anomalienfreinen Entwurf zu gewährleisten.</p>
         <subsubtopic name="Schritt1">Schritt 1</subsubtopic>
         <p>Markiere alle Verbindungslinien (d.h. Rollen), an denen das
        Kardinalitätsintervall <code>1:1</code> steht.</p>
         <p>
            <b>Anmerkung</b>: Eine ausschließliche
        <code>1:1</code>-Markierung stellt einen logisch korrekten
        DB-Entwurf sicher.<br/>
        Verbindungslinien, die zu Spezialisierungsassoziationstypen führen müssen nicht markiert werden.</p>
         <p>Das zusätzliche Markieren aller
        <code>0:1</code>-Verbindungen führt zu
        Performanceverbesserungen.<br/>
        Bei relationalen DBMS, die fehlende Werte (<code>NULL</code>) zulassen führt das
        Markieren von <code>0:1</code>-Verbindungen zu einem
        optimalen relationalen DB-Entwurf. Bei Implementiereungen
        die auch optionale Schlüsselkandidaten zulassen führt das
        fortgesetzte Markieren über 0:1 Verbindungen hinweg zu
        effizienten DB-Strukturen.</p>
         <subsubtopic name="Schritt2">Schritt 2</subsubtopic>
         <ol>
            <li>Bilde die Zusammenhangskomponenten (bestehend aus
            Entitäts- und Assoziationsstypen) bezüglich der
            markierten Verbindungslinien.</li>
            <li>Übrigbleibende (d.h. noch außerhalb von Zusammenhangskomponenten plaziert Entitäts- und Assoziationstypen bilden jeweils eine eigene Zusammenhangskomponenten, wenn gilt:
                <ul>
                  <li>Falls ausschließlich alle Mitgliedschaftsintervalle an der
                    Verbindung zwischen einem solchen Entitätstyp
                    und irgendeinem Assoziationstyp den minimalen
                    Wert 0 haben, ist aus diesem Entitätstyp eine
                    eigenständige Zusammenhangskomponente zu bilden, sofern der
                    Entitätstyp kein Repräsentationstyp oder die
                    entsprechenden Entitäten nicht schon in einem
                    anderen Assoziationstyp definiert sind
                    (Kardinalitätsintervall 1:z; z&gt;=1).</li>
                  <li>Repräsentationstypen werden nicht
                    berücksichtigt.</li>
                  <li>Assoziationstypen bilden
                    jeweils (als einziger Inhalt) eine eigene Zusammenhangskomponente.</li>
               </ul>
            </li>
         </ol>
         <subsubtopic name="Schritt3">Schritt 3</subsubtopic>
         <p>Treten innerhalb einer Zusammenhangskomponente Zyklen auf, so sind diese wie folgt
        zu behandeln:</p>
         <p>
            <em>Anmerkung</em>: Ein Zyklus in einer
        Zusammenhangskomponente ist eine Folge {ET<sub>1</sub>,
        AT<sub>1,2</sub>, ET<sub>2</sub>, AT<sub>2,3</sub>, ...,
        ET<sub>n</sub>, AT<sub>n,1</sub>} mit den
        Eigenschaften:</p>
         <ul>
            <li>In allen Assoziationstypen<sub>i,k</sub> (1&lt;=i,
            k&lt;=n) wird die eine Rolle von ET<sub>i</sub> und
            die andere Rolle von ET<sub>k</sub> gespielt.<br/>
               <em>Anmerkung</em>:Zu Untertypen führende Kanten werden behandelt wie
            gewöhnliche Beziehungen zu Assoziationstypen.</li>
            <li>Alle Verbindungslinien einer Folge sind
            markiert.</li>
         </ul>
         <p>Zur Ableitung von Relationen müssen Zyklen aufgelöst
        werden:</p>
         <ul>
            <li>Falls innerhalb eines Zyklus
            <code>0:1</code>-Markierungen vorhanden sind, werden
            diese gelöscht;</li>
            <li>falls nur <code>1:1</code>-Markierungen vorhanden
            sind, wird eine beliebig festzusetzende
            Verbindungslinie gelöscht.</li>
         </ul>
         <subsubtopic name="Schritt4">Schritt 4</subsubtopic>
         <p>Aus jeder Zusammenhangskomponente wird eine Relation
        nach folgenden Regeln:</p>
         <ol>
            <li>Namensgebend für eine Relation ist genau einer der innen
            liegenden Entitätstypen.<br/>
            Enthält eine Zusammenhangskomponente nur einen
            Assoziationstyp, so bekommt die abgeleitete Relation
            dessen Namen.</li>
            <li>Die Relation enthält je ein Attribut für jeden
            direkt mit einer Repräsentation versehenen
            Entitätstypen im Inneren der Zusammenhangskomponente.
            Ein Entitätstyp wird zusammen mit seinen sämtlichen
            Untertypen als ein Entitätstyp betrachtet, sofern die
            Untertypen über keine eigene Repräsentation verfügen.
            </li>
            <li>Zusätzlich enthält die Relation für jeden
            Assoziationstyp im Inneren einer
            Zusammenhangskomponente noch je ein Attribut für jede
            Rolle die zu einem innenliegenden Assoziationstyp beiträgt, welche ein Entitätstyp spielt, der außerhalb der
            Zusammenhangskomponente liegt.<br/>
            Für einen im Inneren der Zusammenhangskomponente
            liegenden Assoziationstyp sind alle Entitätstypen, zu
            denen eine nicht markierte Verbindungslinie führt,
            außerhalb.</li>
            <li>Zusammenhangskomponenten, die ausschließlich aus genau einem
            Assoziationstyp bestehen werden in eine eigenständige Relation
            überführt, die für jede zum Assoziationstyp beitragende Rolle ein
            Attribut enthält.<br/>
            Dieses Attribut wird mit der Repräsentation des rollenspielenden Entitätstypen typisiert.</li>
            <li>Jedes aus einem Entitätstyp im Inneren einer
            Zusammenhangskomponente abgeleitete Attribut ist
            Schlüsselkandidat.
            <br/>
            Außerdem sind alle diejenigen Attribute
            Schlüsselkandidaten, deren entsprechende
            Kardinalitätsintervalle das Maximum 1 besitzen.
            </li>
            <li>In den restlichen Fällen sind alle Attribute
            zusammen Schlüsselkandidat.</li>
            <li>Existiert in einer Relation mehr als genau ein
            Schlüsselkandidat, so ist einer unter diesen als
            Primärschlüssel auszuzeichnen.</li>
            <li>Jeder Untertyp erbt alle Rollen, die sein Obertyp innerhalb von Assoziationstypen spielt.<br/>
            Zusätzlich erbt er auch die vorhandene Repräsentation des Obertyps.</li>
            <li>Relationen, deren Attribute sich aus jeweils
            gleichen Rollen ableiten, werden durch eine
            einzige Relation dargestellt.<br/>
            Treten in einer Zusammenhangskomponente gleiche Rollen
            eines Entitätstyps mehrfach auf, so werden sie in
            einer entsprechenden Relational als genau ein Attribut
            übernommen.</li>
            <li>Manuelles Eingreifen:<br/>
            bei <code>0:1</code>-Markierung ist u.U.
                    eine Entscheidung, orientiert an der
                    modellierten Semantik, zu treffen:<br/>
                    Folgende Konstellationen können das
                    Rückgängigmachen von Markierungen innerhalb
                    einer Zusammenhangskomponente notwendig werden
                    lassen:<br/>
                    mehrere Schlüsselkandidaten und:
                        <ul>
                  <li>alle Schlüsselkandidaten sind
                            optional</li>
                  <li>nicht alle verpflichtend und die
                            Notwendigkeit vorhanden, einen
                            bestimmten als Primärschlüssel
                            festzulegen.</li>
               </ul>
            </li>
         </ol>
         <subsubtopic name="Schritt5">Schritt 5</subsubtopic>
         <ol>
            <li>Leiten sich aus einem Entitätstyp mehrere sich
            entsprechende Attribute ab, so sind die folgenden
            Abhängigkeiten (Fremdschlüsselbeziehungen) zu
            berücksichtigen:
                <ul>
                  <li>Ist eine Attributkombination
                    Schlüsselkandidat, so sind zu den
                    entsprechenden Attributkombinationen, die als
                    Primärschlüssel ausgewählt wurden,
                    Fremdschlüsselbeziehungen vorzusehen.<br/>
                     <em>Hinweis</em>: Fremdschlüsselbeziehungen
                    bedeuten zusätzliche Zugriffe und sollten
                    daher in der Datenbank entsprechend durch
                    Indexstrukturen unterstützt werden.</li>
                  <li>Beim Auftreten identischer
                    Schlüsselkandidaten sind ebenfalls
                    Fremdschlüsselbeziehungen vorzusehen.</li>
               </ul>
            </li>
            <li>Metainformationen, die nicht die DB-Strukturebene
            betreffen, sondern Ausprägungen einschränken, werden
            den entsprechenden DB-Strukturelementen zugeordnet
            (z.B. Domäneneinschränkungen bei Attributen).</li>
         </ol>
         <subsubtopic name="Schritt6">Schritt 6</subsubtopic>
         <p>Ist ein Entitätstyp Spezialisierung (d.h. Untertyp) eines anderen, so wird
        in die Relation die aus der Zusammenhangskomponente gebildet wurde,
        welche den Untertypen beinhaltet die Primärschlüsselattribute derjenigen
        Relation übernommen, die den Obertypen beinhaltet.</p>
         <p>
            <em>Anmerkung</em>: Schlüsselkandidaten dieser Relation werden identisch zu den anderen
       Relationen ermittelt.</p>
         <subsubtopic name="Schritt7">Schritt 7</subsubtopic>
         <ol>
            <li>Systemunabhängig
                <ul>
                  <li>Alle Attribute bekommen als Datentyp den
                    Entitätstyp, durch den sie repräsentiert
                    werden.</li>
                  <li>Bei <code>1:1</code>-Markierung wird für
                    alle Attribute der Relation ein <code>NOT
                    NULL</code> vergeben.</li>
                  <li>Ein Primärschlüssel muß stets mit
                    <code>NOT NULL</code> vereinbart werden.</li>
                  <li>Bei markierten <code>0:1</code>-Beziehungen: Alle aus über <code>0:1</code>-Beziehungen
                    angebundenen Entitätstypen entstehenden
                    Attribute werden auf <code>NULL</code>
                    gesetzt.</li>
                  <li>Schlüsselkandidaten und Zugriffspfade werden
                als Indexe angelegt.</li>
                  <li>Soweit für Metainformation formale
                Umsetzungsmöglichkeiten existieren, werden die
                entsprechenden konsistenzgarantierenden
                Einschränkungen formuliert.</li>
               </ul>
            </li>
            <li>Systemabhängig<br/>
            Die Syntax für die physische Realisierung der
            Relationen (Tabellen) und der Indexstrukturen sowie
            der Datentypen und Einschränkungen (soweit
            unterstützt) müssen dem jeweiligen DBMS angepaßt
            werden.<br/>
            Evtl. durch das DBMS automatisch angelegte
            Indexstrukturen müssen nicht mehr explizit formuliert
            werden.</li>
         </ol>
         <subtopic name="NF">Algebraischer Entwurf mit der Normalformentheorie</subtopic>
         <p>Neben dem graphischen Entwurf logischer DB-Strukturen
        genießt der algebraische Entwurf auf Basis der sog.
        <em>
               <keyword>Normalformentheorie</keyword>
            </em> in Theorie und Praxis große
        Bedeutung.<br/>
        Historisch gesehen stellt die Betrachtung von relationalen
        Strukturen mit Hilfe mathematischer Methoden die älteste
        Disziplin dar und findet sich heute in allen bedeutenden
        Lehrbüchern.<br/>
        Dieser Abschnitt führt in die sechs verschiedenen Normalformen
        hinsichtlich ihrer Definition sowie ihrer Implikationen
        auf die Struktur des logischen Modells ein und zieht
        Parallelen zur Vorgehensweise des eingeführten Algorithmus
        zur Umsetzung konzeptueller Strukturen des
        <E3R/>-Modells.</p>
         <p>Ebenso wie der Algorithmus zur Transformation eines
        <E3R/>-Schemas führt auch die Normalisierung zu einem
        anomalienfreien relationalen Datenbankentwurf.
        Voraussetzung der <keyword>Anomaliefreiheit</keyword> ist die konsequente
        Ermittlung und Eliminierung von Redundanz, d.h. keine
        Information darf in der Datenbank mehrfach vorhanden
        sein.</p>
         <p>Insgesamt verfolgt der Normalisierungsprozeß folgende
        Ziele:</p>
         <ul>
            <li>Redundanzvermeidung als Basis der
            Anomaliefreiheit</li>
            <li>Vermeidung unnötiger Abhängigkeiten, die
            Performanceeinbußen bei Einfüge-, Lösch- und Änderungsoperationen nach sich
            ziehen</li>
            <li>Senkung der Anzahl beteiligter Tabellen bei der
            Modifikation der Datenbank</li>
            <li>Erhöhung des Dokumentationsgrades des entstehenden
            Datenmodells (Ziel: Verständlichkeit)</li>
         </ul>
         <p>Die <keyword>Anomalienfreiheit</keyword> ist die
        zentrale Basisforderung und Zielsetzung des
        Normalisierungsprozesses. Im Detail werden drei
        Ausprägungen unterschiedlicher Anomalien
        unterschieden:</p>
         <ul>
            <li>
               <b>
                  <a name="IAnomalie">
                     <keyword>Einfügeanomalie</keyword>
                  </a>
               </b>: Durch
            das Hinzufügen eines korrekten neuen Tupels werden konsistent
            vorliegende Daten in einen inkonsistenten Zustand
            überführt.</li>
            <li>
               <b>
                  <a name="DAnomalie">
                     <keyword>Löschanomalie</keyword>
                  </a>
               </b>: Durch die
            Entfernung eines Tupels entsteht ein inkonsistenter
            Datenbestand.</li>
            <li>
               <b>
                  <a name="UAnomalie">
                     <keyword>Aktualisierungsanomalie</keyword>
                  </a>
               </b>:
            Durch die Änderung eines vorhandenen Tupels entsteht
            ein inkonsistenter Datenbestand.</li>
         </ul>
         <p>Alle Arten von Anomalien gehen auf das Vorhandensein
        von Redundanz, mithin einem Verstoß gegen die Grundregel
        jede im konzeptuellen Schema modellierte Information an
        nur genau einer Stelle abzuspeichern, zurück.</p>
         <p>Ausgangssituation des Normalisierungsvorganges ist die
        <em>
               <keyword>Urrelation</keyword>
            </em> die alle Attribute
        in genau einer Relation zusammenfaßt.</p>
         <subsubtopic name="1NF">Erste Normalform</subsubtopic>
         <definition id="1NF" term="Erste Normalform (1NF)">
    Eine Relation ist dann in erster Normalform, wenn ihre Domänen
    (=Wertausprägungen der Attribute) nur einfache (atomare) Werte
    besitzen.
</definition>
         <p>
            <em>
               <keyword>Atomarer Wert</keyword>
            </em> bedeutet hierbei,
    daß kein Attributinhalt strukturiert sein darf, d.h. durch
    mögliche Zerlegungsoperationen in kleine eigenständige
    Informationseinheiten zerlegt werden kann.</p>
         <p>Beispiel einer Relation die <b>nicht in 1NF</b> ist:</p>
         <example name="NF2" caption="Relation, die nicht in 1NF ist">
            <table border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>LNAME</b>
                  </td>
                  <td>
                     <b>ADDRESS</b>
                  </td>
                  <td>
                     <b>BDATE</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>Smith</td>
                  <td>731 Fondren, Houston, TX</td>
                  <td>1965-01-09</td>
               </tr>
               <tr>
                  <td>Franklin</td>
                  <td rowspan="2">Wong</td>
                  <td rowspan="2">638 Voss, Houston, TX</td>
                  <td>1955-12-08</td>
               </tr>
               <tr>
                  <td>Joyce</td>
                  <td>1972-07-31</td>
               </tr>
               <tr>
                  <td>Polly Esther</td>
                  <td>Wallace</td>
                  <td>291 Berry, Bellaire, TX</td>
                  <td>1941-06-20, 1952-09-04</td>
               </tr>
            </table>
         </example>
         <p>Ziel der Überführung in 1NF ist es, Relationen zu erhalten,
    die in gängigen RDBMS abspeicherbar sind. Diese bieten zwar heute technische Mechanismen (wie Array- und Referenztypen)
    an, die Strukturen ähnlich den dargestellten verwaltbar werden lassen. Voraussetzung ihrer konzeptionellen Beherrschung ist
    jedoch die vorherige Normalisierung.</p>
         <p>Im Beispiel befinden sich die Zeilen von
    <code>Franklin</code> und <code>Joyce Wong</code> nicht in
    1NF, da sie nicht für jedes Attribut einen Wert besitzen,
    sondern sich eine Wertausprägung (<code>Wong</code> und <code>638 Voss, Houston, TX</code>) teilen.<br/>
    Ebenso befindet sich der Eintrag von <code>Polly Esther Wallace</code> nicht in 1NF, da hier für das Geburtsdatum
    unerlaubterweise zwei Einträge auftreten.<br/>
    Die beiden Vornamen sind im Rahmen der Semantik des Attributes
    <code>FNAME</code> zugelassen und daher im
    Normalisierungsprozeß nicht zu beanstanden.</p>
         <p>Die Relation aus <exampleLink ref="NF2"/> in erster
    Normalform:</p>
         <example name="1NFOK" caption="Relation, die in 1NF ist">
            <table border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>LNAME</b>
                  </td>
                  <td>
                     <b>ADDRESS</b>
                  </td>
                  <td>
                     <b>BDATE</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>Smith</td>
                  <td>731 Fondren, Houston, TX</td>
                  <td>1965-01-09</td>
               </tr>
               <tr>
                  <td>Franklin</td>
                  <td>Wong</td>
                  <td>638 Voss, Houston, TX</td>
                  <td>1955-12-08</td>
               </tr>
               <tr>
                  <td>Joyce</td>
                  <td>Wong</td>
                  <td>638 Voss, Houston, TX</td>
                  <td>1972-07-31</td>
               </tr>
               <tr>
                  <td>Polly Esther</td>
                  <td>Wallace </td>
                  <td>291 Berry, Bellaire, TX</td>
                  <td>1941-06-20</td>
               </tr>
               <tr>
                  <td>Polly Esther</td>
                  <td>Wallace </td>
                  <td>291 Berry, Bellaire, TX</td>
                  <td>1952-09-04</td>
               </tr>
            </table>
         </example>
         <p>Zur Umformung der Relation in eine Relation in erster
    Normalform wurden die <gerquot>gemeinsamen</gerquot> Attribute
    aufgelöst, so das nunmehr jedes Attribut genau einem
    Tabelleintrag (Tupel) zugeordnet ist.<br/>
    Zusätzlich wurde für jedes Attribut die atomare Belegung
    sichergestellt.</p>
         <p>
            <a name="NF2Ref">Die</a> Einführung der ersten Normalform verhindert damit die
    Bildung <em>
               <keyword>geschachtelter Relationen</keyword>
            </em>, die entstünden, jedes Attribut eine
    Menge anderer Attribute, mithin wiederum eine vollständige
    Relation, enthalten könnte.<br/>
            <em>Anmerkung</em>: Diese Forderung wird durch die in SQL:1999 definierten <code>ARRAY</code>-Typen
    aufgeweicht und für postrelationale und objektorientierte Datenbanken vollständig aufgegeben, weshalb diese Strukturen auch als
    <em>
               <keyword>Non-First-Normal-Form</keyword>
            </em> (kurz: <keyword>NFNF</keyword>, <keyword>NF2</keyword> oder <keyword>NF<sup>2</sup>
            </keyword>) bezeichnet
    werden.</p>
         <p>
            <b>Test auf Einhaltung der ersten Normalform</b>:<br/>
    Die Relation sollte keine nicht-atomaren Attribute oder
    verschachtelte Relationen enthalten.</p>
         <p>Der algorithmische Ableitungsprozeß aus dem konzeptuellen
    Schema stellt durch die Organisation der <a href="#RT">Repräsentationstypen</a> sicher, daß Attribute
    ausschließlich durch atomare Werte repräsentiert werden.</p>
         <subsubtopic name="2NF">Zweite Normalform</subsubtopic>
         <p>Grundlegende Voraussetzung zum Verständnis der zweiten
Normalform ist das Konzept der <em>
               <keyword>vollen funktionalen
Abhängigkeit</keyword>
            </em>.</p>
         <definition id="FD" term="Volle funktionale Abhängigkeit">
Ein Attribut <em>y</em> einer Relation ist vollfunktional abhängig
von einem Attribut <em>x</em> wenn gilt, daß jede Ausprägung von
<em>x</em> genau eine Ausprägung von <em>y</em> bestimmt und
<em>y</em> nicht abhängig von Teilattributen von <em>x</em>
ist.<br/>

Im Zeichen: <em>x</em>-&gt;<em>y</em>.<br/> Die vollfunktionale
Abhängigkeit wird häufig als <em>FD</em> (<em>functional
dependency</em>) abgekürzt.
 </definition>
         <p>
            <em>Bemerkung</em>: Man beachte, daß der Begriff
 <em>Attribut</em> in <definitionLink ref="FD"/> eine nichtleere Menge
 von Attributen bezeichnet.</p>
         <p>Beispiel aus der Demodatenbank:</p>
         <code>
            <pre>+-----------+-----+-------+----------+----------------+-----------------+-----------+
| SSN       | PNO | HOURS | FNAME    | DNAME          | PNAME           | PLOCATION |
+-----------+-----+-------+----------+----------------+-----------------+-----------+
| 123456789 |   1 |  32.5 | John     | Research       | ProductX        | Bellaire  |
| 123456789 |   2 |   7.5 | John     | Research       | ProductY        | Sugarland |
| 333445555 |   2 |  10.0 | Franklin | Research       | ProductY        | Sugarland |
| 333445555 |   3 |  10.0 | Franklin | Research       | ProductZ        | Houston   |
| 333445555 |  10 |  10.0 | Franklin | Research       | Computerization | Stafford  |
| 333445555 |  20 |  10.0 | Franklin | Research       | Reorganization  | Houston   |
| 453453453 |   1 |  20.0 | Joyce    | Research       | ProductX        | Bellaire  |
| 453453453 |   2 |  20.0 | Joyce    | Research       | ProductY        | Sugarland |
| 666884444 |   3 |  40.0 | Ramesh   | Research       | ProductZ        | Houston   |
| 888665555 |  20 |  NULL | James    | Headquarters   | Reorganization  | Houston   |
| 987654321 |  20 |  15.0 | Jennifer | Administration | Reorganization  | Houston   |
| 987654321 |  30 |  20.0 | Jennifer | Administration | Newbenefits     | Stafford  |
| 987987987 |  10 |  35.0 | Ahmad    | Administration | Computerization | Stafford  |
| 987987987 |  30 |   5.0 | Ahmad    | Administration | Newbenefits     | Stafford  |
| 999887777 |  10 |  10.0 | Alicia   | Administration | Computerization | Stafford  |
| 999887777 |  30 |  30.0 | Alicia   | Administration | Newbenefits     | Stafford  |
+-----------+-----+-------+----------+----------------+-----------------+-----------+
</pre>
         </code>
         <p>In der Relation existieren folgende voll funktionale
    Abhängigkeiten:</p>
         <illustration id="2NFFD" width="621" caption="Voll funktionale Abhängigkeiten in der dargestellten Relation" gfx="db/2NF.gif"/>
         <p>Es ist offensichtlich, daß zwar <code>HOURS</code> vom
    vollständigen Primärschlüssel (gebildet aus <code>PNO</code>
    gemeinsam mit <code>SSN</code>) abhängen (<code>FD<sub>1</sub>
            </code>), aber
    der Name (<code>FNAME</code>) und die Kombination aus
    <code>PLOCATION</code> und <code>PNAME</code> nur von
    <code>SSN</code> bzw. <code>PNO</code> und damit Teilen des
    Primärschlüssels abhängen (<code>FD<sub>2</sub>
            </code> bzw.
    <code>FD<sub>3</sub>
            </code>).</p>
         <p>Inhaltlich manifestieren sich diese Probleme im Zwang
    verschiedene Daten (etwa <code>SSN</code> und
    <code>FNAME</code>) wiederholt (redundant) abspeichern zu müssen. Ändert
    sich eine dieser Angaben, so muß potentiell eine große Anzahl Tupel in
    der Datenbank aktualisiert werden. Werden hierbei nicht alle
    Datensätze aktualisiert so entsteht ein inkonsistenter
    Datenbestand.<br/>
    Zusätzlich ist es nicht möglich bestimmte Informationszusammenhänge abzubilden.
    Hierunter fällt beispielsweise der Wunsch Projekte (etwa: <code>PLOCATION</code> und <code>PNAME</code>)
    zur verwalten, denen noch keinen Mitarbeiter zugeordnet ist.</p>
         <p>Um eine Relation in 2NF zu überführen muß sie so zerlegt werden, daß alle Attribute der
	 neu entstehenden Relation vom selben Schlüsselkandidaten abhängen.</p>
         <definition id="2NF" term="Zweite Normalform (2NF)">
Eine Relation ist in 2NF genau dann, wenn sie in <a href="#1NF">1NF</a> ist und jedes Nichtschlüsselattribut voll
funktional abhängig von einem Schlüsselkandidaten
ist.</definition>
         <p>Entstehende Relationen:</p>
         <illustration id="2NFOK" width="550" caption="Relationen in 2NF" gfx="db/2NFOK.gif"/>
         <p>
            <b>Test auf Einhaltung der zweiten Normalform</b>:<br/> In
Relationen deren Primärschlüssel mehrere Attribute enthalten,
sollte kein Nichtschlüsselattribut voll funktional von einem Teil
des Primärschlüssels abhängen.</p>
         <p>Der Ableitungsprozeß aus dem konzeptuellen Schema in
<E3R/>-Notation gewährleistet automatisch die Erzeugung von
Relationen in 2NF:</p>
         <illustration id="2NFE3R" width="550" caption="Konzeptuelles Schema in E3R-Notation für die betrachteten Zusammenhänge" gfx="db/2NFE3R.gif"/>
         <subsubtopic name="3NFGliederung">Dritte Normalform
(3NF)</subsubtopic>
         <p>Die dritte Normalform erweitert die für die <a href="#2NF">Zweite</a> getroffenen Aussagen dahingehend, daß
zusätzlich zur <a href="#FD">voll funktionalen Abhängigkeit</a>
die <em>transitive Abhängigkeit</em> eingeführt und betrachtet
wird.</p>
         <definition id="TD" term="Transitive Abhängigkeit">
    In einer Relation <em>R</em> ist ein Attribut <em>z</em>
    transitiv von einem Attribut <em>x</em> abhängig dann und nur
    dann, wenn <em>z</em> voll funktional von <em>y</em> und
    <em>y</em> voll funktional von <em>x</em> abhängig ist.<br/>
    Im Zeichen: x-&gt;-&gt;z</definition>
         <p>
            <em>Bemerkung</em>: Man beachte, daß der Begriff
<em>Attribut</em> in <definitionLink ref="TD"/> eine nichtleere
Menge von Attributen bezeichnet.</p>
         <p>Im Beispiel der Demodatenbank:</p>
         <code>
            <pre>+----------+-----------+------------+--------------------------+---------+---------------+-----------+
| FNAME    | SSN       | BDATE      | ADDRESS                  | DNUMBER | DNAME         | MGRSSN    |
+----------+-----------+------------+--------------------------+---------+---------------+-----------+
| James    | 888665555 | 1937-11-10 | 450 Stone, Houston, TX   |       1 | Headquarters  | 888665555 |
| Jennifer | 987654321 | 1941-06-20 | 291 Berry, Bellaire, TX  |       4 | Administation | 987654321 |
| Ahmad    | 987987987 | 1969-03-29 | 980 Dallas, Houston, TX  |       4 | Administation | 987654321 |
| Alicia   | 999887777 | 1968-07-19 | 3321 Castle, Spring, TX  |       4 | Administation | 987654321 |
| John     | 123456789 | 1965-01-09 | 731 Fondren, Houston, TX |       5 | Research      | 333445555 |
| Franklin | 333445555 | 1955-12-08 | 638 Voss, Houston, TX    |       5 | Research      | 333445555 |
| Joyce    | 453453453 | 1972-07-31 | 5631 Rice, Houston, TX   |       5 | Research      | 333445555 |
| Ramesh   | 666884444 | 1962-09-15 | 975 Fire Oak, Humble, TX |       5 | Research      | 333445555 |
+----------+-----------+------------+--------------------------+---------+---------------+-----------+

</pre>
         </code>
         <p>In der Relation existieren folgende direkten und transitive
Abhängigkeiten (die direkten funktionalen Abhängigkeiten sind
durch gerichtete Kanten mit durchgezogener Linienführung, die
Transitiven durch unterbroche Linienführung dargestellt):</p>
         <illustration id="3NFTD" width="560" caption="Transitive Abhängigkeiten" gfx="db/3NFTD.gif"/>
         <p>In dieser Organisationsform tritt eine <a href="#IAnomalie">Einfügeanomalie</a> auf, wenn ein Mitarbeiter
neu eingefügt wird und dabei <gerquot>falsche</gerquot> (d.h.
inkonsistente) Werte für die Abteilung angelegt werden.<br/>
Zusätzlich fällt das Einfügen neuer Abteilungen, zu denen (noch)
kein Mitarbeiter abgespeichert wird, schwer, da <code>SSN</code>
zwingend anzugeben ist (<code>NULL</code>-Wert ist wegen der
Definition als Primärschlüssel nicht zugelassen!).<br/>

Daneben existiert eine <a href="#DAnomalie">Löschanomalie</a>
dahingehend, daß wenn der letzte Mitarbeiter einer Abteilung aus
der Datenbank entfernt wird auch alle Informationen über diese
Abteilung verloren gehen.<br/>

Werden Abteilungsdaten verändert, so kann es zu einer <a href="#UAnomalie">Modifikationsanomalie</a> kommen, da nicht in
jedem Falle eindeutig klärbar ist ob nur die Abteilungsdaten
dieses Mitarbeiters verändert werden sollen (beispielsweise im
Falle eines Abteilungswechsels) oder die Daten aller
abgespeicherten Abteilungen (beispielsweise im Falle der
Umbenennung einer Abteilung).</p>
         <p>Die dritte Normalform setzt sich zum Ziel die Ursachen dieser
Anomalien zu beseitigen:</p>
         <definition id="3NF" term="Dritte Normalform (3NF)">
            Eine Relation ist dann und nur dann in 3NF, wenn sie
            in <a href="#2NF">2NF</a> ist und jedes
            Nicht-Schlüsselattribut nicht-transitiv abhängig ist
            von einem Schlüsselkandidaten; sie ist auch in 3NF,
            wenn sich eine transitive Abhängigkeit ausschließlich
            über Bestandteile des Schlüsselkandidaten herleiten läßt.
        </definition>
         <p>Gemäß dieser Definition ist die Beispielrelation zu zerlegen
in:<br/>
            <code>R<sub>1</sub>(<u>SSN</u>, FNAME, BDATE, ADDRESS,
DNUMBER)</code> und <br/>
            <code>R<sub>2</sub>(<u>DNUMBER</u>, DNAME, MGRSSN)</code>.</p>
         <illustration id="3NFOK" width="526" caption="Relation in 3NF" gfx="db/3NFOK.gif"/>
         <p>
            <b>Test auf Einhaltung der dritten Normalform</b>:<br/> Eine
Relation sollte kein Nicht-Schlüsselattribut enthalten, das voll
funktional von einem anderen Nicht-Schlüsselattribut (oder von
einer Menge von Nichtschlüsselattributen) abhängig ist. Das heißt,
es sollte keine transitive Abhängigkeit eines
Nichtschlüsselattributs vom Primärschlüssel bestehen.</p>
         <p>Der Ableitungsprozeß aus dem konzeptuellen Schema in
<E3R/>-Notation gewährleistet automatisch die Erzeugung von
Relationen in 3NF:</p>
         <illustration id="3NFE3R" width="550" caption="Konzeptuelles Schema in E3R-Notation für die betrachteten Zusammenhänge" gfx="db/3NFE3R.gif"/>
         <p>
            <b>Das <name>Rissanen</name>-Theorem</b> klärt die sich prinzipiell ergebene
Fragestellung warum die in <illustrationLink ref="3NFOK"/>
dargestellte Zerlegung gewählt wurde, da sich prinzipiell unter
Ausnutzung der transitiven Abhängigkeiten auch eine
(Alternativ-)Zerlegung in <code>R<sub>1</sub>(<u>SSN</u>, FNAME,
BDATE, ADDRESS, DNUMBER)</code> und
<code>R<sub>2</sub>(<u>SSN</u>, DNAME, MGRSSN)</code> angeboten
hätte.</p>
         <p>Nach dem Theorem von <name>Heath</name> und
<name>Rissanen</name> ist jedoch die in <illustrationLink ref="3NFOK"/> gewählte Zerlegung die einzig korrekt mögliche, da
sie die tatsächlich vorhandenen funktionalen Abhängigkeiten
erhält, was bei obiger Alternative nicht der Fall wäre.</p>
         <p>Angewendet auf unser Beispiel bedeutet dies, daß für obige
(nach <name>Heath/Rissenan</name> fehlerhafte) Zerlegung
beispielsweise der Anwendungsfall nach Anlage einer Abteilung
(<code>DNUMER</code> gemeinsam mit ihrem Namen
(<code>DNAME</code>) und der SSN ihres Abteilungsleiters
(<code>MGRSSN</code>) nicht möglich wäre, da <code>DNAME</code> und
<code>MGRSSN</code> nur verwaltet werden können, wenn gleichzeitig
die als Primärschlüssel zwingend anzugebende SSN eines
Mitarbeiters dieser Abteilung existiert. Mithin wäre die
Speicherung einer Abteilung die nur über ihren Leider aber (noch)
nicht über Mitarbeiter verfügt nicht möglich.<br/>

Die gewählte Zerlegung vermeidet jedoch diese Einschränkung und
liefert, ebenso wie der Abteilungsalgorithmus aus dem
konzeptuellen Schema, das korrekte Resultat.</p>
         <subsubtopic name="BCNFChap">Boyce/Codd-Normalform
(BCNF)</subsubtopic>
         <p>Ursprünglich wurde die <em>
               <keyword>Boyce/Codd Normalform</keyword>
            </em> (<keyword>BCNF</keyword>)
als Vereinfachung
der <a href="#3NF">dritten Normalform</a> vorgeschlagen. Jedoch faßt sie
diese schärfer und führt so zu einem neuen Typ von Normalform, der nach
ihren Schöpfern <code>Boyce</code> und <code>Codd</code> benannt wurde.<br/>
Inhaltlich räumt sie mögliche Anomalien aus, die in Relationen, welche sich bereits in
3NF befinden, noch auftreten können.</p>
         <definition id="BCNF" term="Boyce/Codd-Normalform">
    In einer Relation ist dann und nur dann in BCNF, wenn sie in
    <a href="#3NF">3NF</a> ist und gleichzeitig jede Determinante Schlüsselkandidat ist.</definition>
         <p>Hierbei definiert die BCNF den Begriff der <em>
               <keyword>Determinante</keyword>
            </em> als den
Ausgangspunkt einer funktionalen Abhängigkeit.</p>
         <p>Im Beispiel der Demodatenbank:</p>
         <code>
            <pre>+----------+----------------+-----------+
| FNAME    | PNAME          | DLOCATION |
+----------+----------------+-----------+
| Franklin | ProductY       | Sugarland |
| Franklin | ProductZ       | Houston   |
| Jennifer | Newbenefits    | Stafford  |
|   ...    |     ...        |    ...    |
+----------+----------------+-----------+
</pre>
         </code>
         <p>In der Relation existieren folgende funktionale Abhängigkeiten:</p>
         <illustration id="BCNFPic" width="432" caption="Funktionale Abhängigkeiten" gfx="db/BCNF.gif"/>
         <p>Die Schlüsselkandidaten sind durch farbliche Unterstreichung hervorgehoben.
Hierbei bestimmt <code>FNAME</code> gemeinsam mit <code>PNAME</code> eindeutig
einen Wert für <code>DLOCATION</code> (blau) und <code>DLOCATION</code> (rot) bestimmt eindeutig
einen Wert für <code>FNAME</code>.</p>
         <p>Da sich die transitive Abhängigkeit <code>PNAME-&gt;DLOCATION-&gt;FNAME</code> ausschließlich
über Schlüsselkandidaten herleitet ist die Relation in 3NF.<br/>
Dennoch ist sie nicht anomalienfrei, da sie beispielsweise die Ablage von Abteilungsstandorten
(<code>DLOCATION</code>) und den Namen der Abteilungsleiter (<code>FNAME</code>) verbietet, wenn
kein Projektname (<code>PNAME</code>) zusätzlich abgespeichert wird.<br/>
Ebenso ist die Ablage von Projekten und den zuständigen Abteilungen erst dann möglich,
wenn zusätzlich der Name des Abteilungsleiters bekannt ist.</p>
         <p>Dieses Manko wird durch die Forderung der BCNF behoben. Sie erzwingt
die Zerlegung der abgebildeten Ausgangsrelation in zwei Eigenständige. Hierbei
wird jede Determinante der Ausgangsrelation zum Schlüsselkandidaten
in den neu gebildeten Relationen.</p>
         <p>Gemäß <definitionLink ref="BCNF"/> ist die Beispielrelation zu zerlegen in:</p>
         <p>
            <code>R<sub>1</sub>(<u>FNAME, PNAME</u>, DLOCATION)</code>
            <br/>
            <code>R<sub>2</sub>(<u>DLOCATION</u>, FNAME)</code>.</p>
         <illustration id="BCNFOK" width="432" caption="Relation in BCNF" gfx="db/BCNFOK.gif"/>
         <p>
            <b>Test auf Einhaltung der Boyce/Codd-Normalform:</b>
            <br/>
Eine Relation sollte lediglich direkt vom Schlüssel abhängende Attribute enthalten.</p>
         <p>Der Ableitungsprozeß aus dem konzeptuellen Schema in <E3R/>-Notation gewährleistet
automatisch die Erzeugung von Relationen in BCNF:</p>
         <illustration id="BCNFE3R" width="550" caption="Konzeptuelles Schema in E3R-Notation für die betrachteten Zusammenhänge" gfx="db/BCNE3R.gif"/>
         <subsubtopic name="4NFChap">Vierte Normalform (4NF)</subsubtopic>
         <p>Die bisher betrachteten Normalformen nutzen alle das Vorhandensein funktionaler Abhängigkeiten
aus. Jedoch existieren neben diesem Beziehungstyp auch noch andere, im vorhergehenden nicht berücksichtige,
Abhängigkeit.</p>
         <definition id="MVD" term="Mehrwertige Abhängigkeit">
Eine mehrwertige Abhängigkeit (<em>
               <keyword>multivalue dependency</keyword>
            </em>, <keyword>MVD</keyword>)
ist eine Abhängigkeit, die einem einem Attribut eine Menge verschiedener Werte zuordnet.</definition>
         <p>Das Vorhandensein mehrwertiger Abhängigkeiten in einer Relation kann zu
Aktualisierungsanomalien führen, wie die Betrachtung des bekannten Beispiels aus
der Demodatenbank:</p>
         <code>
            <pre>+----------+----------------+-----------+
| FNAME    | PNAME          | DLOCATION |
+----------+----------------+-----------+
| Franklin | ProductY       | Sugarland |
| Franklin | ProductZ       | Houston   |
| Jennifer | Newbenefits    | Stafford  |
|   ...    |     ...        |    ...    |
+----------+----------------+-----------+
</pre>
         </code>
         <p>In der Relation existieren folgende mehrwertige Abhängigkeiten:</p>
         <illustration id="4NFGfx" width="398" caption="Mehrwertige Abhängigkeiten" gfx="db/4NF.gif"/>
         <p>Die Existenz der dargestellten mehrwertigen Abhängigkeiten in der Datenbank
führt dazu, daß dieselbe Information mehrfach abgespeichert werden muß. So enthält die Beispieldatenbank
mehrfach denselben <code>FNAME</code> sowie wiederholt denselben Produktnamen (<code>PNAME</code>).<br/>
Als Konsequenz dieser Wiederholung müssen bei jedem Aktualisierungsvorgang, der die Zuordnung des Produktes zum
<code>FNAME</code> betrifft alle <code>FNAME</code>-Einträge geändert werden, jedoch bei der Zuständigkeitsänderung
eines Produktverantwortlichen nur der betroffene <code>FNAME</code>.</p>
         <p>Ziel der vierten Normalform ist die Elimination von Redundanzen, die aus mehrwertigen Abhängigkeiten
herrühren. Allerdings können mehrwertige Abhängigkeiten nicht vollständig entfernt werden, daher ist für die Normalisierung
gemäß 4NF die Eliminierung aller <em>nicht trivialen</em> mehrwertigen Abhängigkeiten als Zielsetzung definiert.</p>
         <p>Eine <em>
               <keyword>triviale mehrwertige Abhängigkeit</keyword>
            </em> ist hierbei festgelegt als:</p>
         <definition id="tMVD" term="Triviale mehrwertige Abhängigkeit">
Eine triviale mehrwertige Abhängigkeit ist eine mehrwertige Abhängigkeit zwischen Attributmengen <code>X</code> und <code>Y</code>
der Relation <code>R</code> für die gilt:
<code>Y</code> ist eine Teilmenge von <code>X</code> oder die Vereinigung von <code>X</code> und <code>Y</code>
bildet <code>R</code>.</definition>
         <definition id="4NF" term="Vierte Normalform">
Eine Relation ist dann in vierter Normalform, wenn sie nur noch triviale mehrwertige Abhängigkeiten enthält.</definition>
         <p>Gemäß dieser Definition ist die Beispielrelation zu zerlegen in:<br/>
            <code>R<sub>1</sub>(<u>DLOCATION</u>, PNAME)</code> und<br/>
            <code>R<sub>2</sub>(FNAME, <u>PNAME</u>)</code>.</p>
         <illustration id="4NFOK" width="468" caption="Relation in 4NF" gfx="db/4NFOK.gif"/>
         <p>
            <b>Test auf Einhaltung der vierten Normalform</b>:<br/>
Eine Relation sollte keine nicht trivialen mehrwertigen Abhängigkeiten enthalten.</p>
         <p>Der Ableitungsprozeß aus dem konzeptuellen Schema in <E3R/>-Notation gewährleistet automatisch
die Erzeugung von Relationen in 4NF:</p>
         <illustration id="4NFE3R" width="450" caption="Konzeptuelles Schema in E3R-Notation für die betrachteten Zusammenhänge" gfx="db/4NFE3R.gif"/>
         <subsubtopic name="5NFChap">Fünfte Normalform (5NF)</subsubtopic>
         <p>Die fünfte Normalform greift anders als alle vorhergehenden nicht auf die Zusammenhänge der
Typebene zurück, sondern benötigt zu ihrer Untersuchung die Betrachtung von tatsächlichen Datenbankinhalten.<br/>
Ausgehend von diesen definiert sie die fünfte Normalform als:</p>
         <definition id="5NF" term="Fünfte Normalform">
Eine Relation ist dann in <keyword>fünfter Normalform</keyword> (<keyword>5NF</keyword>),
bei ihrer Zerlegung durch Projektionen und deren anschließender Kombination durch Verbundoperationen
keine Tupel gebildet werden, die nicht Bestandteil der Ausgangsrelation waren.</definition>
         <p>Aufgrund ihrer Abstützung auf die Projektions- und Verbundoperation (engl. <em>join</em>) wird
die 5NF auch als <em>
               <keyword>Project Join Normalform</keyword>
            </em> (<keyword>PJNF</keyword>) bezeichnet.</p>
         <p>Im Beispiel der Demodatenbank:</p>
         <p>Relation <code>Ur</code>:<br/>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DNUMBER</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>1</td>
                  <td>Houston</td>
               </tr>
            </table>
         </p>
         <p>Durch Projektion ergeben sich die drei möglichen Relationen:</p>
         <p>
            <code>SELECT Ur.FNAME, Ur.DNUMBER INTO R11 FROM Ur</code>
            <br/>
            <code>R<sub>11</sub>
            </code>:</p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DNUMBER</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>1</td>
               </tr>
            </table>
         </p>
         <p>
            <code>SELECT Ur.FNAME, Ur.DLOCATION INTO R12 FROM Ur</code>
            <br/>
            <code>R<sub>12</sub>
            </code>:</p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>Houston</td>
               </tr>
            </table>
         </p>
         <p>
            <code>SELECT Ur.DNUMBER, Ur.DLOCATION INTO R13 FROM Ur</code>
            <br/>
            <code>R<sub>13</sub>
            </code>:</p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>DNUMBER</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>5</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>5</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>1</td>
                  <td>Houston</td>
               </tr>
            </table>
         </p>
         <p>Durch Verbundoperationen entstehen die Relationen:</p>
         <p>
            <code>SELECT R11.FNAME, R11.DNUMBER, R12.DLOCATION INTO R21
FROM R11 INNER JOIN R12 ON R11.FNAME=R12.FNAME</code>
            <br/>
            <code>R<sub>21</sub>:</code>
         </p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DNUMBER</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>1</td>
                  <td>Houston</td>
               </tr>
            </table>
         </p>
         <p>
            <code>SELECT R11.FNAME, R11.DNUMBER, R13.DLOCATION INTO R22
FROM R11 INNER JOIN R13 ON R11.DNUMBER = R13.DNUMBER</code>
            <br/>
            <code>R<sub>22</sub>:</code>
         </p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DNUMBER</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>1</td>
                  <td>Houston</td>
               </tr>
            </table>
         </p>
         <p>
            <code>SELECT R12.FNAME, R12.DLOCATION, R13.DNUMBER INTO R23
FROM R12 INNER JOIN R13 ON R12.DLOCATION=R13.DLOCATION</code>
            <br/>
            <code>R<sub>23</sub>:</code>
         </p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DNUMBER</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>1</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>
                     <font color="red">James</font>
                  </td>
                  <td>
                     <font color="red">5</font>
                  </td>
                  <td>
                     <font color="red">Houston</font>
                  </td>
               </tr>
               <tr>
                  <td>
                     <font color="red">John</font>
                  </td>
                  <td>
                     <font color="red">1</font>
                  </td>
                  <td>
                     <font color="red">Houston</font>
                  </td>
               </tr>
            </table>
         </p>
         <p>Trotz der ausschließlich durch Rekombination der zuvor aus der Urrelation gebildeten
Projektionen (d.h. ohne Hinzunahme neuer) Daten <gerquot>entstehten</gerquot> in Relation <code>R<sub>23</sub>
            </code>
(rot hervorgehobene) Tupel (sog. <em>
               <keyword>spurious tupel</keyword>
            </em>), die in dieser Form nicht in der Ausgangsrelation präsent waren.</p>
         <p>Erst das Zusammenfügen aller aus Verbundoperationen erzeugten Relationen durch einen erneuten Verbund
eliminiert diesen <em>unechten Tupel</em>:</p>
         <p>
            <code>SELECT R21.FNAME, R22.DNUMBER, R23.DLOCATION INTO RESULT
FROM (R21 INNER JOIN R22 ON (R21.FNAME = R22.FNAME) AND (R21.DNUMBER = R22.DNUMBER) AND (R21.DLOCATION = R22.DLOCATION))
INNER JOIN R23 ON (R22.FNAME = R23.FNAME) AND (R22.DNUMBER = R23.DNUMBER) AND (R22.DLOCATION = R23.DLOCATION) AND
(R21.FNAME = R23.FNAME) AND (R21.DNUMBER = R23.DNUMBER) AND (R21.DLOCATION = R23.DLOCATION)</code>
         </p>
         <p>
            <table style="margin-left:150px" border="1">
               <tr>
                  <td>
                     <b>FNAME</b>
                  </td>
                  <td>
                     <b>DNUMBER</b>
                  </td>
                  <td>
                     <b>DLOCATION</b>
                  </td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Bellaire</td>
               </tr>
               <tr>
                  <td>John</td>
                  <td>5</td>
                  <td>Houston</td>
               </tr>
               <tr>
                  <td>James</td>
                  <td>1</td>
                  <td>Houston</td>
               </tr>
            </table>
         </p>
         <p>Das Auftreten unechter Tupel ist ein Indiz für eine Relation in der Verbundabhängigkeiten existieren. Eine
solche Relation darf nicht weiter zerlegt werden, da durch die Entfernung von Attributen Information verloren ginge.</p>
         <p>
            <b>Test auf Einhaltung der fünften Normalform</b>:<br/>
Wenn durch Projektions- und Verbundoperationen keine unechten Tupel entstehen, dann ist die Relation in 5NF.</p>
         <p>Der Ableitungsprozeß aus dem konzeptuellen Schema in <E3R/>-Notation gewährleistet
automatisch die Erzeugung von Relationen in 5NF:</p>
         <illustration id="5NFE3R" width="550" caption="Konzeptuelles Schema in E3R-Notation für die betrachteten Zusammenhänge" gfx="db/5NFE3R.gif"/>
         <p>Die 5NF ist die höchstmögliche über den Normalisierungsprozeß erreichbare Normalform.<br/>
Dies bedeutet jedoch nicht, daß jede Relation bis in 5NF gebracht werden kann. Der Normalisierungsprozeß
endet generell mit der höchstmöglichen Normalform, dies muß jedoch nicht immer 5NF sein, sondern orientiert
sich an den modellierten Informationszusammenhängen.</p>
         <subsubtopic name="NFAddOn">Weitere Normalisierungsaspekte</subsubtopic>
         <p>Über die im vorhergehedenden betrachteten formalisierten Normalformen hinaus existieren
noch weitere Abhängigkeiten und Normalformen-ähnliche Güteaussagen für Datenbanken.</p>
         <p>
            <b>Inklusionsabhängigkeit</b>:<br/>

Die <keyword>Inklusionsabhängigkeit</keyword> (engl. <em>
               <keyword>inclusion dependence</keyword>
            </em>, ID)
beschreibt die Beziehungen zwischen <a href="#Spez">Super-
und Subtypen</a>, insbesondere die <em>Attributentsprechung</em>, d.h. die Tatsache, daß
der Subtype mindestens alle Attribute des Supertypen aufweist, sowie die <em>Kompatibilitätsrelation</em> worunter
die Austauschbarkeit von Ausprägungen der beiden Typen verstanden wird für Anwendungsbereiche die lediglich
auf die gemeinsam vorhandenen Attribute zugreifen.<br/>
aus der Inklusionsabhängigkeit folgen u.a. die drei Inferenzregeln:<br/>
IDIR<sub>1</sub>: (Reflexivität) Die Inklusionsabhängigkeit ist reflexiv.<br/>
IDIR<sub>2</sub>: (Attributentsprechung) Verfügen zwei Typen über dieselben Attribute, dann entsprechen sie sich.<br/>
IDIR<sub>3</sub>: (Transitivität) Ist <em>B</em> Untertyp von <em>A</em> und <em>C</em> Untertyp von <em>B</em>,
dann ist auch <em>C</em> Untertyp von <em>A</em>.<br/>
Trotz dieser formalisierbaren Aussagen  und der breiten Verwendung von Modellierungskonstrukten zur Darstellung
von Spezialisierungsbeziehungen wurden auf Basis der Inklusionsabhängigkeit bisher noch keine Normalformen
vorgeschlagen.</p>
         <p>
            <b>Template-Abhängigkeiten</b>:<br/>
Die Idee der <keyword>Template-Abhängigkeit</keyword> fußt auf der Definition einer Reihe von <em>Hypothesetupeln</em>
und daraus abgeleiteten <em>Konklusionstupeln</em>, welche gültige Ausprägungen der Datenbank abstrahiert beispielhaft
aufzeigen.<br/>
Template-Abhängigkeiten gestatten die einfach Formulierung von Intrarelationsabhängigkeiten die sich auf konkrete
Wertausprägungen einzelner Attribute beziehen.<br/>
Das Beispiel zeigt die Abhängigkeit, daß kein Angestellter mit mehr Einkommen ausgestattet sein darf als sein Vorgesetzter:</p>
         <p>
            <code>
               <pre>EMPLOYEE(FNAME, SSN ..., SALARY, SUPERSSN)
              a     b ...    c     NULL
Hypothese     e     f ...    g     b
-------------------------------------
Konklusion       c &lt; g</pre>
            </code>
         </p>
         <p>
            <b>Domain-Key-Normalform (DKNF)</b>:<br/>
Grundannahme der <keyword>Domain-Key-Normalform</keyword> (<keyword>DKNF</keyword>) ist es, daß
wenn für jedes Attribut einer Relation eine <keyword>Domäne</keyword> (d.h. die Menge der zugelassenen Wertbelegungen)
angegeben wird, alle Änderungsanomalien verschwinden.<br/>
Gleichzeitig fordert die DKNF die eineindeutige Identifikation jedes Attributs einer Relation durch einen Schlüssel.<br/>
In der Praxis kann jedoch die Angabe einer allgemein formulierten eindeutigen Domäne mit unter zu Schwierigkeiten führen,
weshalb die Prüfung auf Einhaltung dieser Normalform mit erheblichen technsichen Umsetzungsschwierigkeiten verbunden ist.</p>
      </region>
      <region numbered="yes">
         <topic name="Arbeiten">Arbeiten mit einer Datenbank</topic>
         <subtopic name="Codd">Codd'sche Regeln und Eigenschaften relationaler Systeme</subtopic>
         <p>Trotz des in dieser Hinsicht sehr eindeutigen grundlegenden Papiers von <name>E. F. Codd</name>
        über die Relationenstruktur (<a href="http://www.acm.org/classics/nov95/toc.html">
               <em>A Relational Model of Data for Large Shared Data
        Banks</em>
            </a>) existierte lange Zeit keine Übereinkunft darüber welche Eigenschaften ein relationales
        DBMS mindestens aufweisen muß um dieser Systemklasse zugerechnet werden zu können.<br/>
        Daher definiert <code>Codd</code> 1986 in einem zweiteiligen Artikeln für die Zeitschrift <em>Computer World</em>
        12 strenge Regeln die ein RDBMS aus seiner Sicht zwingend erfüllen muß um als solches eingestuft werden zu können.<br/>
        Diese hierin erhobenen Forderungen sind jedoch so streng, daß sie bis heute kein System vollständig erfüllt.<br/>
        Die Regeln sind nachfolgend mit ihren englischsprachigen Originalbezeichnungen wiedergegeben, da sich für sie
        bisher keine eindeutige und allgemeinverständliche deutsche Übersetzung etablieren konnte.</p>
         <p>Regel 1: <b>The Information Rule</b>:<br/>
        Alle Daten, die in einer Datenbank gespeichert werden sind auf dieselbe Art dargestellt,
        nämlich durch Werte in Tabellen.<br/>
            <em>Anmerkung</em>: In dieser Definition wurde bewußt der Begriff der <a href="#Tabelle">Tabelle</a>
        gegenüber dem der <a href="#Relation">Relation</a> bevorzugt.</p>
         <p>Regel 2: <b>Guaranteed Access Rule</b>:<br/>
        Jeder gespeicherte Wert muß über Tabellenname, Spaltenname und Wert des Primärschlüssels zugreifbar sein,
        wenn der zugreifende Anwender über hinreichende Zugriffsrechte verfügt.</p>
         <p>Regel 3: <b>Systematic Treatment of Null Values</b>:<br/>
        Nullwerte müssen datentypunabhängig zur Darstellung fehlender Werte unterstützt werden. <em>Systematisch</em>
        drückt hierbei aus, daß Nullwerte unabhängig von denjenigem Datentyp für den sie auftreten gleich behandelt werden.</p>
         <p>Regel 4: <b>Dynamic On-line Catalog Based on the Relational Model</b>:
        Forderung nach einem Online-Datenkatalog (<em>data dictionary</em>) in Form von Tabellen.<br/>
        Dieser Katalog beschreibt die in der Datenbank abgelegten Tabellen hinsichtlich ihrer Struktur und
        zugelassenen Inhaltsbelegungen.</p>
         <p>Regel 5: <b>Comprehensive Data Sublanguage Rule</b>:<br/>
        Für das DBMS muß mindestens eine Sprache existieren durch die sich die verschiedenen Inhaltstypen
        (Tabelleninhalte, Sichten, Integritätsstrukturen (Schlüsselbeziehungen, Wertebereichseinschränkungen, Aufzählungstypen) sowie
        Zugriffsrechte) definieren lassen.</p>
         <p>Regel 6: <b>View Updating Rule</b>:<br/>
        Sofern theoretisch möglich, müssen Inhalte von Basistabellen auch über deren Sichten änderbar sein.</p>
         <p>Regel 7: <b>High-level Insert, Update, and Delete</b>:<br/>
        Innerhalb einer Operation können beliebig viele Tupel bearbeitet werden, d.h. die Operationen werden
        grundsätzlich mengenorientiert ausgeführt. Hierfür ist eine so abstrahierte Sicht dieser Operationen
        notwendig, daß keinerlei Information über die syteminterne Darstellung der Tupel notwendig ist.</p>
         <p>Regel 8: <b>Physical Data Independence</b>:<br/>
        Änderungen an der internen Ebene dürfen keine Auswirkungen auf die auf den abgespeicherten Daten operierenden
        Anwendungsprogramme besitzen.<br/>
        Werden Daten demnach reorganisiert oder beispielsweise durch <a href="#Index">Indexe</a> zugriffsbeschleunigt, so darf eine solche
        Änderung die auf die Datenbank zugreifenden Anwendungsprogramme nicht beeinträchtigen.</p>
         <p>Regel 9: <b>Logical Data Independence</b>:<br/>
        Änderungen des <a href="#konzSchema">konzeptuellen Schemas</a> dürfen keine Auswirkung auf die
        Anwedungsprogramme besitzen, solange
        diese nicht direkt von der Änderung betroffen sind.</p>
         <p>Regel 10: <b>Integrity Independence</b>:<br/>
        In Verfeinerung der fünften Regel wird gefordert, daß alle Integritätsbedingungen ausschließlich durch
        die Sprache des DBMS definieren lassen können müssen. Definierte Integritätsbedingungen müssen in
        Tabellen abgespeichert werden und durch das DBMS zur Laufzeit abgeprüft werden.</p>
         <p>Im Mindesten werden folgende Forderungen durch verfügbare Systeme unterstützt:</p>
         <ul>
            <li>Kein Attribut welches Teil eines Primärschlüssels ist darf NULL sein.</li>
            <li>Ein Fremdschlüsselattribut muß als Wert des zugehörigen Primärschlüssels existieren.</li>
         </ul>
         <p>Regel 11: <b>Distribution Independence</b>:<br/>
        Die Anfragesprache muß so ausgelegt sein, daß Zugriffe auf lokal gehaltene Daten identisch denen auf
        verteilt gespeicherte Daten formuliert werden können.<br/>
        Hieraus läßt sich auch die Ausdehnung der Forderungen nach logischer und physischer Datenunabhängigkeit für
        verteilte Datenbanken ableiten.</p>
         <p>Regel 12: <b>Nonsubversion Rule</b>:<br/>
        Definiert ein DBMS neben der High-level Zugriffssprache auch eine Schnittstelle mit niedrigerem Abstraktionsniveau,
        dann darf durch diese keinesfalls eine Umgehung der definierten Integritätsregeln möglich sein.</p>
         <p>Zusätzlich faßt <name>Codd</name> in <b>Regel 0</b> nochmals die Anforderungen dahingehend zusammen, daß
        er postuliert, alle Operationen für Zugriff, Verwaltung und Wartung der Daten ausschließlich mittels
        relationaler Fähigkeiten abzuwickeln.</p>
         <p>Derzeit existiert kein am Markt verfügbares kommerzielles System welches alle zwölf Regeln vollständig umsetzt.
        Insbesondere sind die Regeln 6, 9, 10, 11 und 12 in der Praxis schwer umzusetzen.</p>
         <p>Darüber hinaus greifen die <name>Codd</name>schen Regeln nicht alle Gesichtspunkte des praktischen Datenbankeinsatzes auf.
		  So bleiben Fragestellungen des Betriebs (wie Sicherungs-, Wiederherstellungs- und
		  <a href="http://www.db2mag.com/story/showArticle.jhtml?articleID=18901175">Sicherheitsaspekte</a>) eines DBMS völlig ausgeklammert.</p>
         <subtopic name="SQL-DDL">Implementierung des logischen Modells mit SQL-DDL</subtopic>
         <p>Die SQL-DDL dient allgemein der Definition und Verwaltung von Tabellen- und Indexdefinitionen
        innerhalb einer relationalen Datenbank entlang ihres gesamten Lebenszyklus, d.h. von ihrer Erstellung über
        alle Wartungsstadien bis hin zur Entfernung.</p>
         <p>Nicht normiert durch den SQL-Standard sind die notwendigen Schritte zur Erzeugung einer Datenbank
        innerhalb eines Datenbankmanagementsystems. Überdies variieren die hierfür abzusetzenden Kommandos
        von Hersteller zu Hersteller und müssen der spezifischen Dokumentation entnommen werden.</p>
         <p>
            <em>Hinweis</em>: Zwar läßt SQL inzwischen die beliebige Schreibung der Schlüsselworte (groß, klein oder
        gemischt) zu, zur bessern Hervorhebung und Kompatibilität mit existierender Literatur werden sie jedoch
        in den nachfolgenden Syntaxübersichten und Beispielen durchgehend in Großschreibung wiedergegeben.</p>
         <p>Innerhalb der Syntaxbeschreibungen gelten folgende Konventionen:</p>
         <ul>
            <li>Schlüsselworte, die direkt wie abgedruckt eingegeben werden müssen sind großgeschrieben.</li>
            <li>Optionale Bestandteile, die weggelassen werden können sind in eckigen Klammern
            (<gerquot>[]</gerquot>) dargestellt.<br/>
            Die Klammern selbst sind nicht Bestandteil der Syntax und müssen nicht eingegeben werden.</li>
            <li>Dargestellte runde Klammern (<gerquot>()</gerquot>) sind Syntaxbestandteil und müssen unverändert eingegeben werden.</li>
            <li>Senkrechte Striche (<gerquot>|</gerquot>) trennen Alternativen von denen jeweils eine ausgewählt
            werden kann, nicht jedoch mehrere.</li>
            <li>Kommentare, die auf die Ausführung keinen Einfluß haben werden durch zwei Minuszeichen (<gerquot>--</gerquot>)
            eingeleitet und enden mit dem Zeilenende.</li>
            <li>Alle SQL-Befehle werden generell durch ein Semikolon abgeschlossen. Dieses ist aus Übersichtlichkeitsgründen
            in den Syntaxübersichten weggelassen.</li>
         </ul>
         <subsubtopic name="CREATE_TABLE">Erzeugen von Tabellen</subsubtopic>
         <p>Die SQL-Anweisung <code>CREATE TABLE</code> dient der Erzeugung neuer Tabellen innerhalb einer
        bestehenden Datenbank. Sie legt die Struktur und die zugelassenen Typausprägungen, sowie Einschränkungen
        hinsichtlich der erlaubten Werte fest.</p>
         <p>Die vereinfachte Syntax der <code>CREATE TABLE</code>-Anweisung lautet:</p>
         <code>
            <pre>CREATE [TEMPORARY] TABLE tbl_name [(create_definition,...)]
[table_options] [select_statement]

create_definition:
  col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
            [PRIMARY KEY] [reference_definition]
  or    PRIMARY KEY (index_col_name,...)
  or    KEY [index_name] (index_col_name,...)
  or    INDEX [index_name] (index_col_name,...)
  or    UNIQUE [INDEX] [index_name] (index_col_name,...)
  or    [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...)
            [reference_definition]

type:
        TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  or    SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  or    MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  or    INT[(length)] [UNSIGNED] [ZEROFILL]
  or    INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  or    BIGINT[(length)] [UNSIGNED] [ZEROFILL]
  or    REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  or    NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
  or    CHAR(length) [BINARY]
  or    VARCHAR(length) [BINARY]
  or    DATE
  or    TIME
  or    TIMESTAMP
  or    DATETIME
  or    TINYBLOB
  or    BLOB
  or    MEDIUMBLOB
  or    LONGBLOB
  or    TINYTEXT
  or    TEXT
  or    MEDIUMTEXT
  or    LONGTEXT
  or    ENUM(value1,value2,value3,...)
  or    SET(value1,value2,value3,...)

index_col_name:
        col_name [(length)]

reference_definition:
        REFERENCES tbl_name [(index_col_name,...)]
                   [MATCH FULL | MATCH PARTIAL]
                   [ON DELETE reference_option]
                   [ON UPDATE reference_option]

reference_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT</pre>
         </code>
         <example name="CT1" caption="Erzeugung einer Tabelle">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(
	Name VARCHAR(25)
);</pre>
            </code>
         </example>
         <p>Die Anweisung aus <exampleLink ref="CT1"/> stellt den einfachsten Fall ein Tabellenerzeugungsanweisung dar.<br/>
        Es wird die Tabelle <code>Person</code>, die mit <code>Name</code> nur über eine Spalte verfügt erzeugt.<br/>
        Eine <gerquot>kleinere</gerquot> Fassung ist nicht möglich, da spaltenlose Tabellen nicht erstellt werden können.</p>
         <p>Informationen über eine angelegte Tabelle können durch den Befehl <code>DESCRIBE</code> gefolgt
        vom Namen der abzufragenden Tabelle erlangt werden:</p>
         <example name="CT3" caption="Ermittlung von Tabelleninformation">
            <code>
               <pre>mysql&gt; DESCRIBE Person;
+-------+-------------+-------------------+------+-----+---------+-------+
| Field | Type        | Collation         | Null | Key | Default | Extra |
+-------+-------------+-------------------+------+-----+---------+-------+
| Name  | varchar(25) | latin1_swedish_ci | YES  |     | NULL    |       |
+-------+-------------+-------------------+------+-----+---------+-------+</pre>
            </code>
         </example>
         <p>Im Beispiel werden die zuvor festgelegten Daten wie Spaltenname (<code>Name</code>) und Datentyp (<code>VARCHAR(25)</code>)
        ermittelt, sowie die Belegung einiger Vorgabewerte (u.a. <code>NULL</code> und <code>Default</code>).</p>
         <p>Durch Angabe des Schlüsselwortes <code>TEMPORARY</code> können Tabellen erstellt werden, die während der
        Arbeit mit der Datenbank den herkömmlichen gleichgestellt behandelt werden, jedoch dem Ende der Datenbankverbindung
        automatisch inclusive aller darin abgelegten Daten aus der Datenbank entfernt werden.</p>
         <example name="CT2" caption="Erzeugung einer temporären Tabelle">
            <code>
               <pre>mysql&gt; CREATE TEMPORARY TABLE Person2(
	Name VARCHAR(25)
);

--Verbindungsende
--Aufbau einer neuen Verbindung

mysql&gt; DESCRIBE Person2;
ERROR 1146: Table 'SQLTest.Person2' doesn't exist</pre>
            </code>
         </example>
         <p>Wird die Datenbankverbindung getrennt und neu aufgebaut, so ist die zuvor temporär erstellte
        Tabelle <code>Peson2</code> nicht mehr vorhanden und zugreifbar. Das <code>DESCRIBE</code>-Kommando
        liefert daher einen Fehler.</p>
         <p>Wie bereits in <exampleLink ref="CT1"/> gezeigt muß jede Spalte einer Tabelle einen Datentyp besitzen.
        Dieser definiert die zugelassenen Wertbelegungen und wird durch das DBMS bei jeder schreibenden Operation
        (d.h. Einfügen, Ändern und Leeren) geprüft.<br/>
        Wird versucht ein ungültiger Wert zu setzen, so erfolgt eine Fehlermeldung und die Ablehnung des
        Eintragungs- oder Änderungswunsches. Im Falle eines zeichenkettenwertigen Datentyps (z.B. <code>VARCHAR</code>)
        erfolgt keine Fehlermeldung, sondern die Werte werden nur abgeschnitten eingefügt.</p>
         <example name="CT4" caption="Auswirkung von Datentypen I">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(
	Name VARCHAR(25)
);

mysql&gt; INSERT INTO Person values("Max Mustermann");
--ok

mysql&gt; INSERT INTO Person values("Franz Obermüller-Hinterhuber-Niedermayer");
--keine Fehlermeldung
--Wert wird jedoch nur abgeschnitten eingefügt:

mysql&gt; SELECT * FROM Person;
+---------------------------+
| Name                      |
+---------------------------+
| Max Mustermann            |
| Franz Obermüller-Hinterhu |
+---------------------------+</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="CT4"/> zeigt die Auswirkung eines gesetzten Datentypen <code>VARCHAR</code>. Werden, wie im
        Beispiel Werte eingefügt, die die zulässige maximale Zeichenkettenlänge überschreiten, so werden die überzähligen
        Zeichen ohne Fehlermeldung abgeschnitten.</p>
         <example name="CT5" caption="Auswirkung von Datentypen II">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(GebDat date);

mysql&gt; INSERT INTO Person values ('1970-12-12');
--ok

mysql&gt; insert into Person values ('1970-19-42');
--offensichtlich falsch
--Übernommener Wert: 0000-00-00

</pre>
            </code>
         </example>
         <p>Im <exampleLink ref="CT5"/> wird ein offensichtlich ungültiges Datum eingefügt. Die Datenbank übernimmt
        jedoch nicht diesen falschen Wert sondern setzt den Vorgabewert von <code>0000-00-00</code>.<br/>
        Dasselbe geschieht auch bei numerischen Datentypen (etwa: <code>INTEGER</code>) wenn versucht wird
        sie mit einer Zeichenkette zu belegen.</p>
         <p>MySQL unterstützt drei Datentypklassen:</p>
         <ul>
            <li>Numerischedatentypen zur Darstellung von Zahlen.</li>
            <li>Zeichenkettendatentypen zur Darstellung von Texten und Binärdaten.</li>
            <li>Datumsdatentypen zur Darstellung von Uhrzeit- und Datumsformaten.</li>
         </ul>
         <p>Die derzeit durch MySQL angebotenen Datentypen sind in der nachfolgenden Tabelle zusammengestellt:<br/>
            <table border="1" style="margin-left:150px">
               <tr>
                  <td>
                     <center>
                        <b>Typname</b>
                     </center>
                  </td>
                  <td>
                     <center>
                        <b>Beispiel</b>
                     </center>
                  </td>
                  <td>
                     <center>
                        <b>Bemerkung</b>
                     </center>
                  </td>
               </tr>
               <tr>
                  <td colspan="3">
                     <center>Numerische Datentypen</center>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>TINYINT [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Ganzzahl der Breite acht Bit.</td>
                  <td>
                     <small>(2<sup>7</sup>, ..., -1) 0, 1, ..., 2<sup>7</sup>-1), (2<sup>7</sup>, ... 2<sup>8</sup>-1)<br/>
                (-128, ..., -1,) 0, 1, ..., 127, (128, ..., 255)</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>BOOL</code>
                  </td>
                  <td>
                     <name>Boole</name>'scher Wahrheitswert.</td>
                  <td>Zugelassene Belegungen <code>0</code> und <code>1</code>.<br/>
                Synonym für <code>TINYINT(1)</code>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>SMALLINT [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Ganzzahl der Breite 16 Bit.</td>
                  <td>
                     <small>(2<sup>15</sup>, ..., -1) 0, 1, ..., 2<sup>15</sup>-1), (2<sup>15</sup>, ... 2<sup>16</sup>-1)<br/>
                (-32.768, ..., -1,) 0, 1, ..., 32.767, (32.768, ..., 65.535)</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>MEDIUMINT [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Ganzzahl der Breite 24 Bit.</td>
                  <td>
                     <small>(2<sup>23</sup>, ..., -1) 0, 1, ..., 2<sup>23</sup>-1), (2<sup>23</sup>, ... 2<sup>24</sup>-1)<br/>
                (-8.388.608, ..., -1) 0, 1, ..., 8.388.607, (8.388.608, ..., 16.777.215)</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>INT [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Ganzzahl der Breite 32 Bit.</td>
                  <td>
                     <small>(2<sup>31</sup>, ..., -1) 0, 1, ..., 2<sup>31</sup>-1), (2<sup>31</sup>, ... 2<sup>32</sup>-1)<br/>
                (-2.147.483.648, ..., -1) 0, 1, ..., 2.147.483.647, (2.147.483.648, ..., 4.294.967.295)</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>INTEGER [UNSIGNED]</code>
                  </td>
                  <td/>
                  <td>Synonym für <code>INT</code>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>BIGINT [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Ganzzahl der Breite 64 Bit.</td>
                  <td>
                     <small>(2<sup>63</sup>, ..., -1) 0, 1, ..., 2<sup>63</sup>-1), (2<sup>63</sup>, ... 2<sup>64</sup>-1)<br/>
                (-9.223.372.036.854.774.808, ..., -1) 0, 1, ..., 9.223.372.036.854.774.807, (9.223.372.036.854.774.808, ..., 18.446.744.073.709.551.615)</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>FLOAT [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Fließkommazahl der Breite 32 Bit, gemäß dem Standard <a href="http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html">IEEE-754</a>
                  </td>
                  <td>
                     <small>(-(2-2<sup>-23</sup>)<sup>127</sup>, ..., (2-2<sup>-23</sup>)<sup>127</sup>)<br/>
                -3,402...*10<sup>38</sup>, ..., -1,175...*10<sup>-38</sup> und 1,175...*10<sup>-38</sup> ... 3,402...*10<sup>38</sup>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>DOUBLE [UNSIGNED]</code>
                  </td>
                  <td>(Vorzeichenbehaftete) Fließkommazahl der Breite 64 Bit, gemäß dem Standard <a href="http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html">IEEE-754</a>
                  </td>
                  <td>
                     <small>(-(2-2<sup>-52</sup>)<sup>1023</sup>, ... (2-2<sup>-52</sup>)<sup>1023</sup>
                        <br/>
                -1,797...*10<sup>-308</sup>, ..., -2,225...*10<sup>308</sup> und 1,797...<sup>308</sup>, ..., 2,225...<sup>-308</sup>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>REAL [UNSIGNED]</code>
                  </td>
                  <td/>
                  <td>Synonym für <code>DOUBLE</code>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>DECIMAL [(Genauigkeit, [Nachkommastellen])]</code>
                  </td>
                  <td>Festkommazahl beliebiger Genauigkeit</td>
                  <td>
                     <small>DECIMAL(9,2) liefert eine Dezimalzahl mit neun Gesamtziffern, davon zwei Nachkommastellen.</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>DEC</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym für <code>DECIMAL</code>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>NUMERIC</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym für <code>DECIMAL</code>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td colspan="3">
                     <center>
                        <a name="Zeichenkettendatentypen">Zeichenkettendatentypen</a>
                     </center>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>CHAR [Länge]</code>
                  </td>
                  <td>Textfeld konstanter Länge bis zu 255 Zeichen, das immer die angegebene Anzahl Speicherstellen benötigt.</td>
                  <td>
                     <small>Dies ist ein Test0x20;0x20;0x20;</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>CHARACTER</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym zu CHAR</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>NCHAR</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym zu CHAR</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>NATIONAL CHARACTER</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym zu CHAR</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>CHARACTER VARYING</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym zu VARCHAR</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>NATIONAL VARCHAR</code>
                  </td>
                  <td/>
                  <td>
                     <small>Synonym zu VARCHAR</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>VARCHAR [Länge]</code>
                  </td>
                  <td>Textfeld variabler Länge. Überzähliche Leerzeichen am Ende einer Zeichenkette werden vor dem Abspeichern entfernt.</td>
                  <td>
                     <small>Dies ist ein Test</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>TINYTEXT</code>
                  </td>
                  <td>Textfeld variabler Länge, bis zu 2<sup>8</sup>-1 (=255) Zeichen.</td>
                  <td>
                     <small>... etwas mehr Text</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>TEXT</code>
                  </td>
                  <td>Textfeld variabler Länge, bis zu 2<sup>16</sup>-1 (=65.535) Zeichen.</td>
                  <td>
                     <small>Sehr viel ... Text hier ...</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>MEDIUMTEXT</code>
                  </td>
                  <td>Textfeld variabler Länge, bis zu 2<sup>24</sup>-1 (=16.777.215) Zeichen.</td>
                  <td>
                     <small>... etwas mehr Text hier ...</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>
                        <a name="longtext">LONGTEXT</a>
                     </code>
                  </td>
                  <td>Textfeld variabler Länge, bis zu 2<sup>32</sup>-1 (=2.294.967.295) Zeichen.</td>
                  <td>
                     <small>... noch mehr Text hier ...</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>TINYBLOB</code>
                  </td>
                  <td>Binäre Form von <code>TINYTEXT</code>.</td>
               </tr>
               <tr>
                  <td>
                     <code>MEDIUMBLOB</code>
                  </td>
                  <td>Binäre Form von <code>MEDIUMTEXT</code>
                  </td>
               </tr>
               <td>
                  <td>
                     <code>BLOB</code>
                  </td>
                  <td>Binäre Form von <code>TEXT</code>
                  </td>
               </td>
               <tr>
                  <td colspan="3">
                     <center>
                        <a name="Datumstypen">Datumstypen</a>
                     </center>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>DATE</code>
                  </td>
                  <td>Datum in ISO-8601-Schreibweise (JJJJ-MM-TT)</td>
                  <td>
                     <small>
                        <current value="year"/>-<current value="month"/>-<current value="day"/>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>TIME</code>
                  </td>
                  <td>Uhrzeit gemäß ISO 8601 (hh:mm:ss)</td>
                  <td>
                     <small>07:45:00</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>DATETIME</code>
                  </td>
                  <td>Datum und Uhrzeit gemäß ISO 8601 (JJJJ-MM-TT hh:mm:ss)</td>
                  <td>
                     <small>2005-05-27 07:45:00</small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>TIMESTAMP</code>
                  </td>
                  <td>Sekundengenauer Zeitpunkt zwischen 1970-01-01 und 2037-12-31</td>
                  <td>Anwenderdarstellung: <small>
                        <current value="year"/>-<current value="month"/>-<current value="day"/> <current value="hour"/>:<current value="minute"/>:<current value="second"/>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>YEAR</code>
                  </td>
                  <td>Vierstellige Jahreszahl</td>
                  <td>
                     <small>
                        <current value="year"/>
                     </small>
                  </td>
               </tr>
               <tr>
                  <td colspan="3">
                     <center>Komplexe Datentypen</center>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>ENUM</code>
                  </td>
                  <td>Aufzählungstyp mit bis zu 65.535 Elementen</td>
               </tr>
               <tr>
                  <td>
                     <code>SET</code>
                  </td>
                  <td>Menge mit bis zu 64 Elementen</td>
               </tr>
            </table>
         </p>
         <p>Jede Spalte einer Relation muß mit genau einem Datentyp der oben dargestellten Liste
versehen werden. Nachfolgend sind einige Definitionen und Besonderheiten zusammengestellt:</p>
         <example name="CT6" caption="Auswirkung von Datentypen III">
            <code>
               <pre>mysql&gt; CREATE TABLE test(wenigText CHAR(300));
--zulässige Grenze für CHAR überschritten ...

mysql&gt; DESCRIBE test;
+-----------+------+-------------------+------+-----+---------+-------+
| Field     | Type | Collation         | Null | Key | Default | Extra |
+-----------+------+-------------------+------+-----+---------+-------+
| wenigText | text | latin1_swedish_ci | YES  |     | NULL    |       |
+-----------+------+-------------------+------+-----+---------+-------+</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="CT6"/> zeigt die automatische Konversion des Datentypen <code>CHAR</code> in der Datenbank
in <code>TEXT</code> sobald bereits bei der Anlage die zulässige Größenbegrenzung für <code>CHAR</code> überschritten wird.
Werden zur Laufzeit Texte größer als die im <code>CREATE TABLE</code>-Ausdruck angegebene Maximalkapazität abgespeichert,
so werden alle überzähligen Zeichen abgeschnitten.</p>
         <example name="CT7" caption="Auswirkung von Datentypen IV">
            <code>
               <pre>mysql&gt; CREATE TABLE test(ts timestamp, x VARCHAR(10));
Query OK, 0 rows affected (0.35 sec)

mysql&gt; INSERT INTO test values(null, "abc");
Query OK, 1 row affected (0.06 sec)

mysql&gt; INSERT INTO test values(null, "def");
Query OK, 1 row affected (0.05 sec)

mysql&gt; INSERT INTO test values(null, "abc");
Query OK, 1 row affected (0.06 sec)

mysql&gt; SELECT * FROM test;
+---------------------+------+
| ts                  | x    |
+---------------------+------+
| 2003-05-26 23:25:51 | abc  |
| 2003-05-26 23:26:13 | def  |
| 2003-05-26 23:26:28 | abc  |
+---------------------+------+
3 rows in set (0.00 sec)

mysql&gt; UPDATE test SET x="xyz" WHERE x="abc";
Query OK, 2 rows affected (0.05 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql&gt; SELECT * FROM test;
+---------------------+------+
| ts                  | x    |
+---------------------+------+
| 2003-05-26 23:27:10 | xyz  |
| 2003-05-26 23:26:13 | def  |
| 2003-05-26 23:27:10 | xyz  |
+---------------------+------+
3 rows in set (0.00 sec)
</pre>
            </code>
         </example>
         <p>Das Beispiel zeigt die Nutzung des Typs <code>TIMESTAMP</code>. Spalten dieses Typs werden automatisch durch das DMBS
mit Werten versorgt werden. Daher ist die Belegung mit <code>NULL</code> bei Einfügung der drei Zeichenketten
wirkungslos.<br/>
Überdies wird der Wert jeder <code>TIMESTAMP</code>-typisierten Spalte (im Beispiel: <code>ts</code>) bei jedem
Schreibvorgang aktualisiert. Dies zeigt die nochmalige Ausgabe der Tabelleninhalte nach Aktualisierung der beiden
Tupel, die für das Attribut <code>x</code> den Wert <code>abc</code> aufweisen.</p>
         <example name="CT8" caption="Auswirkung von Datentypen V">
            <code>
               <pre>mysql&gt; create table Ampel(farbe enum('rot','gelb','gruen'));
Query OK, 0 rows affected (0.07 sec)

mysql&gt; INSERT INTO Ampel VALUES('rot');
Query OK, 1 row affected (0.05 sec)

mysql&gt; INSERT into Ampel VALUES('blau');
Query OK, 1 row affected (0.04 sec)

mysql&gt; SELECT * FROM Ampel;
+-------+
| farbe |
+-------+
| rot   |
|       |
+-------+

mysql&gt; INSERT INTO Ampel Values(2);
Query OK, 1 row affected (0.05 sec)

mysql&gt; SELECT * FROM Ampel;
+-------+
| farbe |
+-------+
| rot   |
|       |
| gelb  |
+-------+
3 rows in set (0.00 sec)
</pre>
            </code>
         </example>
         <p>Das <exampleLink ref="CT8"/> zeigt die Nutzung eines Aufzählungstypen.<br/>
Er erlaubt ausschließlich das Einfügen der vordefinierten Werte und legt für alle ungültigen Belegungen (im Beispiel:
<code>blau</code>) die leeren Zeichenkette ab.<br/>
Die Werte können dabei wie in der Aufzählung definiert oder durch ihre Indexposition (beginnend ab 1) gespeichert
werden.</p>
         <example name="CT9" caption="Auswirkung von Datentypen VI">
            <code>
               <pre>mysql&gt; CREATE TABLE test(x SET("a","b","c","d"));
Query OK, 0 rows affected (0.07 sec)

mysql&gt; INSERT INTO test VALUES("a");
Query OK, 1 row affected (0.07 sec)

mysql&gt; INSERT INTO test values("a,b");
Query OK, 1 row affected (0.04 sec)

mysql&gt; INSERT INTO test values("a,c");
Query OK, 1 row affected (0.07 sec)

mysql&gt; INSERT INTO test values("b,c");
Query OK, 1 row affected (0.05 sec)

mysql&gt; SELECT * FROM test;
+------+
| x    |
+------+
| a    |
| a,b  |
| a,c  |
| b,c  |
+------+
4 rows in set (0.00 sec)

mysql&gt; select * FROM test WHERE x &amp; 1;
+------+
| x    |
+------+
| a    |
| a,b  |
| a,c  |
+------+
3 rows in set (0.00 sec)
--liefert alle Tupel, die das zweite Mengenelement (="a") enthalten</pre>
            </code>
         </example>
         <p>Das Beispiel zeigt die Definition eines mengenwertigen Datentyps, d.h. einer Tabellenspalte, die mehr als
einen Wert aufnehmen kann sowie die Abfragemöglichkeiten dafür.<br/>
            <em>Hinweis</em>: Dieser Datentyp führt bereits in die <a href="#NF2Ref">NF<sup>2</sup>
            </a>-Datenstrukturen über und wird daher
nicht im Rahmen des Entwurfsprozesses im konzeptuellen Schema verwendet.</p>
         <p>Ergänzend zur Datentypangabe können für jede Spalte weitere einschränkende Angaben zur Spezifikation der erlaubten
Werte getroffen werden.</p>
         <p>
            <code>NOT NULL</code> legt hierbei fest, daß ein Tupel für eine Spalte zwingend einen von <code>NULL</code>
verschiedenen Wert besitzen muß.</p>
         <example name="CT10" caption="Definition einer Spalte als NOT NULL">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(Name VARCHAR(20), PersAuswNr INT NOT NULL);
Query OK, 0 rows affected (0.08 sec)

mysql&gt; INSERT INTO Person VALUES('Max Obermüller', '123456789');
Query OK, 1 row affected (0.11 sec)

mysql&gt; INSERT INTO Person VALUES('Xaver Hinterhuber', NULL);
ERROR 1048: Column 'PersAuswNr' cannot be null

mysql&gt; select * from Person;
+----------------+------------+
| Name           | PersAuswNr |
+----------------+------------+
| Max Obermüller |  123456789 |
+----------------+------------+
1 row in set (0.00 sec)</pre>
            </code>
         </example>
         <p>Das Beispiel zeigt eine Tabelle, bei der das Attribut <code>PersAuswNr</code> als
<code>NOT NULL</code> definiert wurde. Einfüge- oder Aktualisierungsversuche, die zu
Nullwerten dieses Attributs führen würden, werden durch das DMBS unterbunden.</p>
         <p>Alternativ dazu gestattet die Angabe von <code>NULL</code> die Existenz von Nullwerten
in der Tabelle. Diese Definition ist optional und wird bei fehlender Angabe automatisch
als Vorgabe gesetzt.<br/>
Das Beispiel zeigt die Definition der Spalte <code>Autofahrer</code> als <code>NULL</code>, die neben
den beiden vorgegebenen Werten auch keinen Wert enthalten darf.</p>
         <example name="CT11" caption="Definition einer Spalte als NULL">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(
    -&gt; Name VARCHAR(20),
    -&gt; PersAuswNr INT NOT NULL,
    -&gt; Autofahrer ENUM('J','N') NULL);
Query OK, 0 rows affected (0.07 sec)

mysql&gt; INSERT INTO Person VALUES('Max Obermüller', '123456789', NULL);
Query OK, 1 row affected (0.12 sec)

mysql&gt; INSERT INTO Person VALUES('Xaver Hinterhuber', '234567891', 'J');
Query OK, 1 row affected (0.04 sec)

mysql&gt; select * from Person;
+-------------------+------------+------------+
| Name              | PersAuswNr | Autofahrer |
+-------------------+------------+------------+
| Max Obermüller    |  123456789 | NULL       |
| Xaver Hinterhuber |  234567891 | J          |
+-------------------+------------+------------+
3 rows in set (0.01 sec)</pre>
            </code>
         </example>
         <p>Die Angabe der Klausel <code>DEFAULT VALUE</code> gestattet es einen Vorgabewert zu definieren,
der gesetzt wird wenn kein Wert für eine Spalte angegeben wird.<br/>
Dies ersetzt jedoch nicht automatisch die Möglichkeit des Auftretens von Nullwerten innerhalb
einer Spalte. Diese können auch weiterhin auftreten, sofern sie explizit eingefügt werden.<br/>
Die unterschiedlichen Wirkungsweisen zeigt <exampleLink ref="CT12"/>. Dort findet sich die Spalte
<code>Autofahrer</code> (vorgabegemäß, da keine andere Angabe erfolgte) als nullwertfähig mit
Vorgabewert <code>J</code>, sowie die Spalte <code>Hundebesitzer</code>, die mit Vorgabe <code>N</code>
und als nicht nullwertfähig deklariert wurde.</p>
         <example name="CT12" caption="Definition einer Spalte mit Vorgabewerten">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(
    -&gt; Name VARCHAR(20) NOT NULL,
    -&gt; Autofahrer ENUM('J','N') DEFAULT 'J',
    -&gt; Hundebesitzer ENUM('J','N') NOT NULL DEFAULT 'N'
    -&gt; );
Query OK, 0 rows affected (0.07 sec)

mysql&gt; INSERT INTO Person VALUES('Xaver Obermüller', 'J', 'J');
Query OK, 1 row affected (0.10 sec)

mysql&gt; INSERT INTO Person VALUES('Max Hinterhuber', NULL, 'N');
Query OK, 1 row affected (0.05 sec)

mysql&gt; INSERT INTO Person (Name) VALUES('Schorsch Huber');
Query OK, 1 row affected (0.05 sec)

mysql&gt; SELECT * FROM Person;
+------------------+------------+---------------+
| Name             | Autofahrer | Hundebesitzer |
+------------------+------------+---------------+
| Xaver Obermüller | J          | J             |
| Max Hinterhuber  | NULL       | N             |
| Schorsch Huber   | J          | N             |
+------------------+------------+---------------+
3 rows in set (0.00 sec)
</pre>
            </code>
         </example>
         <p>Ist die Auszeichnung einer einzelnen Spalte als <a href="#Primaerschluessel">Primärschlüssel</a>
gewünscht, so kann der Definition <code>(PRIMARY) KEY</code> nachgestellt werden um dies zu erreichen.<br/>
Die Definition eines Primärschlüssels impliziert den Zwang in jedem Tupel einen von <code>NULL</code> verschiedenen
eineindeutigen Wert dafür abspeichern zu müssen. Primärschlüsselspalten sind damit immer auch <code>NOT NULL</code>.<br/>
Zusätzlich kann für jede Tabelle höchstens ein Primärschlüsselattribut angegeben werden.<br/>
            <em>Hinweis</em>: Aus mehr als einer Spalte zusammengesetzte Primärschlüssel können nicht durch diese
Syntax gebildet werden.</p>
         <example name="CT13" caption="Definition eines Primärschlüssels">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(Name VARCHAR(20) PRIMARY KEY, Adresse VARCHAR(50));
Query OK, 0 rows affected (0.06 sec)

mysql&gt; INSERT INTO Person VALUES('Xaver Obermüller', 'Dorfstr. 12');
Query OK, 1 row affected (0.10 sec)

mysql&gt; INSERT INTO Person VALUES('Hans Hintermeier', 'Dorfstr. 13');
Query OK, 1 row affected (0.05 sec)

mysql&gt; INSERT INTO Person (Name) VALUES ('Schorsch Huber');
Query OK, 1 row affected (0.06 sec)

mysql&gt; select * from Person;
+------------------+--------------+
| Name             | Adresse      |
+------------------+--------------+
| Hans Hintermeier | Dorfstr. 13  |
| Schorsch Huber   | NULL         |
| Xaver Obermüller | Dorfstr. 12  |
+------------------+--------------+
4 rows in set (0.00 sec)

mysql&gt; INSERT INTO Person VALUES(NULL, 'Hauptstr. 11');
ERROR 1048: Column 'Name' cannot be null</pre>
            </code>
         </example>
         <p>Zur Erstellung eines zusammengesetzten Primärschlüssels kann nicht das nachgestellte Schlüsselwort <code>PRIMARY KEY</code>
verwendet werden, da seine wiederholte Angabe mehrdeutig wäre. Für diesen Fall muß eine gesondert <code>PRIMARY KEY</code>-Definition
in den <code>CREATE TABLE</code>-Ausdruck aufgenommen werden:</p>
         <example name="PK1" caption="Definition eines zusammengesetzten Primärschlüssels">
            <code>
               <pre>CREATE TABLE DEPT_LOCATIONS(
   DNUMBER INTEGER(1) NOT NULL,
   DLOCATION VARCHAR(20) NOT NULL,
   PRIMARY KEY (DNUMBER, DLOCATION));</pre>
            </code>
         </example>
         <p>Das Beispiel zeigt verschiedene Einfügeoperationen. Bemerkenswert ist die letzte, die das Primärschlüsselattribut
leer läßt. Die hierbei erfolgende Belegung mit der leeren Zeichenkette (nicht <code>NULL</code>!) ist ein gültiger
Eintrag im Sinne des angegebenen Datentypen <code>VARCHAR</code> und der Restriktion keine Belegung mit <code>NULL</code>
vorzunehmen.</p>
         <p>Soll ein nicht-sprechender Schlüssel (z.B. eine einfache Zählnummer) zur Identifikation genutzt werden,
so kann diese durch das DBMS automatisiert bereitgestellt werden.</p>
         <example name="CT14" caption="Definition eines automatisch befüllten Primärschlüssels">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(
    -&gt; LfdNr Int AUTO_INCREMENT PRIMARY KEY,
    -&gt; Name VARCHAR(20) NOT NULL);
Query OK, 0 rows affected (0.07 sec)

mysql&gt; INSERT INTO Person VALUES(1,'Max Obermüller');
Query OK, 1 row affected (0.09 sec)

mysql&gt; INSERT INTO Person VALUES(3,'Schorsch Hinterhuber');
Query OK, 1 row affected (0.05 sec)

mysql&gt; INSERT INTO Person VALUES(3,'Xaver Mayer');
ERROR 1062: Duplicate entry '3' for key 1

mysql&gt; SELECT * FROM Person;
+-------+----------------------+
| LfdNr | Name                 |
+-------+----------------------+
|     1 | Max Obermüller       |
|     3 | Schorsch Hinterhuber |
+-------+----------------------+
2 rows in set (0.00 sec)

mysql&gt; INSERT INTO Person (Name) VALUES('Xaver Mayer');
Query OK, 1 row affected (0.05 sec)

mysql&gt; INSERT INTO Person (Name) VALUES('Hans Huber');
Query OK, 1 row affected (0.04 sec)

mysql&gt; select * from Person;
+-------+----------------------+
| LfdNr | Name                 |
+-------+----------------------+
|     1 | Max Obermüller       |
|     2 | Xaver Mayer          |
|     3 | Schorsch Hinterhuber |
|     4 | Hans Huber           |
+-------+----------------------+
4 rows in set (0.00 sec)</pre>
            </code>
         </example>
         <p>Im <exampleLink ref="CT14"/> wird der Wert der Spalte <code>LfdNr</code>, sofern nicht durch den Anwender
explizit angegeben, automatisch ermittelt und eingefügt.</p>
         <p>Zur Zugriffsbeschleunigung dienende Indexstrukturen können bereits zum Tabellenerstellungszeitpunkt durch
den Anwender angegeben werden. Diese werden jedoch nicht der Spaltendefinition als nachgestellt, sondern bilden
einen eigenen Eintrag innerhalb der Tabellendefinition.<br/>
Ein Index kann gleichzeitig eine oder mehrere Spalten umfassen. Beispiel <exampleLink ref="CT15"/> zeigt dies:</p>
         <example name="CT15" caption="Definition von Indexen">
            <code>
               <pre>mysql&gt; CREATE TABLE Person(
    -&gt; Name VARCHAR(20) PRIMARY KEY,
    -&gt; GebDat DATE, Str_HsNr VARCHAR(20),
    -&gt; PLZ CHAR(5),
    -&gt; Ort VARCHAR(50),
    -&gt; INDEX GebDatIdx (GebDat),
    -&gt; INDEX AdresseIndex (Str_HsNr, PLZ, Ort));
Query OK, 0 rows affected (0.07 sec)</pre>
            </code>
         </example>
         <p>Als beschränkende Verschärfung, die sich auch positiv auf die Zugriffsgeschwindigkeit auswirkt, kann ein Index als
<code>UNIQUE INDEX</code> definiert werden. Er darf dann ausschließlich eindeutige Werte oder Wertkombinationen aufnehmen.</p>
         <subsubtopic name="CreateFK">Erzeugung von Fremdschlüsselbeziehungen</subsubtopic>
         <p>Die Erzeugung von Fremdschlüsselbeziehungen ist das integrale Element zur Wahrung der referentiellen
Integrität. Fremdschlüsselbeziehungen können bereits zum Erstellungszeitpunkt einer Tabelle angegeben werden
wie <exampleLink ref="FK1"/> zeigt oder nachträglich durch einen <code>ALTER TABLE</code>-Ausdruck hinzugefügt
werden wie durch <exampleLink ref="FK2"/> gezeigt.</p>
         <example name="FK1" caption="Erzeugung von Fremdschlüsselbeziehungen zum Tabellenersellungszeitpunkt">
            <code>
               <pre>CREATE TABLE DEPARTMENT(
   DNAME VARCHAR(20) NOT NULL,
   DNUMBER INTEGER(1) PRIMARY KEY,
   MGRSSN INTEGER(9),
   MGRSTARTDATE DATE);

CREATE TABLE EMPLOYEE(
   FNAME VARCHAR(10) NOT NULL,
   MINIT VARCHAR(1),
   LNAME VARCHAR(10) NOT NULL,
   SSN INTEGER(9) PRIMARY KEY,
   BDATE DATE,
   ADDRESS VARCHAR(30),
   SEX ENUM('M','F'),
   SALARY REAL(7,2) UNSIGNED,
   SUPERSSN INTEGER(9),
   DNO INTEGER(1) REFERENCES DEPARTMENT(DNUMBER),
   INDEX DNO_IDX (DNO));</pre>
            </code>
         </example>
         <p>Das Beispiel erzeugt neben der angestrebten Fremdschlüsselbeziehungen zwischen dem Attribut <code>DNO</code>
der Tabelle <code>EMPLOYEE</code> und dem Primärschlüssel <code>DNUMBER</code> in <code>DEPARTMENT</code> einen
Index auf den Fremdschlüssel innerhalb der Tabelle <code>EMPLOYEE</code>.<br/>
Dies ist für einige Datenbankmanagementsysteme (darunter MySQL) notwendig, um die Zugriffe auf den Fremdschlüssel
zu beschleunigen.</p>
         <p>Das nachfolgende Beispiel liefert dasselbe Ergebnis, jedoch unter nachträglicher (d.h. nach dem Erstellungszeitpunkt
der Tabellen) Fremdschlüsselerzeugung:</p>
         <example name="FK2" caption="Nachträgliche Erzeugung von Fremdschlüsselbeziehungen">
            <code>
               <pre>CREATE TABLE DEPARTMENT(
   DNAME VARCHAR(20) NOT NULL,
   DNUMBER INTEGER(1) PRIMARY KEY,
   MGRSSN INTEGER(9),
   MGRSTARTDATE DATE);

CREATE TABLE EMPLOYEE(
   FNAME VARCHAR(10) NOT NULL,
   MINIT VARCHAR(1),
   LNAME VARCHAR(10) NOT NULL,
   SSN INTEGER(9) PRIMARY KEY,
   BDATE DATE,
   ADDRESS VARCHAR(30),
   SEX ENUM('M','F'),
   SALARY REAL(7,2) UNSIGNED,
   SUPERSSN INTEGER(9),
   DNO INTEGER(1));

ALTER TABLE EMPLOYEE ADD INDEX DNO_IDX (DNO);
ALTER TABLE EMPLOYEE ADD CONSTRAINT DNO_FK FOREIGN KEY (DNO) REFERENCES DEPARTMENT(DNUMBER);</pre>
            </code>
         </example>
         <subtopic name="Anfragen">Der Anfrageteil von SQL</subtopic>
         <p>Anfragen zur Ermittlung von Datenbankinhalten stellen den eigentlichen Sprachkern von SQL und
zweifellos den in der Praxis bedeutsamsten Anteil der Sprache dar.<br/>
Die gesamte Mächtigkeit des Anfrageteils von SQL erschließt sich durch das Schlüsselwort <code>SELECT</code>.
Es gestattet Anfragen theoretisch unbegrenzter Komplexität in einer uniformen und leicht zu behaltenden
Syntax zu formulieren, deren Mächtigkeit von einfachsten Anfragen bis zu aufwendigen Auswertungen reicht.</p>
         <subsubtopic name="querySyntax">Anfragen von Datenbankinhalten</subsubtopic>
         <p>Die SQL-Anweisung <code>SELECT</code> dient der Abfrage von in einer Datenbank abgelegten Inhalten.
Sie benötigt Wissen über die angelegten Tabellen sowie deren Struktur hinsichtlich Spalten und deren
Typen.<br/>
Alle nachfolgenden Beispielanfragen beziehen sich, sofern nicht anders angegeben auf die
<a href="http://www.jeckle.de/vorlesung/datenbanken/MySQLStart.html#demodbstruct">Demodatenbank</a>.</p>
         <p>Die vereinfachte Syntax der <code>SELECT</code>-Anweisung lautet:</p>
         <pre>
            <code>SELECT [ALL|DISTINCT] select_item,...
FROM table_specification,...
[WHERE search_condition]
[GROUP BY grouping_column,...]
[HAVING search_condition]
[ORDER BY sort_specification,...]</code>
         </pre>
         <example name="Q1" caption="Einfache Anfrage">
            <code>
               <pre>SELECT FNAME
FROM EMPLOYEE;</pre>
            </code>
         </example>
         <p>Die Anfrage liefert die Inhalte der Spalte <code>FNAME</code>
aller in der Tabelle <code>EMPLOYEE</code> abgelegten Tupel. Die Werte
werden in keiner vorgegebenen Reihenfolge ausgegeben, d.h. eine etwaige
Sortierung ist zufallsbedingt und kann durch DBMS interne Reorganisationsprozesse zerstört werden.</p>
         <p>Durch diese Anfrage wird als Resultat eine nicht in der Datenbank abgelegte Tabelle erzeugt, welche
nur die im <code>SELECT</code>-Ausdruck angegebenen Spalten enthält. Die Ergebnistabelle stimmt zwar in Tupelanzahl
mit der Ursprungstabelle überein, blendet jedoch einzelne Attribute aus. Diese Vorgang wird als <em>Projektion</em>
bezeichnet.</p>
         <definition id="Projektion" term="Projektion">
            Die Projektion blendet einzelne Spalten aus.
</definition>
         <example name="Q2" caption="Anfrage aller Spalten einer Tabelle">
            <code>
               <pre>SELECT FNAME, MINIT, LNAME, SSN, BDATE, ADDRESS, SEX, SALARY, SUPERSSN, DNO
FROM EMPLOYEE;</pre>
            </code>
         </example>
         <p>Die Abfrage aus <exampleLink ref="Q2"/> liefert die Wertinhalte aller
Spalten (sie sind explizit nach dem Schlüsselwort <code>SELECT</code> angegeben)
der Relation <code>EMPLOYEE</code>.<br/>
Als Besonderheit wird für das Attribut <code>SUPERSSN</code> des
Mitarbeiters James E. Borg der Wert <code>NULL</code> ausgegeben. Diese
Zeichenkette gibt an, daß für dieses Attribut der Relation kein Wert abgespeichert wurde.</p>
         <p>Die schreibaufwendige und damit fehlerträchtige Explizierung aller
Spalten einer Relation ist kaum praktikabel und überdies äußerst änderungssensitiv
im Falle der Aufnahme neuer Spalten oder der Lösung Existierender.<br/>
Aus diesem Grunde kann statt des Spaltennamens ein Stern <gerquot>
               <code>*</code>
            </gerquot>
als Jokerzeichen stellvertretend für alle Spalten einer Relation angegeben werden.<br/>
            <exampleLink ref="Q3"/> zeigt dies als Umschreibung der Anfrage aus <exampleLink ref="Q2"/>:</p>
         <example name="Q3" caption="Anfrage aller Spalten einer Tabelle mit Jokerzeichen">
            <code>
               <pre>SELECT *
FROM EMPLOYEE;</pre>
            </code>
         </example>
         <p>Enthält die Ausgabe nicht den Primärschlüssel einer Tabelle, so kann es vorkommen, das mehrfach
dieselben Werte ausgegeben werden. Dies kann durch Angabe des Schlüsselwortes <code>DISTINCT</code> in
der <code>SELECT</code>-Klausel vermieden werden.<br/>
            <code>DISTINCT</code> überschreibt das vorgegebene Verhalten (<code>ALL</code>) alle Einträge auszugeben.</p>
         <example name="Q15" caption="Duplikatfreie Ausgabe aller verschiedenen Werte">
            <code>
               <pre>SELECT DISTINCT SALARY
FROM EMPLOYEE;</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="Q15"/> liefert alle verschiedenen Werteinträge der Spalte <code>SALARY</code>
duplikatfrei.</p>
         <p>Durch Angabe mehrerer Einträge in der <code>FROM</code>-Klausel
können Inhalte aus verschiedenen Tabellen innerhalb einer Anfrage extrahiert werden:</p>
         <example name="Q4" caption="Anfrage auf zwei Tabellen">
            <code>
               <pre>SELECT DNAME, PNUMBER
FROM DEPARTMENT, PROJECT;</pre>
            </code>
         </example>
         <p>Die Anfrage bildet das <a href="http://de.wikipedia.org/wiki/Kartesisches_Produkt">kartesische Produkt</a>
der beiden angefragten Tabellen.</p>
         <subsubtopic name="QAlias">Aliasbildung</subsubtopic>
         <p>Bei Anfragen über mehrere Tabellen kann es zu Problemen hinsichtlich
der Eindeutigkeit der Spaltenbezeichner kommen. So würde die Anfrage aus
<exampleLink ref="Q5"/> nicht die für <code>ESSN</code> abgelegten Werte liefern,
sondern den Fehler <code>ERROR 1052: Column: 'ESSN' in field list is ambiguous</code>, da
in jeder der beiden in der Anfrage berücksichtigten Tabellen eine Spalte mit <code>ESSN</code>
benannt ist.</p>
         <example name="Q5" caption="Fehlerhafte Anfrage auf zwei Tabellen">
            <code>
               <pre>SELECT ESSN, ESSN
FROM WORKS_ON, DEPENDENT;</pre>
            </code>
         </example>
         <p>Als Lösung bietet SQL die Möglichkeit den Spaltennamen zusätzlich
durch Voranstellung des Namens der die Spalte beherbergenden Tabelle zu qualifizieren
um die erforderliche Eindeutigkeit herzustellen:</p>
         <example name="Q6" caption="Lösung des Mehrdeutigkeitsproblems bei Anfrage auf zwei Tabellen">
            <code>
               <pre>SELECT WORKS_ON.ESSN, DEPENDENT.ESSN
FROM WORKS_ON, DEPENDENT;</pre>
            </code>
         </example>
         <p>Unter Nutzung der Möglichkeit Alternativnamen für Tabellen, sog. <em>Aliasnamen</em>,
anzugeben ergibt sich eine in der Schreibung kompaktere Umsetzung:</p>
         <example name="Q7" caption="Lösung des Mehrdeutigkeitsproblems bei Anfrage auf zwei Tabellen">
            <code>
               <pre>SELECT w.ESSN, d.ESSN
FROM WORKS_ON AS w, DEPENDENT AS d;</pre>
            </code>
         </example>
         <p>Gleichzeitig kann die Aliasbildung eingesetzt werden, um die Benennung der
Spalten bei der Ausgabe zu modifizieren. Auf diesem Wege können wenig sprechende Namen
oder Doppelbenennungen umgangen werden.</p>
         <example name="Q8" caption="Umbenennung von Ausgabespalten">
            <code>
               <pre>SELECT w.ESSN AS "Mitarbeiter Sozialversicherungsnummer",
d.ESSN AS "Sozialversicherungsnummer des Verwandten"
FROM WORKS_ON AS w, DEPENDENT AS d;</pre>
            </code>
         </example>
         <subsubtopic name="CalcRes">Berechnete Ausgaben</subsubtopic>
         <p>Durch die Angabe einfacher arithmetischer Formeln in der <code>SELECT</code>-Klausel
können vor ihrer Ausgabe Berechnungen auf den Werten aus der Datenbank angestellt werden.</p>
         <example name="Q14" caption="Berechnungen I">
            <code>
               <pre>SELECT FNAME, SALARY*12 as Jahreseinkommen
FROM EMPLOYEE;</pre>
            </code>
         </example>
         <subsubtopic name="QWhere">Beschränkung der Ergebnismenge</subsubtopic>
         <p>Die bisher betrachteten Anfrageformen lieferten immer die gesamten Inhalte
der betrachteten Tabellen. Durch Angabe einer einschränkenden Bedingung innerhalb der
<code>WHERE</code>-Klausel einer <code>SELECT</code>-Anweisung können die Tabelleninhalte
hinsichtlich einer Bedingung gefiltert werden.</p>
         <p>
            <exampleLink ref="Q9"/> liefert nur die abgespeicherten Werte für Geburtsdatum
(<code>BDATE</code>) und Adresse (<code>ADDRESS</code>) derjenigen Mitarbeiter, deren
Vornamen (<code>FNAME</code>) <em>John</em> ist.</p>
         <example name="Q9" caption="Einschränkung der Anfrage">
            <code>
               <pre>SELECT BDATE, ADDRESS
FROM EMPLOYEE
WHERE FNAME="John";</pre>
            </code>
         </example>
         <p>Durch die Filterung der Ergebnistupel werden alle diejenigen Datenbankeinträge, welche die getroffene
Bedingung nicht erfüllen ausgeblendet. Das Ergebnis kann (sofern <code>SELECT * ...</code> gewählt wurde) zwar
in der Anzahl Spalten mit der Ursprungsrelation übereinstimmen, wird dies jedoch typischerweise (d.h. außer
im Falle, daß alle Tupel der Relation die formulierte Bedingung erfüllen) nicht tun.<br/>
Dieser Vorgang wird als <em>Selektion</em> bezeichnet.</p>
         <definition id="Selektion" term="Selektion">
            Die Selektion blendet einzelne Werteinträge aus..
        </definition>
         <p>Als relationale Operatoren für Vergleichstests zwischen zwei (möglicherweise
einelementigen) Mengen stehen zur Verfügung:</p>
         <SimpleTable>
            <tr>
               <td>
                  <b>Operator</b>
               </td>
               <td>
                  <b>Funktion</b>
               </td>
               <td>
                  <b>Bemerkung</b>
               </td>
            </tr>
            <tr>
               <td>
                  <code>=</code>
               </td>
               <td>Gleichheitstest</td>
            </tr>
            <tr>
               <td>
                  <code>&lt;&gt;</code>
               </td>
               <td>Test auf Ungleichheit</td>
               <td>Teilweise (auch in MySQL!) ist der Standardoperator durch <code>!=</code> ersetzt</td>
            </tr>
            <tr>
               <td>
                  <code>&lt;</code>
               </td>
               <td>Test auf kleiner</td>
               <td>Liefert bei Zeichenkettendatentypen alle lexikalisch <gerquot>kleineren</gerquot>,
    d.h. diejenigen die in der alphabetischen Sortierung früher auftreten.<br/>
    Ebenso liefert der Operator bei der Anwendung auf Datumsdatentypen die kalendarisch früheren.</td>
            </tr>
            <tr>
               <td>
                  <code>&lt;=</code>
               </td>
               <td>Kleiner oder gleich</td>
            </tr>
            <tr>
               <td>
                  <code>&gt;</code>
               </td>
               <td>Größer</td>
            </tr>
            <tr>
               <td>
                  <code>&gt;=</code>
               </td>
               <td>Größer oder gleich</td>
            </tr>
            <tr>
               <td>
                  <code>IS NULL</code>
               </td>
               <td>Testet ob eine Spalte <code>NULL</code> enthält</td>
            </tr>
            <tr>
               <td>
                  <code>IS NOT NULL</code>
               </td>
               <td>Testet ob eine Spalte nicht <code>NULL</code> enthält</td>
            </tr>
            <tr>
               <td>
                  <code>BETWEEN</code>
               </td>
               <td>Testet ob ein Wert in vorgegebenen Grenzen liegt</td>
            </tr>
            <tr>
               <td>
                  <code>IN</code>
               </td>
               <td>Testet ob ein Wert innerhalb einer vorgegebenen Menge liegt</td>
            </tr>
         </SimpleTable>
         <p>Neben den einfachen Vergleichsoperationen können durch den <code>LIKE</code>-Operator
unscharfe musterbasierte Suchen ausgedrückt werden.<br/>
Die Musterausdrücke werden dabei aus den tatsächlich in der Ergebnisemenge erwarteten Zeichen ergänzt
um Metazeichen mit besonderer Bedeutung zusammengesetzt. Hierbei stehen <gerquot>
               <code>%</code>
            </gerquot>
zur Stellvertretung einer (möglicherweise leeren) Menge beliebiger Zeichen und <gerquot>
               <code>_</code>
            </gerquot>
zur Stellvertretung genau eines Zeichens zur Verfügung.</p>
         <example name="Q10" caption="Musterbasierte Anfrage I">
            <code>
               <pre>SELECT BDATE, ADDRESS
FROM EMPLOYEE
WHERE FNAME LIKE "J%";</pre>
            </code>
         </example>
         <p>Die Anfrage aus <exampleLink ref="Q10"/> liefert die Werte der
Spalten <code>BDATE</code> und <code>ADDRESS</code> aller Mitarbeiter
deren Name (<code>FNAME</code>) mit einem <gerquot>J</gerquot> beginnt.<br/>
Die Anfrage aus <exampleLink ref="Q11"/> beschränkt die Suche zusätzlich auf
diejenigen Namen, deren vorletztes Zeichen ein <gerquot>e</gerquot> ist, d.h. diejenigen Einträge
für die nach dem <gerquot>e</gerquot> nur noch genau ein beliebiges Zeichen auftritt.</p>
         <example name="Q11" caption="Musterbasierte Anfrage II">
            <code>
               <pre>SELECT BDATE, ADDRESS
FROM EMPLOYEE
WHERE FNAME LIKE "J%e_";</pre>
            </code>
         </example>
         <p>Die Variante aus <exampleLink ref="Q12"/> extrahiert alle Spalteninhalte der Mitarbeitertabelle
deren Name aus genau fünf Zeichen besteht.</p>
         <example name="Q12" caption="Musterbasierte Anfrage III">
            <code>
               <pre>SELECT *
FROM EMPLOYEE
WHERE FNAME LIKE "____";</pre>
            </code>
         </example>
         <subsubtopic name="QWHEREKomb">Kombination von Einzelbedingungen</subsubtopic>
         <p>Zur Selektion nach mehreren Bedingungen können diese mit den logischen Operationen <code>AND</code>, <code>OR</code>
und <code>NOT</code> kombiniert werden.</p>
         <p>Die Anfrage aus <exampleLink ref="Q13"/> liefert die Namen aller Mitarbeiter, die in <gerquot>Houston</gerquot>
wohnen und weniger als 50000 verdienen.</p>
         <example name="Q13" caption="Kombination von Bedingungen">
            <code>
               <pre>SELECT FNAME
FROM EMPLOYEE
WHERE ADDRESS LIKE "%Houston%" AND SALARY &lt; 50000;</pre>
            </code>
         </example>
         <p>Mittels der Verknüpfungsoperatoren können auch einige der zuvor gezeigten Vergleichsoperatoren ausgedrückt werden.<br/>
            <SimpleTable>
               <tr>
                  <td>
                     <b>Vergleichsoperator</b>
                  </td>
                  <td>
                     <b>Alternative Schreibweise mit Bedingungsverknüpfung</b>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>a BETWEEN b and c</code>
                  </td>
                  <td>
                     <code>(a &gt;= b) AND (a &lt;= c)</code>
                  </td>
               </tr>
               <tr>
                  <td>
                     <code>x IN (a, b, c)</code>
                  </td>
                  <td>
                     <code>(x = a) OR (x = b) OR (x = c)</code>
                  </td>
               </tr>
            </SimpleTable>
         </p>
         <p>Für die Kombinationsoperatoren gilt, aufgrund der Möglichkeit des Auftretens von
<code>NULL</code>-Werten, die dreiwertige Logik:</p>
         <SimpleTable>
            <tr>
               <td>
                  <b>AND</b>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>NULL</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
         </SimpleTable>
         <p>
            <br/>
         </p>
         <SimpleTable>
            <tr>
               <td>
                  <b>OR</b>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
            <tr>
               <td>
                  <code>NULL</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
         </SimpleTable>
         <p>
            <br/>
         </p>
         <SimpleTable>
            <tr>
               <td>
                  <b>NOT</b>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
            <tr>
               <td/>
               <td>
                  <code>FALSE</code>
               </td>
               <td>
                  <code>TRUE</code>
               </td>
               <td>
                  <code>NULL</code>
               </td>
            </tr>
         </SimpleTable>
         <subsubtopic name="union">Kombination von Anfrageergebnissen</subsubtopic>
         <p>In manchen Fällen ist es gewünscht das Ergebnis eigenständiger Anfragen zu einem Ergebnis zu
kombinieren. Hierzu kann das <code>UNION</code>-Schlüsselwort zur Verbindung der Einzelanfragen.</p>
         <example name="Q20" caption="Kombination mittels UNION">
            <code>
               <pre>CREATE TABLE Artikel(
	ArtNo 		VARCHAR(4) PRIMARY KEY,
	Bezeichnung VARCHAR(10) NOT NULL,
	Preis			DECIMAL(5,2) NOT NULL);
CREATE TABLE Sonderpreise(
	ArtikelNo	VARCHAR(4) PRIMARY KEY,
	Bezeichnung	VARCHAR(10) NOT NULL,
	Sonderverkaufsgrund VARCHAR(20));

INSERT INTO Artikel VALUES("2222", "Blitz Superrein", 19.99);
INSERT INTO Artikel VALUES("1111", "Wusch Superfein", 99.95);

INSERT INTO Sonderpreise VALUES("4444", "Kratzweich", "Wasserschaden");
INSERT INTO Sonderpreise VALUES("3333", "Glanz Extraweiss", NULL);

SELECT ArtNo
FROM Artikel
UNION
SELECT ArtikelNo
FROM Sonderpreise;</pre>
            </code>
         </example>
         <p>Die Anfrage aus <exampleLink ref="Q20"/> erstellt zunächst zwei Tabellen und fügt einige Daten ein.<br/>
Anschließend werden die Artikelnummern (Spalte <code>ArtNo</code> bzw. <code>ArtikelNo</code>) beider
Tabellen angefragt und das Ergebnis mittels <code>UNION</code> zu einer Resultattabelle kombiniert.</p>
         <p>Voraussetzung der Kombinierbarkeit ist die Typgleichheit der selektierten und zu vereinigenden Attribute (im Beispiel
beide vom Typ <code>VARCHAR(4)</code>).</p>
         <p>Implizit führt die Verwendung von <code>UNION</code> sowohl die Sortierung der Ergebnissmenge als auch die
Duplikatentfernung daraus herbei.</p>
         <subsubtopic name="Join">Verbünde</subsubtopic>
         <p>Häufig besteht der Wunsch Werte aus verschiedenen Tabellen nicht nur gemeinsam abzufragen und anzuzeigen, sondern
auch inhaltlich in Beziehung zu setzen.</p>
         <p>Die Anfrage aus <exampleLink ref="Q16"/> versucht durch Abfrage der Tabellen <code>EMPLOYEE</code> und
<code>DEPARTMENT</code> die Namen der Mitarbeiter und die (in der anderen Tabelle abgelegte)
Bezeichnung Abteilung zu ermitteln die sie beschäftigen.<br/>
Aufgrund der Bildung des kartesischen Produkts werden jedoch alle theoretisch möglichen Kombinationen geliefert und
nicht die Untermenge der tatsächlich existierenden Paarungen.</p>
         <example name="Q16" caption="Fehlerhafte Verbundbildung">
            <code>
               <pre>SELECT FNAME, DNAME
FROM DEPARTMENT, EMPLOYEE;</pre>
            </code>
         </example>
         <p>Durch (geschickte) Nutzung der <code>WHERE</code>-Bedingung, die Werte aus beiden Tabellen miteinander
in Beziehung setzt, gelingt jedoch die gewünschte Ermittlung:</p>
         <example name="Q17" caption="Innerer Verbund">
            <code>
               <pre>SELECT FNAME, DNAME
FROM DEPARTMENT AS d, EMPLOYEE as e
WHERE d.DNUMBER = e.DNO;</pre>
            </code>
         </example>
         <p>Das <exampleLink ref="Q17"/> liefert lediglich diejenigen Tupel, für die das in <code>EMPLOYEE</code>
abgespeicherte <code>DNO</code>-Attribut einen Wert enthält, der auch in der Spalte <code>DNUMBER</code>
der Tabelle <code>DEPARTMENT</code> auftritt.</p>
         <definition id="innerJoin" term="Innerer Verbund">
            Ein Innerer Verbund enthält die selektierten Daten aller beteiligten Tabellen, welche
            die formulierte Einschränkungsbedingung erfüllen.
</definition>
         <p>Der SQL-Standard gibt für diese besondere Anfrageform eine eigene Syntax vor:</p>
         <example name="Q18" caption="Innerer Verbund in Standardnotation">
            <code>
               <pre>SELECT FNAME, DNAME
FROM DEPARTMENT AS d INNER JOIN EMPLOYEE AS e
ON d.DNUMBER = e.DNO;</pre>
            </code>
         </example>
         <p>Die Bildung von Verbünden ist nicht auf die Angabe verschiedener Tabellen beschränkt, sondern kann
auch durch mehrfache Bezugnahme auf dieselbe Tabelle geschehen:</p>
         <example name="Q19" caption="Innerer Verbund unter mehrfacher Nutzung derselben Tabelle">
            <code>
               <pre>SELECT e1.FNAME as Chef, e2.FNAME as Mitarbeiter
FROM EMPLOYEE AS e1, EMPLOYEE AS e2
WHERE e1.SSN = e2.SUPERSSN;</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="Q21"/> zeigt ein Beispiel der Bildung eines inneren Verbundes unter Zugriff auf drei Tabellen.<br/>
Die Anfrage liefert die Familiennamen (Tabelle <code>EMPLOYEE</code>) sowie die Abteilungen denen der Mitarbeiter
zugeordnet ist (aus Tabelle <code>DEPARTMENT</code>) sowie die durch den Mitarbeiter bearbeiteten Projekte (Tabelle
<code>PROJECT</code>).<br/>
Die Tabelle <code>PROJECT</code> kann jedoch nicht direkt in den Verbund einbezogen werden, da sie über keine geeigneten
Attribute (d.h. Attribute die mit derselben Semantik in einer der beiden anderen Tabellen auftreten) verfügt. Daher
wird zusätzlich die Tabelle <code>WORKS_ON</code> in die Anfrage miteinbezogen, weil sie mit dem Attribut <code>ESSN</code>
ein Attribut bietet, welches die in <code>EMPLOYEE</code> enthaltene Attribut <code>SSN</code> als Fremdschlüssel beinhaltet.
Ausgehend hiervon kann eine Bedingung unter Einbezug von <code>PROJECT</code> formuliert werden.</p>
         <example name="Q21" caption="Innerer Verbund dreier Tabellen">
            <code>
               <pre>SELECT FNAME, DNAME, PNAME
FROM EMPLOYEE AS e, DEPARTMENT AS d, PROJECT AS p, WORKS_ON AS w
WHERE d.DNUMBER = e.DNO AND e.SSN = w.ESSN AND w.PNO = p.PNUMBER;</pre>
            </code>
         </example>
         <p>Für Verbünde ist die Bildung durch ausschließliche Nutzung des Gleichheitsoperators innerhalb der <code>WHERE</code>-Klausel
keineswegs zwingend, wenngleich diese sog. <em>
               <keyword>Equi Joins</keyword>
            </em> eine häufige Anwendungsform darstellen.<br/>
            <exampleLink ref="NEJ.sql"/> zeigt einen durch Nutzung des kleiner-Operators gebildeten Verbund, der alle Abteilungen
enthält, in denen ein Mitarbeiter (noch) nicht arbeitet und deren Abteilungsnummer größer ist als die Nummer
der Abteilung welcher der Mitarbeiter gegenwärtig zugeordnet ist. (Mögliche semantische Deutung: Liste möglicher
Beförderungen, sofern größere Abteilungsnummern einen Aufstieg codieren.</p>
         <example name="NEJ" caption="Non-Equi-Join">
            <code>
               <pre>SELECT FNAME, DNAME
FROM EMPLOYEE JOIN DEPARTMENT
ON DEPARTMENT.DNUMBER &lt; EMPLOYEE.DNO;</pre>
            </code>
         </example>
         <subsubtopic name="outerJoin">Äußere Verbunde</subsubtopic>
         <p>Neben der Möglichkeit durch innere Verbünde Tupel die über Attribute mit übereinstimmenden Wertbelegungen
zu selektieren besteht durch <em>äußere Verbünde</em> die Möglichkeit neben den Tupeln mit übereinstimmenden Werten
alle Tupel einer am Verbund beteiligten Tabelle vollständig zu selektieren.</p>
         <definition id="outerJoin" term="Äußerer Verbund">
            Ein Äußerer Verbund enthält die selektierten Daten aller beteiligten Tabellen, welche
            die formulierte Einschränkungsbedingung erfüllen, sowie alle Daten der <gerquot>äußeren</gerquot>
            Tabelle.<br/>
            Die nicht mit Werten belegbaren Felder werden durch <code>NULL</code> aufgefüllt.
</definition>
         <p>Konzeptionell wird zwischen <em>linken</em> und <em>rechten Äußeren Verbünden</em> unterschieden. Die
<gerquot>Seite</gerquot> des Verbundes gibt diejenige beteiligte Tabelle an, die im Rahmen der Verbundbildung
vollständig ausgegeben wird.<br/>
            <exampleLink ref="LOJ"/> zeigt ein Beispiel eines linken Äußeren Verbundes, <exampleLink ref="ROJ"/> illustriert einen
rechten äußeren Verbund.</p>
         <example name="LOJ" caption="Linker Äußerer Verbund">
            <code>
               <pre>INSERT INTO EMPLOYEE VALUES("John", "X", "Doe", "999999999", "1965-03-04", "42 XYZ Street", "M", 50000, NULL, NULL);

SELECT FNAME, DNAME
FROM EMPLOYEE LEFT OUTER JOIN DEPARTMENT
ON DEPARTMENT.DNUMBER = EMPLOYEE.DNO;</pre>
            </code>
         </example>
         <p>Das Beispiel fügt zunächst einen Tupel zur Tabelle <code>EMPLOYEE</code> hinzu, der keiner Abteilung zugeordnet ist.
In einem Inneren Verbund erscheint dieser Tupel daher nicht. Der linke Äußere Verbund des Beispiels hingegen umfaßt
alle Tupel aus <em>EMPLOYEE</em> sowie die Werte der hinsichtlich der Bedingung <code>DEPARTMENT.DNUMBER = EMPLOYEE.DNO</code>
ermittelten Übereinstimmungen in <code>DEPARTMENT</code>.<br/>
Für die nicht ermittelbaren Übereinstimmungen werden <code>NULL</code>-Werte erzeugt.</p>
         <example name="ROJ" caption="Rechter Äußerer Verbund">
            <code>
               <pre>INSERT INTO DEPARTMENT VALUES("New Dept.", 0, 888665555, NULL);

SELECT FNAME, DNAME
FROM EMPLOYEE RIGHT OUTER JOIN DEPARTMENT
ON DEPARTMENT.DNUMBER = EMPLOYEE.DNO;</pre>
            </code>
         </example>
         <p>Auch das <exampleLink ref="ROJ"/> zum rechten Äußeren Verbund fügt zunächst einen Datensatz ein; diesmal in die Tabelle
<code>DEPARTMENT</code>, der zu keinem Tupel in <code>EMPLOYEE</code> in Beziehung steht. Analog dem linken
Äußeren Verbund liefert der rechte Äußere Verbund alle Tupel der rechtsstehenden Tabelle (<code>DEPARTMENT</code>) sowie
die mit <em>EMPLOYEE</em> übereinstimmenden.</p>
         <subsubtopic name="crossJoin">Kreuzverbund</subsubtopic>
         <p>Der Kreuzverbund liefert alle gemäß den Gesetzen des kartesischen Produkts bildbaren Kombinationen
aus Tupeln der beitragenden Relationen:</p>
         <example name="CJ" caption="Kreuzverbund">
            <code>
               <pre>SELECT DNAME, PNUMBER
FROM DEPARTMENT CROSS JOIN PROJECT;</pre>
            </code>
         </example>
         <p>Das Beispiel entspricht damit im Ergebnis der Anfrage aus <exampleLink ref="Q4"/>.</p>
         <p>Wird beim Kreuzverbund eine Bedingung angegeben, so entspricht er dem Inneren Verbund.
Das Ergebnis der Anfrage aus <exampleLink ref="CJ2"/> ist daher identisch zum inneren Verbund
aus <exampleLink ref="Q17"/>.</p>
         <example name="CJ2" caption="Kreuzverbund mit Bedingung">
            <code>
               <pre>SELECT FNAME, DNAME
FROM DEPARTMENT CROSS JOIN EMPLOYEE
WHERE DEPARTMENT.DNUMBER = EMPLOYEE.DNO;</pre>
            </code>
         </example>
         <p>Artikel von Satya Komatineni: <a href="http://www.onjava.com/lpt/a/4443#1">The Effective Use of Joins in Select Statements</a>
         </p>
         <subsubtopic name="orderBy">Sortierungen</subsubtopic>
         <p>Zur Sortierung hinsichtlich einer oder mehrerer Spalten der als Anfrageergebnis ermittelten Tabelle
steht die <code>ORDER BY</code>-Klausel zur Verfügung.<br/>
            <exampleLink ref="OB1"/> zeigt die Anwendung zur lexikalischen Sortierung:</p>
         <example name="OB1" caption="Sortierung">
            <code>
               <pre>CREATE TABLE Person(
	Vorname VARCHAR(10),
	Nachname VARCHAR(10));

INSERT INTO Person VALUES("Adam", "C-Mann");
INSERT INTO Person VALUES("Cesar", "C-Mann");
INSERT INTO Person VALUES("Berta", "C-Mann");
INSERT INTO Person VALUES("Adam", "A-Mann");
INSERT INTO Person VALUES("Cesar", "A-Mann");
INSERT INTO Person VALUES("Berta", "A-Mann");
INSERT INTO Person VALUES("Adam", "B-Mann");
INSERT INTO Person VALUES("Cesar", "B-Mann");
INSERT INTO Person VALUES("Berta", "B-Mann");

SELECT *
FROM Person
ORDER BY Nachname;</pre>
            </code>
         </example>
         <p>Ist die Sortierung bezüglich mehrerer Attribute, d.h. Sortierung innerhalb eines gleicher
Attributwerte hinsichtlich eines anderen Attributs, gewünscht, so können auch mehrere Sortierattribute in der
<code>ORDER BY</code>-Klausel versammelt werden.<br/>
Zusätzlich zeigt das Beispiel die Kurzschreibweise, welche die zu sortierenden Attribute nicht namentlich benennt, sondern
nur hinsichtlich ihrer Position innerhalb der <code>SELECT</code>-Klausel referenziert.</p>
         <example name="OB2" caption="Sortierung bezüglich mehrerer Attribute">
            <code>
               <pre>CREATE TABLE Person(
	Vorname VARCHAR(10),
	Nachname VARCHAR(10));

INSERT INTO Person VALUES("Adam", "C-Mann");
INSERT INTO Person VALUES("Cesar", "C-Mann");
INSERT INTO Person VALUES("Berta", "C-Mann");
INSERT INTO Person VALUES("Adam", "A-Mann");
INSERT INTO Person VALUES("Cesar", "A-Mann");
INSERT INTO Person VALUES("Berta", "A-Mann");
INSERT INTO Person VALUES("Adam", "B-Mann");
INSERT INTO Person VALUES("Cesar", "B-Mann");
INSERT INTO Person VALUES("Berta", "B-Mann");

SELECT *
FROM Person
ORDER BY 2,1;</pre>
            </code>
         </example>
         <p>Vorgabegemäß erfolgt die Sortierung aufsteigend (<em>ascending</em>). Die Umkehrung der Sortierreihenfolge
kann durch nachstellen der Zeichenfolge <code>DESC</code> (für <em>descending</em>) nach dem Namen des Sortierattributes
erreicht werden.<br/>
Die aufsteigende Vorgabesortierung (<code>ASC</code>) wird üblicherweise nicht ausgeschrieben, ist aber im
<exampleLink ref="OB3"/> zur besseren Verdeutlichung expliziert.</p>
         <example name="OB3" caption="Auf- und Absteigende Sortierung bezüglich mehrerer Attribute">
            <code>
               <pre>CREATE TABLE Person(
	Vorname VARCHAR(10),
	Nachname VARCHAR(10));

INSERT INTO Person VALUES("Adam", "C-Mann");
INSERT INTO Person VALUES("Cesar", "C-Mann");
INSERT INTO Person VALUES("Berta", "C-Mann");
INSERT INTO Person VALUES("Adam", "A-Mann");
INSERT INTO Person VALUES("Cesar", "A-Mann");
INSERT INTO Person VALUES("Berta", "A-Mann");
INSERT INTO Person VALUES("Adam", "B-Mann");
INSERT INTO Person VALUES("Cesar", "B-Mann");
INSERT INTO Person VALUES("Berta", "B-Mann");

SELECT *
FROM Person
ORDER BY 2 ASC,1 DESC;</pre>
            </code>
         </example>
         <subsubtopic name="subqueries">Unteranfragen</subsubtopic>
         <p>Bisher wurden Anfragen lediglich auf Tabellen in ihrer Rolle als in der Datenbank abgelegte Eingabemengen betrachtet.
Die relationale Sichtweise erfordert jedoch keineswegs, daß die Eingangswerte einer Anfrage direkt aus der Datenbank
gelesen werden müssen. Sie können auch Ergebnis einer weiteren Anfrage sein.</p>
         <p>Anfragen die vor einer anderen Anfrage ausgeführt werden müssen um für diese Eingangswerte zu liefern werden
daher als <em>Unterabfragen</em> (<em>subqueries</em> oder <em>nested queries</em>) bezeichnet.</p>
         <p>Das <exampleLink ref="SQ1"/> zeigt eine solche Unteranfrage die alle Projektnummern liefert welche Projekten zugeordnet
sind die in der durch <em>Smith</em> gleiteten Abteilung bearbeitet werden. Eine zweite Unterabfrage des
Beispiels liefert alle Nummern von Projekten an denen dieser Mitarbeiter selbst arbeitet.<br/>
Die durch diese Abfrage gelieferten Daten (Projektnummern) sind Eingangsdaten in die Ermittlung der Projektnamen.</p>
         <example name="SQ1" caption="Unterabfrage I">
            <code>
               <pre>SELECT DISTINCT PNAME
FROM PROJECT
WHERE PNUMBER IN (
   SELECT PNUMBER
   FROM PROJECT AS p, DEPARTMENT AS d, EMPLOYEE AS e
   WHERE e.SSN = d.MGRSSN AND
   d.DNUMBER = p.DNUM AND
   e.LNAME="Smith")
      OR
         PNUMBER IN (SELECT PNO
            FROM WORKS_ON AS w, EMPLOYEE AS e
            WHERE w.ESSN = e.SSN AND
            e.LNAME="Smith");</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="SQ2"/> zeigt den Vergleich eines Einzelwertes (<code>SALARY</code>) mit einer Menge gelieferter
Werte. Die Anfrage ermittelt diejenigen Mitarbeiter, deren Einkommen höher liegt als das Einkommen aller Mitarbeit in Abteilung
Nummer 5. (Hinweis es wird nicht ermittelt ob das Einkommen größer ist als die Summe aller Einkommen der Mitarbeiter aus
Abteilung 5, sondern nur ob das Einkommen größer ist als jedes Einzeleinkommen eines Mitarbeiters aus Abteilung 5.)</p>
         <example name="SQ2" caption="Unterabfrage II">
            <code>
               <pre>SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE SALARY &gt; ALL (SELECT SALARY FROM EMPLOYEE WHERE DNO=5);</pre>
            </code>
         </example>
         <subsubtopic name="correlatedSubqueries">Korrelierte Unteranfragen</subsubtopic>
         <p>Eine besondere Form der Unteranfragen stellen solche dar, die sich in ihrer <code>WHERE</code>-Klausel auf die
äußere Anfrage beziehen. <br/>
Diese Form der Anfrageschachtelung wird auch als <em>korrelierte Unteranfrage</em> bezeichnet.</p>
         <p>Das <exampleLink ref="SQ3"/> zeigt eine solche Anfrage, die alle Verwandten (<code>DEPENDENT</code>) ermittelt,
die das selbe Geschlecht haben wie der in der Tabelle <code>EMPLOYEE</code> erfaßte Mitarbeiter.</p>
         <example name="SQ3" caption="Korrelierte Unterabfrage">
            <code>
               <pre>SELECT e.FNAME, e.LNAME
FROM EMPLOYEE AS e
WHERE e.SSN IN (SELECT ESSN
					 FROM DEPENDENT
					 WHERE e.SEX = SEX);</pre>
            </code>
         </example>
         <p>Jede korrelierte Unterabfrage kann durch Umschreibung in eine nicht-korrelierte Fassung überführt werden.
So lautet die Formulierung des aus <exampleLink ref="SQ3"/> ohne geschachtelte Unterabfrage:</p>
         <example name="SQ4" caption="Auflösung der korrelierten Unterabfrage">
            <code>
               <pre>SELECT e.FNAME, e.LNAME
FROM EMPLOYEE AS e, DEPENDENT AS d
WHERE e.SSN = d.ESSN AND
e.SEX = d.SEX;</pre>
            </code>
         </example>
         <p>Die Formulierung als geschachtelte Unterabfrage ist damit nicht zwingend notwendig, kann jedoch aus Gründen der
Übersichtlichkeit gewünscht sein.</p>
         <p>Die nähere Betrachtung der Anfragen aus <exampleLink ref="SQ3"/> und <exampleLink ref="SQ4"/> zeigen, daß die
aus der Tabelle <code>DEPENDENT</code> angefragten Daten lediglich zur Formulierung der Bedingung, nicht jedoch
zur Ausgabe herangezogen werden. Daher läßt sich die Bedingung unter Verwendung des <code>EXISTS</code>-Operators
umschreiben zu:</p>
         <example name="SQ5" caption="Korrelierte Unterabfrage mit EXISTS">
            <code>
               <pre>SELECT e.FNAME, e.LNAME
FROM EMPLOYEE AS e
WHERE EXISTS (	SELECT *
					FROM DEPENDENT
					WHERE e.SSN = ESSN AND
					e.SEX = SEX);</pre>
            </code>
         </example>
         <p>
            <code>EXISTS</code> liefert den <name>Boole</name>'schen Wahrheitswert immer dann, wenn die (Unter-)Abfrage
eine nichtleere Menge ist, d.h. Daten enthält.</p>
         <p>Anfragen die <code>EXISTS</code> oder <code>IN</code>
beinhalten können auch durch linke Äußere Verbünde ausgedrückt werden, wie
<exampleLink ref="SQ6"/> zeigt:</p>
         <example name="SQ6" caption="Korrelierte Unterabfrage ausgedrückt als linker äußerer Verbund">
            <code>
               <pre>SELECT e.FNAME, e.LNAME
FROM EMPLOYEE AS e LEFT JOIN DEPENDENT AS d
ON e.SSN = d.ESSN AND e.SEX = d.SEX
WHERE d.SEX IS NOT NULL; </pre>
            </code>
         </example>
         <p>Eine ähnliche Funktion wie die <code>EXISTS</code>-Operation stellt <code>ANY</code> bereit,
jedoch liefert diese die durch die Unterabfrage angefragten Tupel zurück um sie an eine Bedingung zu knüpfen.<br/>
            <exampleLink ref="SQ7"/> zeigt die Ermittlung der Namen derjenigen Mitarbeiter, die mehr als
irgendein beliebiger Manager verdienen.</p>
         <example name="SQ7" caption="Unterabfrage unter Verwendung von ANY">
            <code>
               <pre>SELECT FNAME
FROM EMPLOYEE
WHERE SALARY &gt; ANY (SELECT SALARY
   FROM EMPLOYEE
   WHERE SSN IN (SELECT SUPERSSN
      FROM EMPLOYEE));
						  					</pre>
            </code>
         </example>
         <subsubtopic name="AggGrp">Aggregatfunktionen und Gruppierung</subsubtopic>
         <p>Über die Sortierung hinausgehend ist oftmals ein bestimmte Anordnung der durch eine Anfrage ermittelten
Ergebnistupel gewünscht, etwa als inhaltliche Gruppierung.<br/>
Gleichzeitig sind oft quantiative Aussagen über Eigenschaften der Resultatmenge --- wie größter oder kleinster Wert
sowie Summen- oder Durchschnittsbildung --- gewünscht.</p>
         <p>
            <exampleLink ref="AG1.sql"/> zeigt die Ermittlung der Summe aller Gehälter (SQL-Funktion <code>SUM</code>) sowie
des Maximal- (<code>MAX</code>), Minimal- (<code>MIN</code>) und Durchschnittsgehalts (<code>AVG</code>) für die
Mitarbeiter der <em>Research</em>-Abteilung.<br/>
Die genannten SQL-Funktionen werden als <em>
               <keyword>Aggregierungsfunktion</keyword>en</em> bezeichnet, da sie
die durch die Abfrage ermittelten Einzelwerte (d.h. die Einträge der Spalte <code>SALARY</code>) jeweils zu genau einer
Aussage verdichten.</p>
         <example name="AG1" caption="Aggregierungsfunktionen">
            <code>
               <pre>SELECT SUM(SALARY), MAX(SALARY), MIN(SALARY), AVG(SALARY)
FROM EMPLOYEE, DEPARTMENT
WHERE DNO = DNUMBER AND DNAME="Research";</pre>
            </code>
         </example>
         <p>Mit der Funktion <code>COUNT</code> steht eine Möglichkeit zur Ermittlung der Mächtigkeit einer Tupelmenge zur
Verfügung. Beispiel <exampleLink ref="AG2"/> zeigt ihre Verwendung zur Ermittlung der Anzahl der Mitarbeiter der
mit <em>Research</em> bezeichneten Abteilung.</p>
         <example name="AG2" caption="Zählfunktion I">
            <code>
               <pre>SELECT COUNT(*)
FROM EMPLOYEE, DEPARTMENT
WHERE DNO = DNUMBER AND DNAME = "Research";</pre>
            </code>
         </example>
         <p>Als Argument der <code>COUNT</code>-Funktion kann mit <code>DISTINCT</code> ein Schlüsselwort angegeben werden,
welches die ausschließliche Zählung verschiedener Werte erwirkt.<br/>
Die Anfrage aus Beispiel <exampleLink ref="AG3"/> ermittelt durch Nutzung dieses Schlüsselwortes die Anzahl der
verschiedenen Werte in der Spalte <code>SALARY</code>.</p>
         <example name="AG3" caption="Zählfunktion II">
            <code>
               <pre>SELECT COUNT(DISTINCT SALARY)
FROM EMPLOYEE;</pre>
            </code>
         </example>
         <p>Häufig wird, wie in <exampleLink ref="AG4"/> gezeigt, eine Anfrage zur Ermittlung der Anzahl als Unterabfrage
formuliert und in der umgebenden Hauptabfrage mit einer Bedingung versehen.</p>
         <example name="AG4" caption="Eingebettete Zählfunktion">
            <code>
               <pre>SELECT LNAME, FNAME
FROM EMPLOYEE
WHERE (SELECT COUNT(*)
		 FROM DEPENDENT
		 WHERE SSN=ESSN) &gt;= 2;</pre>
            </code>
         </example>
         <p>Neben den bisher gezeigten aggregierten Aussagen über eine Gesamtmenge besteht oftmals der Wunsch nach von Ermittlung
Aussagen dieses Stils über bestimmte Werteklassen innerhalb der betrachteten Gesamtmenge. Hierzu dienen Gruppierungen
der Ausgangsmenge, auf welche dann die verschiedenen Aggregierungsfunktionen separat angewandt werden können.<br/>
Beispiel <exampleLink ref="AG5"/> zeigt dies für die Ermittlung der Mitarbeiteranzahl pro Abteilung sowie der
Berechnung des abteilungsinternen Durchschnittsgehalts.</p>
         <example name="AG5" caption="Gruppierung">
            <code>
               <pre>SELECT d.DNAME AS "Abteilung", COUNT(*) AS "Anzahl Mitarbeiter", AVG(SALARY) AS "Durchschnittsgehalt"
FROM EMPLOYEE AS e, DEPARTMENT AS d
WHERE e.DNO = d.DNUMBER
GROUP BY DNO;</pre>
            </code>
         </example>
         <p>Zur Realisierung wird die <code>GROUP BY</code>-Klausel verwendet, welche die Angabe eines oder mehrerer
Attribute zuläßt anhand der die selektierte Menge partitioniert werden soll.</p>
         <p>Die Anfrage des Beispiels <exampleLink ref="AG6"/> zeigt die Nutzung einer Verbundbedingung innerhalb einer
Gruppierungsanfrage, die Projektnummer und -name sowie vermöge der <code>COUNT</code>-Funktion die Anzahl der das
Projekt bearbeitenden Mitarbeiter ermittelt.</p>
         <example name="AG6" caption="Gruppierung mit Verbundbedingung">
            <code>
               <pre>SELECT PNUMBER, PNAME, COUNT(*) AS "Anzahl Mitarbeiter"
FROM PROJECT, WORKS_ON
WHERE PNUMBER = PNO
GROUP BY PNUMBER, PNAME;</pre>
            </code>
         </example>
         <p>Durch zusätzliche Angabe der <code>HAVING</code>-Klausel kann die Menge der Gruppierungsresultate mittels einer Bedingung beschränkt werden.<br/>
So ermittelt die Anfrage aus <exampleLink ref="AG7"/> dieselben Resultat wie die in <exampleLink ref="AG6"/> gezeigte,
jedoch nur für Projekte deren Mitarbeiteranzahl größer 2 ist.</p>
         <example name="AG7" caption="Bedingte Gruppierung">
            <code>
               <pre>SELECT PNUMBER, PNAME, COUNT(*)
FROM PROJECT, WORKS_ON
WHERE PNUMBER = PNO
GROUP BY PNUMBER, PNAME
HAVING COUNT(*) &gt; 2;</pre>
            </code>
         </example>
         <p>Die formulierte Beschränkung wirkt sich nicht auf die zur Berechnung herangezogene Grundgesamtheit, sondern
lediglich auf die Ausgabe der Gruppierungsergebnisse aus, die vor der Auswertung der in der <code>HAVING</code>-Klausel
formulierten Bedingung berechnet werden müssen.<br/>
Zur Beschränkung der zur Berechnung heranzuziehenden Grundgesamtheit steht auch unter Nutzung der
<code>GROUP BY</code>-Klausel der durch <code>WHERE</code> formulierte Bedingungsteil der <code>SELECT</code>-Anfrage
zur Verfügung.</p>
         <example name="AG8" caption="Beschränkung der Gruppierungseingangsdaten">
            <code>
               <pre>SELECT PNUMBER, PNAME, COUNT(*)
FROM PROJECT, WORKS_ON, EMPLOYEE
WHERE PNUMBER = PNO AND SSN = ESSN AND DNO=5
GROUP BY PNUMBER, PNAME;</pre>
            </code>
         </example>
         <p>Gruppierungsschritte können auch in Unterabfragen auftreten, wie das <exampleLink ref="AG9"/> zur Ermittlung
des Abteilungsnamens und der Anteil der darin arbeitenden Personen mit einem Gehalt über 40000 für alle
Abteilungen mit mindestens 2 Mitgliedern zeigt:</p>
         <example name="AG9" caption="Gruppierung in Unterabfrage">
            <code>
               <pre>SELECT DNAME, COUNT(*)
FROM DEPARTMENT, EMPLOYEE
WHERE DNUMBER = DNO AND SALARY &gt; 4000 AND DNO IN (
		SELECT DNO
		FROM EMPLOYEE
		GROUP BY DNO
		HAVING COUNT(*) &gt; 2)
GROUP BY DNUMBER;</pre>
            </code>
         </example>
         <subsubtopic name="Manipulate">Der Datenmanipulationsteil von SQL</subsubtopic>
         <p>Neben den bisher betrachteten Eigenschaften der Sprache SQL zur Definition von Datenbankstrukturen und zur
Abfrage von Datenbankinhalten stehen auch Befehle zur Manipulation in Form von Einfüge-, Aktualisierung- und Löschoperationen
zur Verfügung.</p>
         <subsubsubtopic name="INSERT">Der Einfügebefehl <code>INSERT</code>
         </subsubsubtopic>
         <p>Zum Hinzufügen neuer Tupel in eine bestehende Tabelle durch Angabe von Werten für einen oder mehrere Spalten
dieser Tabelle wird der Befehl <code>INSERT</code> anboten.<br/>
Typischerweise wird dieser Befehlstyp zum Einfügen neuer Datensätze in bestehende Tabellen laufender
Applikationen, ebenso wie zur Übernahme kompletter Datenbestände aus existierenden Datenquellen oder zur
Neuladung einer Datenbank im Rahmen der Wiederherstellungsprozesses nach einem Systemausfall mit Datenverlust verwendet.</p>
         <p>Die allgemeine Syntax des <code>INSERT</code>-Ausdruckes lautet:<br/>
            <code>
               <pre>INSERT INTO tbl_name (col_name,...)? VALUES(constant|NULL ...)</pre>
            </code>
         </p>
         <example name="INS1" caption="Einfügen eines vollständigen Tupels">
            <code>
               <pre>INSERT INTO EMPLOYEE VALUES(
	'John',
	'B',
	'Smith',
	123456789,
	'1965-01-09',
	'731 Fondren, Houston, TX',
	'M',
	30000,
	333445555,
	5);</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="INS1"/> zeigt den Befehl zur Erzeugung eines neuen Eintrages in der Tabelle
<code>EMPLYOEE</code> der Demodatenbank. Die Aufzählung der einzufügenden Werte ist vollständig, d.h. für jede
Spalte der Tabelle wird explizit ein konstanter Wert angegeben. Per Konvention müssen alle nichtnumerischen Werte in
einfache oder doppelte Hochkommata eingeschlossen werden. Hierunter fallen neben den <a href="#Zeichenkettentypen">Zeichenkettentypen</a> auch
alle <a href="#Datumstypen">Datumstypen</a>.</p>
         <p>Eine Sonderstellung innerhalb der angebbaren Konstanten zur Eintragung stellt die Zeichenkette <code>NULL</code> dar.
Sie repräsentiert explizit fehlende Werte, deren Tabelleneinträge entsprechend gekennzeichnet werden. Zur Abgrenzung von
der Zeichenkette <em>NULL</em> wird diese Angabe nicht in Anführungzeichen eingeschlossen, selbst wenn es sich um
eine Spalte eines Zeichenkettentypen handelt.<br/>
            <exampleLink ref="INS2"/> zeigt eine exemplarische Befehlskonstruktion:</p>
         <example name="INS2" caption="Einfügen eines vollständigen Tupels mit NULL-Wert">
            <code>
               <pre>INSERT INTO EMPLOYEE VALUES(
	'James',
	'E',
	'Borg',
	888665555,
	'1937-11-10',
	'450 Stone, Houston, TX',
	'M',
	55000,
	NULL,
	1);
</pre>
            </code>
         </example>
         <p>Neben der Möglichkeit vollständige Tupel einzufügen, kann durch explizite Angabe der einzufügenden Spalten auch
eine partielle Befüllung des neu erzeugten Tupels vorgenommen werden.<br/>
Für die im <code>INSERT</code>-Befehl nicht angegebenen Spalten wird der spezifizierte Vorgabewert oder <code>NULL</code>
eingefügt.<br/>
            <exampleLink ref="INS3"/> zeigt dies exemplarisch anhand des Einfügens der drei Attribute <code>FNAME</code>, <code>LNAME</code>
und <code>SSN</code>. Gleichzeitig stellt das Beispiel auch heraus, daß bei expliziter Angabe der einzufügenden
Spalten die gewählte Reihenfolge von der in der Tabelle realisierten abweichen kann.</p>
         <example name="INS3" caption="Einfügen eines unvollständigen Tupels">
            <code>
               <pre>INSERT INTO EMPLOYEE (LNAME, FNAME, SSN) VALUES(
	'Doe',
	'John',
	912873465);
</pre>
            </code>
         </example>
         <p>Prinzipiell kann jedes Element der Potenzmenge der Attribute einer Relation eingefügt werden. Es muß jedoch zwingend
einen Wert für das Primärschlüsselattribut enthalten, da hierfür der Wert <code>NULL</code> nicht gesetzt werden darf.</p>
         <subsubsubtopic name="UPDATE">Der Aktualisierungsbefehl <code>UPDATE</code>
         </subsubsubtopic>
         <p>Zur Aktualisierung von Werten innerhalb bestehender Datenbankeinträge bietet der SQL-Sprachumfang den
Befehl <code>UPDATE</code> an, der es gestattet frei wählbare Mengen von Tupeln einer Tabelle zu modifizieren.</p>
         <p>Die allgemeine Syntax des Befehls lautet:<br/>
            <code>
               <pre>UPDATE tbl_name SET col_name=expression, ... [WHERE search_condition]</pre>
            </code>
         </p>
         <p>Beispiel <exampleLink ref="UPD3"/> zeigt den Befehl zur <code>null</code>-Setzung aller in der Tabelle
<code>EMPLOYEE</code> verwalteten Geburtsdaten (<code>BDATA</code>):</p>
         <example name="UPD3" caption="Modifikation aller Tupel durch Setzen eines konstanten Wertes">
            <code>
               <pre>UPDATE EMPLOYEE SET BDATE=NULL;</pre>
            </code>
         </example>
         <p>Neben der Eintragung von Konstanten können auch neue Inhalte aus den Bisherigen errechnet werden. So zeigt
<exampleLink ref="UPD2"/> eine Aktualisierung, die das Gehalt (<code>SALARY</code>) aller Mitarbeiter
um zehn Prozent erhöht:</p>
         <example name="UPD2" caption="Modifikation aller Tupel durch Setzen eines berechneten Wertes">
            <code>
               <pre>UPDATE EMPLOYEE SET Salary=Salary*1.1;</pre>
            </code>
         </example>
         <p>Durch Nutzung der, identisch zum <code>SELECT</code>-Ausdruck aufgebauten, <code>WHERE</code>-Klausel
kann die Menge der von der Änderung betroffenen Datensätze eingeschänkt werden.<br/>
Das Beispiel <exampleLink ref="UPD1"/> ändert in allen Einträgen, deren <code>LNAME</code> auf <code>Zelaya</code>
lautet den Wert zu <code>Jones</code>.<br/>
Die Anzahl der betroffenen Tupel ist durch den <code>UPDATE</code>-Ausdruck nicht festlegbar, sondern richtet
sich ausschließlich nach der durch die <code>WHERE</code>-Klausel selektierten Eintragsmenge.</p>
         <example name="UPD1" caption="Modifikation von Tupeln">
            <code>
               <pre>UPDATE EMPLOYEE SET LNAME='Jones'
WHERE LNAME='Zelaya';</pre>
            </code>
         </example>
         <p>Durch die Nutzbarkeit der vollständigen Möglichkeiten der aus dem <code>SELECT</code>-Befehl bekannten
Mächtigkeit der <code>WHERE</code>-Klausel lassen sich selbst komplexe Aktualisierungen realiseren.<br/>
            <exampleLink ref="UPD4"/> zeigt führt die Erhöhung der Gehälter derjenigen Mitarbeiter durch, die Abteilungen
zugewiesen sind, die mehr als zwei Projekte bearbeiten.</p>
         <example name="UPD4" caption="Modifikation von Tupeln (Ermittlung der betroffenen Tupel durch Subanfrage)">
            <code>
               <pre>UPDATE EMPLOYEE SET SALARY=SALARY*1.1 WHERE DNO IN
	(SELECT DNUMBER
	FROM PROJECT AS p, DEPARTMENT AS d
	WHERE d.DNUMBER=p.DNUM
	GROUP BY 1
	HAVING COUNT(*) &gt; 2);</pre>
            </code>
         </example>
         <subsubsubtopic name="DELETE">Der Löschbefehl <code>DELETE</code>
         </subsubsubtopic>
         <p>Zur Löschung von verwalteten Tupeln aus einer Tabelle existiert der <code>DELETE</code>-Befehl, der die betroffenen
Datensätze ohne weite Nachfrage entfernt.</p>
         <p>Seine allgemeine Syntax lautet:<br/>
            <code>DELTE FROM tbl_name [WHERE search_condition]</code>
         </p>
         <p>Die einfachste Ausprägung der <code>DELETE</code>-Anweisung löscht alle Tupel einer Tabelle:</p>
         <example name="DEL1" caption="Löschen aller Tupel einer Tabelle">
            <code>
               <pre>DELETE FROM EMPLOYEE;</pre>
            </code>
         </example>
         <p>Durch Angabe der <code>WHERE</code>-Klausel können, wie bereits bei <code>UPDATE</code> für die zu aktualisierenden
Tupel gezeigt, die zu löschenden Tupel eingegrenzt werden.<br/>
So entfernt der Ausdruck aus <exampleLink ref="DEL2"/> alle Mitarbeiter die in Houston wohnen.</p>
         <example name="DEL2" caption="Löschen aller Mitarbeiter, die in Houston wohnhaft sind">
            <code>
               <pre>DELETE FROM EMPLOYEE
WHERE ADDRESS LIKE "%Houston%";</pre>
            </code>
         </example>
         <p>Durch die Nutzung der expliziten Mengenangabe innerhalb der <code>WHERE</code>-Klausel läßt sich die
Menge der zu entfernenden Datensätze statische eingrenzen wie <exampleLink ref="DEL4"/> zeigt.</p>
         <example name="DEL4" caption="Löschen bestimmter Datenstätze">
            <code>
               <pre>DELETE EMPLOYEE
WHERE SSN IN (333445555, 888665555, 987987987);</pre>
            </code>
         </example>
         <p>
            <exampleLink ref="DEL3"/> zeigt die Nutzung einer Unterabfrage zur Ermittlung aller Abteilungen, die nur genau ein
Projekt durchführen und anschließenden Löschung dieser Abteilungen aus der Tabelle <code>DEPARTMENT</code>.</p>
         <example name="DEL3" caption="Löschen aller Abteilungen, die nur genau ein Projekt durchführen">
            <code>
               <pre>DELETE FROM DEPARTMENT
WHERE DNUMER IN
	(SELECT DNUM
	FROM PROJECT
	GROUP BY 1
	HAVING COUNT(*) = 1);</pre>
            </code>
         </example>
      </region>
      <topic name="definitions">Definitionsverzeichnis</topic>
      <defList/>
      <topic name="keywords">Schlagwortverzeichnis</topic>
      <keywordList/>
      <topic name="illustrations">Abbildungsverzeichnis</topic>
      <illustrationList/>
      <topic name="examples">Verzeichnis der Beispiele</topic>
      <exampleList/>
   </body>
</document>
