Datenbanksysteme SS 06 Ole Ole WM Tipp Tutor: Patrick Neumann Michael Zuberbier Zaidoun Samman Carsten Martin Michael Zuberbier Zaidoun Samman Carsten Martin Ole Ole WM Tipp Spezifikation Geschäftsprozess Ziel Akteur Eingabe : : : : Registrierungs-Routine User registriert sich in Datenbank User gewünschter Account-name und Passwort (optional: Eingabe eine Sicherheitspassworts um Adminrechte zu bekommen) registriert im System um sich darauf einloggen zu können falls Account-name schon vorhanden wird gebeten einen anderen Account-namen einzugeben und falls Sicherheitspasswort falsch, erfolgt Anfrage auf Korrektur Result Ausnahme : : Geschäftsprozess Ziel Akteur Eingabe Result Ausnahme : : : : : : Login-routine einloggen des Admin und/oder Users in das Tippsystem registrierter Admin und/oder User von sich registrierter Account-name und Passwort User ist im System eingeloggt. Wenn Account-name und/oder Passwort falsch eingetippt wurde, nochmaliges korrigieren möglich Geschäftsprozess Ziel Akteur Eingabe Result Ausnahme : : : : : : Tipp-routine User tippt auf noch kommende WM Spiele eingeloggter User Tore der Spielbegegnung(en) Tipp erfolgt, hoffen auf Punktgewinn durch richtigen Tipp Bei Eingabe von nicht numerischen Werten, Fehlermeldung auf Berichtigung der Werte Geschäftsprozess Ziel : : Akteur Eingabe Result Ausnahme : : : : Statistik-routine Admin und/oder User bestaunt Statistik über seine erzielten Punkte/Tipps, der Top10 oder alle Resultate eines bestimmten Spiels eingeloggter Admin und/oder User Format der Statistik Ergebnis in Punkten/Tipps wird numerisch angezeigt Admin kann natürlich nicht seine Punkte/Tipps ansehen, da er nicht tippen kann Michael Zuberbier Zaidoun Samman Carsten Martin Geschäftsprozess Ziel : : Akteur Eingabe Result Ausnahme : : : : Geschäftsprozess Ziel Akteur Eingabe Result : : : : : Ausnahme : Geschäftsprozess Ziel Akteur Eingabe : : : : Result : Ausnahme : Geschäftsprozess Ziel Akteur Eingabe Result Ausnahme : : : : : : Team-routine Admin gibt die qualifizierenden Teams ein für die jeweilige Runde eingeloggter Admin Team –und Gruppennamen Teams einsehbar in Gruppenübersicht falls Teams fehlen, nochmalige Korrektur Übersichts-routine Übersicht der Gruppen oder KO-Runden eingeloggter Admin und/oder User welche Gruppen oder welche Runde des KO-Systems Admin und/oder User können sich die Gruppen –bzw. KO-System-übersicht ansehen falls noch keine Teams eingetragen wurde, Entschuldigung auf später Spiel-routine Begegnungen eintragen eingeloggter Admin beide Teamnamen, welcher Rundentyp und Endzeit für Tipps, nach Beendigung des Spiels erfolgen die Ergebnisse durch Bearbeitung der Eingabe Begegnung sind somit tippbar, nach Ergebniseintragung erfolgt automatische Berechnung und Eintragung der Punkte für jeden User bei fehlenden Teamnamen oder falscher Datentypwahl des Ergebnisses, Erbitten auf Korrektur Verwaltungs-routine User verwalten eingeloggter Admin der zu löschende User User und alle seine Tipps und Statistiken existieren nicht mehr falls zu löschender User nicht existiert wegen fehlerhafter Eingabe, erbitten auf Korrektur Michael Zuberbier Zaidoun Samman Carsten Martin 2. MeilenStein „oleole“ Projekt Patrick Neumann Teil 2: Relationales Schema Teil 2-1) - Entität „Admin“ wurde entfernt, und stattdessen wurde einen Attribut „admin“ in der Tabelle „Users“ hinzugefügt. - Week Entität „Tipp“ wurde zu einer (M,N) Beziehung „tipp“ zwischen „Users“ und „Spiel“ umgewandelt. - Eine neue Entität „Spieler“ mit einer (1,N) Beziehung „hat“ zur Entität „Team“ und einer zweiten (M,N) „schießt_tor“ zur Entität „Spiel“ wurde zum ER-Diagramm hinzugefügt. - Attribut „punkte“ in „users“ wurde aus technischen Gründen in „statistik“ verlegt und in „points“ umgennant. Michael Zuberbier Zaidoun Samman Carsten Martin Teil 2-2) Relationales Schema: Team (Land, Gruppe ,Punkte) Spieler(Name, Vorname, Nummer, Tore, Land) Spiel(Team1, Team2, Runde , Tor1,Tor2,Anfang) Statistik(Name,Tendenz ,Differenz ,Verloren ,Sieg ,Points, Username) Users(Username, Password, Email, admin) Involviert(Land, Team1, Team2, Runde) Schießt_Tor(Name, Vorname, Team1, Team2, Runde,Minute) Tipp(Name, Team1, Team2, Runde, Tore1, Tore2) Teil 3: Relationen in Oracle/Postgres Teil 3-2) 3-2-1) create table team ( land varchar(20) primary key, gruppe varchar(1), punkte int ); create table spieler ( name varchar(20), vorname varchar(20), team varchar(20), nummer int, tore int, primary key (name, vorname), foreign key (team) references team(land) ); create table spiel ( team1 varchar(20), team2 varchar(20), runde varchar(20), tore1 int, tore2 int, anfang timestamp, 2. MeilenStein „oleole“ Projekt Patrick Neumann Michael Zuberbier Zaidoun Samman Carsten Martin 2. MeilenStein „oleole“ Projekt Patrick Neumann primary key(team1,team2,runde) ); create table schiesst_tor ( name varchar (20), vorname varchar (20), team1 varchar (20), team2 varchar (20), runde varchar (20), minute int, primary key (name, vorname, team1, runde), foreign key (name,vorname) references spieler (name,vorname), foreign key (team1,team2,runde) references spiel(team1,team2,runde) ); create table users ( username varchar(20) primary key, password varchar(20), email varchar(50), punkte int, admin varchar(4) ); create table statistik ( name varchar(20) primary key, verloren int, tendenz int, differenz int, sieg int, foreign key (name) references users(username) ); create table tipp ( tore1tipp int, tore2tipp int, username varchar (20), team1 varchar (20), team2 varchar (20), runde varchar (20), primary key (username, team1, team2, runde), foreign key (team1, team2, runde)references spiel (team1, team2, runde), foreign key (username) references users (username) ); create table involviert ( land varchar(20), team1 varchar(20), team2 varchar(20), runde varchar(20), primary key (land, team1, team2, runde), foreign key (team1, team2, runde)references spiel (team1, team2, runde), foreign key (land)references team (land) ); AUSGABE : NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "team_pkey" for table "team" Michael Zuberbier Zaidoun Samman Carsten Martin NOTICE: CREATE TABLE / PRIMARY KEY will create "spieler_pkey" for table "spieler" NOTICE: CREATE TABLE / PRIMARY KEY will create for table "spiel" NOTICE: CREATE TABLE / PRIMARY KEY will create "schiesst_tor_pkey" for table "schiesst_tor" NOTICE: CREATE TABLE / PRIMARY KEY will create for table "users" NOTICE: CREATE TABLE / PRIMARY KEY will create "statistik_pkey" for table "statistik" NOTICE: CREATE TABLE / PRIMARY KEY will create for table "tipp" NOTICE: CREATE TABLE / PRIMARY KEY will create "involviert_pkey" for table "involviert" 2. MeilenStein „oleole“ Projekt Patrick Neumann implicit index implicit index "spiel_pkey" implicit index implicit index "users_pkey" implicit index implicit index "tipp_pkey" implicit index Abfrage war erfolgreich nach 531 ms. Keine Zeilen geliefert. 3-3-2) & 3-3-3) ALTER TABLE schiesst_tor ADD CONSTRAINT schiesst_fk FOREIGN KEY (team1, team2, runde) REFERENCES spiel (team1, team2, runde); ALTER TABLE schiesst_tor ADD CONSTRAINT minuten_check CHECK ("minute" >= 0 AND "minute" < 100); ALTER TABLE spiel ADD CONSTRAINT spiel_check CHECK (tore1 >= 0 AND tore2 >= 0); ALTER TABLE spiel ADD constraint team_ck check (team1 <> team2); ALTER TABLE spiel ADD constraint runde_ck check (runde in ('vorrunde', 'achtelfinale', 'viertelfinale', 'halbfinale', 'platz3', 'finale')); CONSTRAINT admin_ck CHECK (admin::text = 'ja'::text OR admin::text = 'nein'::text), AUSGABE: Abfrage war erfolgreich nach 94 ms. Keine Zeilen geliefert. 3-3-4) 1) insert into spieler values ('lehmann', 'jens', 'deutschland', 2, 0); ERROR: duplicate key violates unique constraint "spieler_pk" 2) update spieler set name='kahn', vorname='oliver' where name='lehmann'; ERROR: duplicate key violates unique constraint "spieler_pk" Michael Zuberbier Zaidoun Samman Carsten Martin 2. MeilenStein „oleole“ Projekt Patrick Neumann 3) insert into spieler values ('ballack', 'michael', 'teamnichtexistent', 10, 0); ERROR: insert or update on table "spieler" violates foreign key constraint "spieler_team_fkey" DETAIL: Key (team)=(teamnichtexistent) is not present in table "team". 4) uptade involviert set land='syrien' where team1='deutschland'; ERROR: insert or update on table "involviert" violates foreign key constraint "involviert_land_fkey" Detail: Key (land)=(syrien) is not present in table "team". 5)delete from team where land='deutschland'; ERROR: update or delete on "team" violates foreign key constraint "spieler_team_fkey" on "spieler" Detail: Key (land)=(deutschland) is still referenced from table "spieler". 6) insert into spieler values ('lehmann', 'oliver', 'deutschland', 233, 0); ERROR: new row for relation "spieler" violates check constraint "nummer_ck" 7) update team set gruppe='x' where land='deutschland' ERROR: new row for relation "team" violates check constraint "gruppe_ck" Teil 4: Datenbasen Da man viele Daten erzeugen muss, steht die dazu gehörige Ausgabe von erfolgreichem Laden der Daten in einem extra Datei namens: logfile.txt in Ordner projektteil4 Teil 5: SQL-Anfragen 5-2) -- Abfrage ausführen: der User ,der am meisten richtig getippt hat SELECT s.name ,s.points FROM test_statistik s WHERE s.points = (SELECT max(points) From test_statistik) Gesamtlaufzeit der Abfrage: 46 ms. Benötigte Zeit zum Holen der Daten:32 ms. 2 Zeilen geholt. -- Abfrage ausführen: Der Team mit den meisten Toren (SELECT s.team2 ,s.tore2 FROM test_spiel s WHERE s.tore2=( SELECT max(tore2) FROM test_spiel ) UNION SELECT s.team1 ,s.tore1 FROM test_spiel s WHERE s.tore1 >( Michael Zuberbier Zaidoun Samman Carsten Martin 2. MeilenStein „oleole“ Projekt Patrick Neumann SELECT max(tore2) FROM test_spiel )) AS foo SELECT max(tore2) From foo ; Gesamtlaufzeit der Abfrage: 16 ms. Benötigte Zeit zum Holen der Daten:31 ms. 6 Zeilen geholt. -- Abfrage ausführen:Liste aller eingetragene Users und Admins und ihren Anzahl SELECT t.admin,count(*) FROM test_users t GROUP BY (admin); Gesamtlaufzeit der Abfrage: 63 ms. Benötigte Zeit zum Holen der Daten:46 ms. 2 Zeilen geholt. (AUSGABE in select.csv) -- Abfrage ausführen:Der Team ,der Weltmeister werden sollte (nach Users meinung) SELECT count(*),t.team1 from test_tipp t where (t.tore2tipp>t.tore1tipp) AND t.runde = 'finale' GROUP BY t.team1 UNION SELECT count(*) ,t.team2 from test_tipp t where(t.tore1tipp>t.tore2tipp) AND t.runde = 'finale' GROUP BY t.team2 Gesamtlaufzeit der Abfrage: 313 ms. Benötigte Zeit zum Holen der Daten:46 ms. 62 Zeilen geholt. -- Abfrage ausführen: der beste Torjäger SELECT s.name,s.vorname,s.team,s.tore from test_spieler s WHERE s.tore=(SELECT max(tore) from test_spieler); Gesamtlaufzeit der Abfrage: 31 ms. Benötigte Zeit zum Holen der Daten:63 ms. 34 Zeilen geholt. AUSGABE in select1.csv -- Abfrage ausführen: Teams ,die alle Spiele in vorrunde gewonnen haben SELECT land FROM test_team WHERE (punkte>= 9); AUSGABE in select2.csv Gesamtlaufzeit der Abfrage: 31 ms. Benötigte Zeit zum Holen der Daten:0 ms. 1 Zeilen geholt. -- Abfrage ausführen: Alle Users,die ihre name mir a anfängt. SELECT name FROM test_spieler WHERE name LIKE 'a%'; Gesamtlaufzeit der Abfrage: 16 ms. Benötigte Zeit zum Holen der Daten:47 ms. Michael Zuberbier Zaidoun Samman Carsten Martin 2. MeilenStein „oleole“ Projekt Patrick Neumann 51 Zeilen geholt. -- Abfrage ausführen: Der absoulot schlechte User,der seine Tipps am meistens daneben ist SELECT name FROM test_statistik WHERE verloren= (SELECT max(verloren) FROM test_statistik ) Gesamtlaufzeit der Abfrage: 15 ms. Benötigte Zeit zum Holen der Daten:16 ms. 1 Zeilen geholt. 5-3) -- Abfrage ausführen: INSERT into tipp values ('sammantipp', 'deutschland','costa rica','vorrunde', 3, 1); Query erfolgreicht durchgeführt: Eine Zeile mit OID 8904722 eingefügt, 110 ms Ausführungszeit. -- Abfrage ausführen: update tipp set tore1tipp=2 and tore2tipp=0 where username='gerhard'; ERROR: argument of AND must be type boolean, not type integer -- Abfrage ausführen: update tipp set tore1tipp=2, tore2tipp=0 where username='gerhard'; Abfrage war erfolgreich durchgeführt: 2 Zeilen, 94 ms Ausführungszeit. -- Abfrage ausführen: delete from users where username='stephie' on cascade ERROR: syntax error at or near "on" at character 44 -- Abfrage ausführen: delete from users where username='stephie'; ERROR: update or delete on "users" violates foreign key constraint "statistik_name_fkey" on "statistik" DETAIL: Key (username)=(stephie) is still referenced from table "statistik". -- Abfrage ausführen: delete from statistik where name='stephie'; delete from tipp where username='stephie'; delete from users where username='stephie'; Abfrage war erfolgreich durchgeführt: 1 Zeilen, 593 ms Ausführungszeit. Michael Zuberbier Zaidoun Samman Carsten Martin 2. MeilenStein „oleole“ Projekt Patrick Neumann Teil 6: Sichten -- Abfrage ausführen: View Alle Users ohne Adminstratoren und ihre Emails CREATE VIEW all_users AS (SELECT username,email FROM users WHERE admin='nein'); Abfrage war erfolgreich nach 906 ms. Keine Zeilen geliefert. -- Abfrage ausführen: View Alle aktuellen Users,ihre zugehörige statisitk(sieg,verloren,differenz,tendenz) und Punkte CREATE VIEW tipp_statistik AS (SELECT * FROM statistik); Abfrage war erfolgreich nach 1125 ms. Keine Zeilen geliefert. Michael Zuberbier Zaidoun Samman Carsten Martin Ole Ole WM Tipp Programmlisting Liste der Funktionalitäten Für alle zugänglich: - Registrierung Login Supportpage Für User zugänglich: - Startseite Gruppen Übersicht KO-System Übersicht Auf offene Spiele tippen Spielergebnisse anschauen Seine eigenen Tipps anschauen und wieder löschen Userstatistik (Punkte, Siege etc. von allen) Fussballstatistik (Spieler anschauen) Logout Für Admin zugänglich: - Startseite Spieler eintragen Spielerliste anzeigen und einzeln löschen Teams eintragen Teamliste anzeigen und einzeln löschen Spiele eintragen Spielliste anzeigen und einzeln löschen Ergebnisse eintragen Spielergebnisse anschauen Userverwaltung (User löschen) Logout Nur intern einsehbar: - Connection Pool Manager DbLogic (einfachere Handhabung für SQL statements in den Servlets) Michael Zuberbier Zaidoun Samman Carsten Martin Funktionsweise Eine Art „three way handshake“, zwischen Servlet und JSP Im Endeffekt gibt es nur 2 Varianten an Servlets (und zugehöriger JSP). In einem der Menüpunkte startet man per Klick das jeweilige Servlet. Folgend 2 Beispiele (andere Funktionalitäten sind im Normalfall analog dazu) Variante A (z.B. Spieler eintragen): - Check ob Sessionattribut zur jeweiligen Funktion passt (Admin oder User) if( "Admin".equals( (String) session.getAttribute( "Status" ) ) ) { ..... } - Select-anweisung „alle teams holen“ dblogic.connect (); spielerliste = dblogic.selectStatement("SELECT * FROM team ORDER BY land", Team.class); dblogic.disconnect(); - Vektor an JSP weitergeben request.setAttribute("spielerliste", spielerliste); - Fehlerbehandlung für leere Felder if( leer.equals((String)request.getParameter("vorname"))) { return "jsps/admin_spieler_hinzufuegen.jsp"; } ..... - an dieser Stelle geht er natürlich erstmal zu JSP, da nach dem Klick auf den Link noch nichts eingegeben wurde. Designdetails lass ich an dieser Stelle mal weg (sieht man ja dann) Es beinhaltet eine Form action, in dem Fall bekommt eine der selectboxes den zuvor geholten Inhalt <% List spielerliste = (List) request.getAttribute("spielerliste"); Iterator iter = spielerliste.iterator(); while (iter.hasNext()) { Team team = (Team) iter.next(); out.println ( "<option value=\"" + team.getLand() + "\"> " + team.getLand() + "</option>" ); } %> Michael Zuberbier Zaidoun Samman Carsten Martin - Wenn alle restlichen Eingaben vollständig sind, kann man per Button einen submit ausführen und landet wieder in dem Servlet Jetzt wo alle Felder beschrieben sind, kommt das Servlet auch zum Insert Statement dblogic.connect (); dblogic.insertStatement("INSERT INTO spieler VALUES ('"+request.getParameter("name")+"','"+request.getParameter("vorname")+"', '"+request.getParameter("team")+"',"+request.getParameter("nummer")+", 0)"); dblogic.disconnect(); - Wenn alles korrekt lief, an Startseite weiterleiten return "jsps/admin_uebersicht.jsp"; Variante B (z.B. Teams löschen): - Check ob Sessionattribut zur jeweiligen Funktion passt (Admin oder User), das ist noch identisch... if( "Admin".equals( (String) session.getAttribute( "Status" ) ) ) { ..... } - Delete-statement abschicken, tut in diesem Fall nichts, da noch keine Parameter übergeben wurden, sprich DELETE ... WHERE primaryKeyattribut=’null’ dblogic.connect (); dblogic.deleteStatement("DELETE FROM spieler WHERE team='" + request.getParameter( "land" ) + "'"); dblogic.deleteStatement("DELETE FROM tipp WHERE team1='" + request.getParameter( "land" ) + "' OR team2='" + request.getParameter( "land" ) + "'"); dblogic.deleteStatement("DELETE FROM spiel WHERE team1='" + request.getParameter( "land" ) + "' OR team2='" + request.getParameter( "land" ) + "'"); dblogic.deleteStatement("DELETE FROM team WHERE land='" + request.getParameter( "land" ) + "'"); dblogic.disconnect(); - Select-anweisung „alle teams holen“ dblogic.connect (); liste = dblogic.selectStatement("SELECT * FROM team ORDER BY gruppe", Team.class); dblogic.disconnect(); - Vektor an JSP weitergeben und zur JSP gehen request.setAttribute("liste", liste); return "jsps/admin_team.jsp"; Michael Zuberbier Zaidoun Samman Carsten Martin - Designdetails lass ich an dieser Stelle mal wieder weg (sieht man ja dann) Es beinhaltet ein Table, in dem die Übersicht dargestellt wird <% List teamliste = (List) request.getAttribute("liste"); Iterator iter = teamliste.iterator(); while (iter.hasNext()) { Team team = (Team) iter.next(); out.println ( "<tr>" ); out.println ( "<td bgcolor=\"#E4E4E4\" class=\"txttable\">" + team.getLand() + "</td></td>" ); out.println ( "<td bgcolor=\"#E4E4E4\" class=\"txttable\">" + team.getGruppe() + "</td></td>" ); out.println ( "<td bgcolor=\"#E4E4E4\" class=\"txttable\">" + team.getPunkte() + "</td></td>" ); out.println ( "<td bgcolor=\"#FFFFFF\" align=\"center\"><a href=\""+request.getContextPath()+" /controller?action=Admin_Team_loeschen&land=" + team.getLand() + "\"><img ..... out.println ( "</tr>" ); } %> - Wie man sieht gibt’s am Ende jeder Zeile einen Button der das vorige Servlet wieder starten würde und ihm ein (oder mehrere) Parameter mitgibt Jetzt kann das vorige Deletestatment ausgeführt werden Die Übersicht wird neu geladen und wenn alles korrekt lief wird an die vorige JSP zurückgegangen Sonstiges: - Der Connectionpool Manager sorgt dafür, dass nach einiger Zeit der Inaktivität die Session automatisch schliesst und den Admin/User bei der nächsten Aktion zum Index wirft DbLogic, neben den Connectionpool Manager Klassen, die einzige „Nicht-Servlet“ Klasse Sie beinhaltet die Datenbank Daten (Host etc.) und hat die Methoden für die benötigten SQL Funktionen wie Connection aufbauen/abbauen, Select-, Update –und Deletestatements zur einfachen Handhabung in den Servlets Michael Zuberbier Zaidoun Samman Carsten Martin 3. MeilenStein „oleole“ Projekt Patrick Neumann Teil 8: Indexierung 1) Index Erstellen: -- Abfrage ausführen: CREATE INDEX test_spiel_index ON test_spiel (anfang); Abfrage war erfolgreich nach 312 ms. Keine Zeilen geliefert. -- Abfrage ausführen: (vor der Erstellung vom Index) SELECT team1,team2,runde FROM test_spiel where anfang between '20060603' AND '20060618' Gesamtlaufzeit der Abfrage: 47 ms. Benötigte Zeit zum Holen der Daten:734 ms. 28 Zeilen geholt. -- Abfrage ausführen: (nach der Erstellung vom Index) SELECT team1,team2,runde FROM test_spiel where anfang between '20060603' AND '20060618' Gesamtlaufzeit der Abfrage: 32 ms. Benötigte Zeit zum Holen der Daten:32 ms. 28 Zeilen geholt. Man Kann hier den Unterschied in den Ausführungszeiten (vor und nach Indexierung )bemerken. 2) Index Erstellen: -- Abfrage ausführen: CREATE INDEX test_spieler_index ON test_spieler (tore); Abfrage war erfolgreich nach 312 ms. Keine Zeilen geliefert. -- Abfrage ausführen: (vor der Erstellung vom Index) SELECT s.name,s.vorname,s.team,s.tore from test_spieler s WHERE s.tore=(SELECT max(tore) from test_spieler); Michael Zuberbier Zaidoun Samman Carsten Martin 3. MeilenStein „oleole“ Projekt Patrick Neumann Gesamtlaufzeit der Abfrage: 31 ms. Benötigte Zeit zum Holen der Daten:63 ms. 34 Zeilen geholt. -- Abfrage ausführen: (nach der Erstellung vom Index) SELECT s.name,s.vorname,s.team,s.tore from test_spieler s WHERE s.tore=(SELECT max(tore) from test_spieler); Gesamtlaufzeit der Abfrage: 47 ms. Benötigte Zeit zum Holen der Daten:47 ms. 34 Zeilen geholt. 3) Index Erstellen: -- Abfrage ausführen: CREATE INDEX test_statistik_index ON test_statistik(points); Abfrage war erfolgreich nach 313 ms. Keine Zeilen geliefert. -- Abfrage ausführen: (vor der Erstellung vom Index) SELECT s.name ,s.points FROM test_statistik s WHERE s.points = (SELECT max(points) From test_statistik) Gesamtlaufzeit der Abfrage: 46 ms. Benötigte Zeit zum Holen der Daten:32 ms. 2 Zeilen geholt. -- Abfrage ausführen: (nach der Erstellung vom Index) SELECT s.name ,s.points FROM test_statistik s WHERE s.points = (SELECT max(points) From test_statistik) Gesamtlaufzeit der Abfrage: 46 ms. Benötigte Zeit zum Holen der Daten:16 ms. 2 Zeilen geholt. Da es hier sich um nur 2 Zeilen als Ergebnis handelt ,hat der Indexierung keine bedeutende Wirkung. Michael Zuberbier Zaidoun Samman Carsten Martin 3. MeilenStein „oleole“ Projekt Patrick Neumann Teil 9: Transaktionen -- Abfrage ausführen: INSERT INTO spiel VALUES ('deutschland','portugal','platz3',null,null,'20060708'); UPDATE spiel set tore1=3,tore2=1 WHERE team1='deutschland' AND runde='platz3'; INSERT INTO tipp VALUES ('sammantipp','deutschland','portugal','platz3',2,0); DELETE FROM tipp WHERE runde='platz3'; COMMIT; WARNING: there is no transaction in progress Abfrage war erfolgreich nach 203 ms. Keine Zeilen geliefert. Nach der Überprüfung in der Datenbank konnte man feststellen,dass es nur in der Tabelle (spiel) einen Eintrag (detschland,portugal,platz3,3,1,2006-07-08) eingefügt wurde. -- Abfrage ausführen: INSERT INTO spiel VALUES ('frankreich','italien','finale',null,null,'20060709'); UPDATE spiel set tore1=6,tore2=4 WHERE team1='frankreich' AND runde='finale'; INSERT INTO tipp VALUES ('sammantipp','frankreich','italien','finale',1,0); DELETE FROM tipp WHERE runde='finale'; ROLLBACK; WARNING: there is no transaction in progress Abfrage war erfolgreich nach 47 ms. Keine Zeilen geliefert. Hier auch konnte man feststellen,dass die gesamte Abfrage zu keinen Änderungen in den Tabellen(spiel und tipp) geführt hat. Michael Zuberbier Zaidoun Samman Carsten Martin Projekt Dokumentation „oleole“ Projekt Patrick Neumann Projekt-Dokumentation 1) Aufgabenverteilung innerhalb der Gruppe („Wer hat was gemacht?“) Zaidoun = Z, Michael= M, Carsten = C, alle =A Teil 1a: Beschreibung des Projekts A Teil 1b: Entwurf des ER-Diagramms A Teil 2: Relationales Schema A Teil 3: Relationen in Oracle/Postgres A Teil 4: Datenbasen A Teil 5: SQL-Anfragen A Teil 6: Sichten Z Teil 7: Webanbindung der Datenbank M zum größten Teil Teil 8: Indexierung Z Teil 9: Transaktionen Z 2) Erfahrungen bei der Gruppenarbeit. Bei unserer Gruppe haben sich alle Mitglieder engagiert. Bei regelmäßigen Treffen wurden Probleme und die nächsten Arbeitsschritte besprochen. Alle Gruppenmitglieder waren gleichberechtigt und keiner musste mit seiner Meinung zurückstecken. Bei unterschiedlichen Meinungen wurden zuerst Ratschläge von Außen eingeholt. Falls dies nichts brachte, so wurde eine Mehrheitsentscheidung gefällt – was sich bei einem 3er Team auch anbietet. Wenn Gruppenmitglieder wegen Krankheit und ähnlichem ausfielen, so sprangen die anderen wie selbstverständlich für diesen ein. Probleme konnten offen angesprochen werden ohne dabei in irgendwelche Fettnäpfchen zu treten. Insgesamt war die Gruppe sehr ausgewogen. 3) Wie hat die Zeiteinteilung der Gruppe funktioniert? Die Gruppe hat den Zeitplan immer zusammen beim regelmäßigen Treffen verabredet. Wir haben immer versucht die Arbeiten nicht bis zum letzten Zeitpunkt hinauszuzögern. Dadurch blieb uns immer die nötige Zeit für Korrekturen. Bei Zeitengpässen durch unerwartete Ereignisse waren alle Gruppenmitglieder bereit Mehrarbeit auf sich zu nehmen um das Gruppenziel zu erreichen. Michael hatte bei der Datenbankanbindung die Arbeit freiwillig auf sich genommen, weil der dazu fähigste in unserer Gruppe war. Dieser Entschluss wurde auch Michael Zuberbier Zaidoun Samman Carsten Martin Projekt Dokumentation „oleole“ Projekt Patrick Neumann so ohne viel Murren in der Gruppe akzeptiert. Allerdings haben sich dann Zaidoun und Carsten regelmäßig über den Verlauf der Programmierarbeit, der Kontrolle des Quellcodes und um die Verbesserung der Webanbindung bemüht, so dass man hier trotzdem von Teamarbeit sprechen kann. Ja, denn wir haben wie oben erwähnt immer großzügig geplant und uns bei Termindruck alle gegenseitig unterstützt. Da konnte ein jeder dem Anderen Fragen stellen, obwohl dieser selbst im Stress war. Wir haben also bei der letzten Meile immer auch örtlich zusammengearbeitet – was sonnst meist nicht der Fall war 4) Ist ein anfänglicher Plan eingehalten worden? Die Säulen von unserem Konzept standen von Anfang bis zum Ende und auch die Umsetzung wurde nur durch Entscheidungen von Außerhalb beeinflusst Erfahrungen beim Programmieren. Beim Programmieren haben uns die Kenntnisse aus den vergangenen Vorlesungen (ALP IIV) geholfen. Auch die laufende DBS Veranstaltung war für die Datenbank und das Gesamtverständnis sehr von Nutzen. An Stellen wo wir zusammen nicht weiterkamen haben wir uns Hilfe von Außen geholt und waren uns auch nicht zu Schade den Tutor fragen. Insgesamt verlief die Programmierarbeit flüssig kostete aber viel Zeit. Auch hier ist noch einmal hervorzuheben, dass Michael hier einige Überstunden geleistet hat und an dieser Stelle besonderes Lob verdient. Abschließend ist noch zu sagen dass sich die Arbeit mit einem CVS positiv auf unsere Zusammenarbeit ausgewirkt hat. 5) Beschreibung der Implementation (Entwurf, Konzepte, auftretende Probleme,...). Der Entwurf lief ziemlich strukturiert ab, linear zu den Datenbankmodellen und Schemata konnte man quasi die Anforderungen schon dort herausfiltern. Beim Konzept waren sich schnell alle einig, die übliche JSP/Servlet Variante wieder aufzugreifen ohne irgendwelche extravaganten Sonderprogramme zu benutzen. Auftretende Probleme waren die üblichen Semantik-Fehlerquellen die erst nach dem 50maligen Einblick in einem einzigartigen „AH!“-Effekt endeten. Der Alpha bzw. Beta Test lief kontinuierlich ab, sprich Step-by-Step nach jeder fertig programmierten Routine einmal alle Möglichkeiten durchtesten. Dann noch mal nebenbei im laufenden Betrieb während der WM, dabei konnten noch 2 Fehlerquellen ausgemerzt werden. Durch die gerade beschriebenen qualitativen Tests, ergaben sich hin und wieder ein paar neue Funktionen, die aber die Spezifikation nicht über den Haufen geworfen haben. 6) Wie haben Sie Ihr Programm getestet? (Qualität/Funktion)? Michael Zuberbier Zaidoun Samman Carsten Martin Projekt Dokumentation „oleole“ Projekt Patrick Neumann Unser Projekt(OleOle) wurde unter realen Bedingungen getestet, und man konnte höchste Qualität und Robustheit feststellen. Alle Teilnehmer der Gruppe haben sich in zwei verschiedenen Rollen (User & Admin) an dem Test beteiligt. Zwei Teilnehmer (Zaidoun & Mike) haben sich registriert. Der dritte Teilnehmer (Carsten) war Admin und hatte dazugehörige Rechte. So konnte der Admin alle Mannschaften, die an der WM teilgenommen haben, und alle Spiele in der Vorrunde, und danach folgende Runden eintragen. Wenn er etwas Falsches eintragen hatte, konnte er es ohne Probleme mit Hilfe der Software löschen und neu eintragen. Die Users (Zaidoun & Mike) konnten für alle eingetragenen Spiele mehrmals bis zu dem vorherigen Tag, in dem ein Spiel stattfindet, tippen. Am ende von jedem Spieltag konnte der Admin (Carsten) die Ergebnisse, und die Tore für jeden Spieler eintragen. Wenn er fertig war, wurden die alte Spiele der Tipp-Seite automatisch gelöscht, und die Users konnten die aktuellen Ergebnissen, Gruppenstand, aktuelle Runde, Mannschaften Punkte, Anzahl der Tore, die von einem Spieler erzielt wurden, und den aktuellen Punktenstand mit der Anzahl der verschiedenen Kategorien( Sieg, Tendenz, Differenz, Verloren) jeweils von sich selbst und anderen Teilnehmer sehen. Bei Regelverstößen eines Users konnte der Admin sein Account löschen, und dieser User verlor seinen Zugang und konnte nicht mehr am Tippspiel teilnehmen. Dies war die Beschreibung von dem Funktionalentest(die unterstrichene Wörter deuten auf Attribute oder Funktionen in unserem Projekt). Ein anderer Test wurde auch ausgeführt wie z.B: - sinnlose Daten in Felder eingeben - ein zweiten User mit einem schon vorhandenen Name registrieren. - Einfügen Operation mit freien Feldern - usw.….