Løbeseddel 9: Online klassificeringssystem

for Databasestøttet Webpublicering

af Martin Elsman og Niels Hallenberg sidst rettet 15. februar, 2002


I denne øvelse skal du konstruere et online klassificeringssystem. I opgaveteksten vil vi som eksempel beskrive et system til klassificering af restauranter. Brugerne opretter selv de restauranter, som de ønsker at evaluere.

Du må selv bestemme det emne som skal klassificeres, dvs. det behøver ikke at være restauranter.

Hovedsiden for servicen som ønskes konstrueret skal give et overblik over restauranter, sorteret efter brugeres vurderinger af kvaliteten. Indgangsbilledet kan eksempelvis se således ud:

En bruger har mulighed for

  1. at rate en allerede oprettet restaurant med linket "rate it" til højre for restauranten.
  2. at oprette en ny restaurant, som derefter kan rates. Dette gøres ved at skrive navnet på den restaurant som skal rates i tekstfeltet nederst.
  3. at se alle kommentarer til en given restaurant ved at klikke på navnet på restauranten, dvs. den første kolonne "Restaurant".

Ved et klik på linket med restaurantens navn ses de kommentarer som brugere af servicen har skrevet om restauranten:

Restauranterne klassificeres løbende efter hvordan brugere af systemet vurderer restauranterne. Der er ingen brugerkontrol, og dermed heller ikke kontrol med om en bruger rater den samme restaurant flere gange. Fra hovedsiden skal der således være links til en side til indtastning af kommentar og rating for en restaurant. Der skal også være en mulighed for at rate, dvs. oprette, en ny restaurant.

I systemet som du konstruerer vælger du selv hvilket emne som skal klassificeres - det kan altså være andet end restauranter der klassificeres! Øvelsen er opdelt i de fire sædvanlige opgaver:

  1. konstruktion af datamodel
  2. opstilling af legale transaktioner
  3. tilknytning af transaktioner til web-forms (HTML-sider)
  4. konstruktion af kode til at processere ovenstående web-forms (TCL-filer)

Opgave A (30 procent) - Datamodel

Som det første led i konstruktionen af et klassificeringssystem skal du konstruere en datamodel for systemet i form af to tabeller. Den første tabel skal definere de enkelte restauranter og knytte et unikt tal til hver restaurant (du får derfor også brug for at oprette en Oracle-sequence.) Der skal som minimum gemmes et navn på hver restaurant.

Den anden tabel skal knytte brugerindtastede kommentarer og ratings til restauranterne. Der skal som minimum være mulighed for at gemme en kommentartekst, navn, email og rating.

En datamodel, helt uden detaljer, kan f.eks. se således ud:

Du skal huske at overveje

  1. hvilke felter skal hver tabel indeholde.
  2. hvilke felter skal være primær-nøgle i hver tabel. Du bør have en primær-nøgle i den tabel der svarer til Restaurant men ikke nødvendigvis i tabellen svarende til Rating.
  3. hvilken type hvert felt skal have, f.eks. varchar(...) og integer. Det er f.eks. nærliggende at have et felt rating af type integer som angiver antal stjerner restauranten får. Du kan f.eks. indsætte et check på at rating altid er et tal mellem 0 og 10:
    create table rating (
      ...
      rating integer,
      check(rating >= 0 and rating <= 10)
    );
    
  4. er der nogle felter, som du synes skal udfyldes, dvs. være not null.
  5. er der nogle felter, som du synes skal være unikke udover primær-nøglerne, dvs unique
  6. om du vil anvende references.
  7. hvis du anvender drop table skal din rækkefølge være korrekt. Antag f.eks., at du anvender to tabeller tab1 og tab2, hvor tab2 refererer til tab1, dvs. databasen checker at der til alle rækker i tab2 findes referede rækker i tab1. Så skal du slette tab2 før du sletter tab1, idet rækkerne i tab2 jo henviser til rækker i tab1.

Gem din datamodel i filen /web/login/www/oevelse9/rating.sqlhug.it.edu sammen med sql-kode for indsættelse af to restauranter med tilhørende klassificeringer i tabellerne.

Endelig skal du starte SQL*Plus på hug.it.edu ved brug af ssh og udføre sql-kommandoerne:

  SQL> @/web/login/www/oevelse9/rating.sql  
  ...
  SQL> commit;
SQL*Plus kommandoen commit sikrer at dine tabel-indsættelser bliver synlige for andre SQL*Plus vinduer og for din web-server.

Opgave B (20 procent) - Legale transaktioner

I denne opgave skal du opskrive en række legale transaktioner for klassificeringsservicen. Her er to eksempler på legale transaktioner:

Tilknytning af en kommentar og en rating til en restaurant

insert into rating (restaurant_id, text, email, fullname, rating)
values (1, 'It is a great place for a snack!', 'nh@it.edu', 'Niels Hallenberg', 9);   

Visning af restauranter, sorteret efter gennemsnitlig rating

select restaurant.restaurant_id, name, 
       avg(rating) as average, count(*) as ratings
  from restaurant, rating
 where restaurant.restaurant_id = rating.restaurant_id 
 group by restaurant.restaurant_id, name
 order by average desc;
Tilpas ovenstående transaktioner til din datamodel og opskriv eksempler på SQL-kommandoer for følgende transaktioner:
  1. oprettelse af en ny restaurant i databasen -- uden tilknyttede kommentarer
  2. visning af kommentarer og ratings for en given restaurant (select)

Det kan anbefales at du nu sikrer dig--ved brug af SQL*Plus--at de ovenstående transaktioner virker på din datamodel. Specielt er det vigtigt at select kommandoen, som benytter sig af group by funktionaliteten, virker efter hensigten; se eventuelt SQL for Web Nerds, kapitel 4 for information omkring group by funktionaliteten.

Gem SQL-kommandoerne i en fil /web/login/www/oevelse9/transaktioner.sqlhug.it.edu.

Opgave C (10 procent) - Webstrukturen

Du skal nu planlægge webstrukturen for klassificeringssystemet. Her er en skitse af hvordan systemet kan tænkes opbygget:

Kasserne i diagrammet repræsenterer det webbaserede rating-systems tilstande for hvilke HTML-kode vises i en brugers browser. Pilene repræsenterer links til en ny tilstand. På hver pil skriver vi navnet på det Tcl-program, som vi kalder samt de form-variable der overføres. Nogle pile repræsenterer transaktioner for hvilke databasen opdateres (se opgave B) og brugeren ser en ændring i sin browser.

Indgangssiden til klassificering af restauranter er vist som en kasse øverst i diagrammet, som skal implementeres som en Tcl-fil, idet restauranter hentes fra databasen. De resterende kasser (tilstande) i diagrammet skal også implementeres som Tcl-filer, da disse kasser repræsenterer dynamiske sider (d.v.s., hvad brugeren ser i sin browser afhænger af indholdet i databasen og af eventuelle form-argumenter).

Det er din opgave at gøre tegningen ovenfor færdig. Der er to pile, hvor Tcl-programmet rating_add kaldes. Du skal angive de form-variable der mangler. Derudover er der en pil, hvor der slet ikke er angivet noget program.

I den vejledende løsning indgår 4 filer:

Det anbefales, at du laver en tegning svarende til den ovenfor. På alle pile skal der være annoteret en Tcl-fil samt de form-variable, som overføres til Tcl-filen.

Til denne opgave skal du aflevere

  1. en beskrivelse af din web-struktur, som indeholder navne på de Tcl-programmer ratingsystemet anvender samt, for hver Tcl-fil de form-variable som filen forventer. Dette kan enten afleveres i en tekstfil /web/login/www/oevelse9/struktur.txt, eller som en tegning svarende til den ovenfor, hvor der på alle pile er noteret både Tcl-program og de form-variable som overføres. Hvis du vælger at aflevere en tegning, så kan du evt. scanne en tegning skrevet i hånden, og overføre filen til hug.it.edu som /web/login/www/oevelse9/struktur.gif.
Formålet med opgave C er ikke at du skal konstruere Tcl-filerne for servicen, men at du planlægger navngivningen af filerne som indgår og planlægger hvilke formvariabler der skal overføres fra en side til en anden.

Opgave D (40 procent) - Konstruktion

I denne opgave skal du konstruere Tcl-filerne for de dynamiske sider og for database-transaktionerne. Start med at konstruere de dynamiske sider for kasserne i diagrammet.

Det er en god ide at begrænse ratings til tal mellem 0 og 10. Til rapportering af ratings kan følgende tcl-procedure bruges:

proc genstars { n } {
  if { $n == 0 } { 
    return "" 
  } else {
    return "*[genstars [expr $n - 1]]"
  }   
}
Ved at kalde proceduren genstars med tallet 5 som argument, returneres en streng bestående af 5 stjerner. Rigtige stjerner såsom må meget gerne benyttes.

Vink: I filen rating.tcl har du brug for at afrunde et kommatal til et heltal. Dette kan du gøre med Tcl-kommandoen format. Du anvender en select-kommando til at beregne snittet af alle ratings pr. restaurant. Dette gennemsnit skal omformes til et heltal for at kunne anvende procedureren genstars. Antag, at kommatallet er i variablen average:

set average_int [format "%.0f" $average] 

mael@it.edu, nh@it.edu