Forum internetowe

Transkrypt

Forum internetowe
Opole, dn. 24 stycznia 2008
Politechnika Opolska
Wydział Elektrotechniki i Automatyki
pl
u
s.
p
l
Kierunek: Informatyka
.a
Systemy Baz Danych
.d
zy
sz
la
Temat:
Forum internetowe
w
Autor:
Dawid Najgiebauer
w
w
Informatyka, rok 2005/06, sem. V,
grupa lab. 7 (Cz. g. 9.15)
O P O L E
Prowadzący:
mgr inż. G. Suchacka
Ocena:
................................................
Uwagi:
.................................................
2 0 0 5
Spisy
2
1. Spisy
1.1. Spis treści
1.1.
Spis treści.................................................................................................................................................... 2
1.2.
Spis tabel..................................................................................................................................................... 2
1.3.
Spis rysunków............................................................................................................................................. 3
Opis tematu ............................................................................................................................................................ 4
2.1.
4.
Tabele i indeksy bazy danych ................................................................................................................................ 5
l
3.
Założenia .................................................................................................................................................... 4
s.
p
2.
Spisy ...................................................................................................................................................................... 2
3.1.
Użytkownicy............................................................................................................................................... 5
3.2.
Działy i wątki.............................................................................................................................................. 6
3.3.
Wypowiedzi................................................................................................................................................ 6
3.4.
Tabele ułatwiające korzystanie z forum...................................................................................................... 6
pl
u
1.
Perspektywy........................................................................................................................................................... 7
4.1.
Listy użytkowników ................................................................................................................................... 7
4.2.
Statystyki forum.......................................................................................................................................... 8
Relacje pomiędzy tabelami .................................................................................................................................. 10
6.
Wyzwalacze ......................................................................................................................................................... 12
7.
Implementacja...................................................................................................................................................... 13
zy
sz
la
Liczniki..................................................................................................................................................... 13
7.2.
Tabele ....................................................................................................................................................... 13
7.3.
Indeksy...................................................................................................................................................... 14
7.4.
Relacje ...................................................................................................................................................... 14
7.5.
Perspektywy.............................................................................................................................................. 15
7.6.
Wyzwalacze.............................................................................................................................................. 16
7.7.
Procedury i funkcje................................................................................................................................... 16
7.8.
Przykładowe dane ..................................................................................................................................... 17
.d
7.1.
Wnioski z testowania i uruchamiania .................................................................................................................. 20
w
w
8.
.a
5.
w
1.2. Spis tabel
Tabela 2.1. Struktura tabeli przechowującej dane użytkowników.................................................................................. 5
Tabela 2.2. Struktura tabeli przechowującej dane o miastach. ..................................................................................... 5
Tabela 2.3. Struktura tabeli przechowującej nazwy państw. ......................................................................................... 5
Tabela 2.4. Struktura tabeli przechowującej dane o działach i wątkach. ...................................................................... 6
Tabela 2.5. Struktura tabeli przechowującej wypowiedzi. ............................................................................................. 6
Tabela 2.6. Struktura tabeli przechowującej dane o przeczytanych wątkach. ............................................................... 6
Tabela 2.7. Struktura tabeli przechowującej dane o monitorowanych wątkach............................................................ 6
Spisy
3
Tabela 3.1. Perspektywa listy użytkowników. ................................................................................................................ 7
Tabela 3.2. Perspektywa ilości wypowiedzi wg użytkowników. ..................................................................................... 7
Tabela 3.3. Perspektywa listy ostatnio aktywnych użytkowników.................................................................................. 7
Tabela 3.4. Perspektywa statystyk forum. ...................................................................................................................... 8
Tabela 3.5. Perspektywa ilości użytkowników. .............................................................................................................. 8
Tabela 3.6. Perspektywa ilości wątków. ........................................................................................................................ 8
Tabela 3.7. Perspektywa ilości wypowiedzi. .................................................................................................................. 8
Tabela 3.8. Perspektywa najnowszych wątków.............................................................................................................. 8
Tabela 3.9. Perspektywa wątków bez odpowiedzi.......................................................................................................... 9
Tabela 4.1. Relacje pomiędzy tabelami........................................................................................................................ 10
s.
p
l
1.3. Spis rysunków
w
w
w
.d
zy
sz
la
.a
pl
u
Rysunek 4.1. Relacje pomiędzy tabelami..................................................................................................................... 10
Opis tematu
4
2. Opis tematu
Przedmiotem zadania jest baza danych do obsługi internetowego forum dyskusyjnego. Forum ma działać w oparciu o
bazę danych Oracle w wersji 8.
2.1. Założenia
s.
p
l
Baza danych musi umożliwiać gromadzenie wypowiedzi użytkowników z podziałem na kategorie (działy) oraz
tematy (wątki). Zapamiętywane muszą być takie informacje, jak:
- Nazwa działu,
- Nazwa wątku,
- Treść wypowiedzi i jej przypisanie do konkretnego wątku
- Autor wypowiedzi
- Czas opublikowania wypowiedzi
pl
u
Ponadto forum musi posiadać system logowania, by wypowiadać mogli się wyłącznie zarejestrowani jego
użytkownicy oraz nie było możliwości podszywania się pod inną osobę. Z tego względu należy przechowywać w
informacje dane dotyczące:
- Loginu (nicku) użytkownika
- Hasła do konta użytkownika
.a
Wśród społeczności forum panuje hierarchia uprawnień. Dzięki temu np. dana osoba ma prawo wyłącznie do
wypowiadania się i edytowania własnych wypowiedzi, inna do możliwości edycji i usuwania także wypowiedzi
innych osób (tzw. moderatorzy), zaś jeszcze inna grupa może mieć prawo do, na przykład zakładania i usuwania
działów (tzw. administratorzy). Dlatego każdemu użytkownikowi należy przypisać wartość odpowiadającą jego
uprawnieniom.
zy
sz
la
Wśród uczestników forum istnieje także inna jeszcze hierarchia oparta o dane statystyczne, jak np. czas, od kiedy
dana osoba uczestniczy i wypowiada się na Forum.
Od strony społecznej często w celu większej integracji i zmniejszenia anonimowości osób dodaje się informacje o
stronach WWW użytkowników, ich adresach e-mail oraz np. miejscowości, w której zamieszkują. Baza danych
powinna umożliwiać gromadzenie wszystkich powyższych elementów.
Kluczowym aspektem jest także wygoda użytkowania bazy danych. Dlatego musi ona przechowywać informacje
umożliwiające wskazywanie użytkownikowi, które wątki zostały już przez niego przeczytane, a które nie. Warto też,
by mógł on mieć możliwość otrzymywania powiadomień na adres e-mail o nowych wypowiedziach w wątkach,
które szczególnie go interesują.
w
w
w
.d
Tabela musi też posiadać własny system nadawania identyfikatorów, aby nie obciążać tym użytkowników bazy.
Liczniki muszą nadawać kolejne wartości z całego dostępnego przedziału liczbowego.
Tabele i indeksy bazy danych
5
3. Tabele i indeksy bazy danych
Użyte skróty:
- PK – klucz główny
- FK – klucz obcy
- I – indeks
- UI – indeks unikalny
- nazwa_licznika
3.1. Użytkownicy
name
pass
status
regtime
logtime
email
www
signature
city
Identyfikator użytkownika w bazie
Nazwa (login/nick) użytkownika
Hasło do konta użytkownika
Wartość określająca uprawnienia użytkownika:
- 1 – administrator
- 2 – moderator
- 3 – użytkownik o rozszerzonych uprawnieniach (VIP)
- 4 – zwykły użytkownik
Data zarejestrowania się użytkownika
Data ostatniego logowania użytkownika
Adres e-mail użytkownika
Adres strony WWW użytkownika
Podpis użytkownika dodawany do każdej jego wypowiedzi
Miasto, z jakiego pochodzi użytkownik
zy
sz
la
data
data
znakowe
znakowe
tekstowe
liczbowe (FK)
Opis
pl
u
Typ danych
liczbowe (PK)
userID_sequence
znakowe (UI)
znakowe
liczbowe
.a
users
Nazwa pola
id
s.
p
l
Tabela 2.1. Struktura tabeli przechowującej dane użytkowników.
Tabela 2.2. Struktura tabeli przechowującej dane o miastach.
cities
Nazwa pola
id
.d
Typ danych
liczbowe (PK)
cityID_sequence
znakowe (I)
liczbowe (FK)
w
name
country
Opis
Identyfikator miasta w bazie
Nazwa miasta
Kraj, w jakim położone jest miasto
w
Tabela 2.3. Struktura tabeli przechowującej nazwy państw.
w
countrys
Nazwa pola
id
name
Typ danych
liczbowe (PK)
countryID_sequence
znakowe (I)
Opis
Identyfikator państwa w bazie
Nazwa państwa
Tabele i indeksy bazy danych
6
3.2. Działy i wątki
Tabela 2.4. Struktura tabeli przechowującej dane o działach i wątkach.
threads
Nazwa pola
parent
id
order
Typ danych
liczbowe (FK, I)
threadID_sequence
liczbowe (PK)
liczbowe (I)
name
desc
status
Identyfikator rodzica wątku/działu (0 = root)
Identyfikator działu/wątku
Wartość określająca porządek, w jakim mają być wyświetlane
działy/wątki
Nazwa (tytuł) działu/wątku
Krótki opis działu/wątku
Identyfikuje rekord:
- 1 – dział otwarty
- 2 – dział zamknięty (nie można publikować nowych wątków)
- 3 – wątek otwarty
- 4 – wątek zamknięty (nie można publikować nowych wypowiedzi)
s.
p
l
znakowe
tekstowe
liczbowe
Opis
Tabela 2.5. Struktura tabeli przechowującej wypowiedzi.
Opis
Identyfikator wątku, którego wypowiedź dotyczy
Identyfikator wypowiedzi
Wartość określająca autora wypowiedzi
Adres IP komputera, z którego dokonano dodania wypowiedzi
Data opublikowania wypowiedzi
Treść wypowiedzi
zy
sz
la
id
user
ip
time
text
Typ danych
liczbowe (FK, I)
postID_sequence
liczbowe (PK)
liczbowe (FK)
znakowe
data (I)
tekstowe
.a
posts
Nazwa pola
parent
pl
u
3.3. Wypowiedzi
.d
3.4. Tabele ułatwiające korzystanie z forum
Tabela 2.6. Struktura tabeli przechowującej dane o przeczytanych wątkach.
Typ danych
liczbowe (PK, FK)
liczbowe (PK, FK, I)
w
w
readed
Nazwa pola
topicid
userid
Opis
Identyfikator wątku
Identyfikator użytkownika
w
Tabela 2.7. Struktura tabeli przechowującej dane o monitorowanych wątkach.
monitoring
Nazwa pola
Typ danych
topicid
liczbowe (PK, FK)
userid
liczbowe (PK, FK, I)
Opis
Identyfikator wątku
Identyfikator użytkownika
Perspektywy
7
4. Perspektywy
Ze względu na brak możliwości parametryzacji perspektyw, stworzono wyłącznie najbardziej ogólne.
4.1. Listy użytkowników
Tabela 3.1. Perspektywa listy użytkowników.
UsersView
s.
p
name
status
regtime
logtime
email
www
signature
city
country
wypowiedzi
l
Nazwa wyniku
.a
name
status
regtime
logtime
email
www
signature
name
name
wypowiedzi
Tabela lub widok
źródłowy
users
users
users
users
users
users
users
cities
countries
UserPostsCountView
pl
u
Nazwa pola
zy
sz
la
Powyższa perspektywa powinna zwracać listę wszystkich użytkowników posortowanych wg ich nazw.
Tabela 3.2. Perspektywa ilości wypowiedzi wg użytkowników.
UserPostsCountView
Tabela lub widok
Nazwa pola
źródłowy
user
posts
count(*)
posts
Nazwa wyniku
userid
wypowiedzi
.d
Powyższa perspektywa powinna zwracać liczbę wypowiedzi wszystkich użytkowników.
w
w
w
Tabela 3.3. Perspektywa listy ostatnio aktywnych użytkowników.
ActiveUsersView
Tabela lub widok
Nazwa pola
źródłowy
name
users
logtime
users
Nazwa wyniku
name
logtime
Powyższa perspektywa powinna zwracać listę nazw użytkowników oraz datę ich aktywności posortowaną od
użytkownika aktywnego najpóźniej (najpóźniejsza data).
Perspektywy
8
4.2. Statystyki forum
Tabela 3.4. Perspektywa statystyk forum.
ForumStatView
Tabela lub widok
źródłowy
UsersCountView
ThreadsCountView
PostsCountView
Nazwa pola
UsersCount
ThreadsCount
PostsCount
Nazwa wyniku
UsersCount
ThreadsCount
PostsCount
Powyższa perspektywa powinna przedstawiać liczbę użytkowników, wątków oraz wypowiedzi dokonanych na
całym forum.
UsersCountView
count(*)
Tabela lub widok
źródłowy
users
Nazwa wyniku
count
pl
u
Nazwa pola
s.
p
l
Tabela 3.5. Perspektywa ilości użytkowników.
Powyższa perspektywa powinna przedstawić ilość zarejestrowanych użytkowników.
Tabela 3.6. Perspektywa ilości wątków.
zy
sz
la
.a
ThreadsCountView
Tabela lub widok
Nazwa pola
źródłowy
count(*)
threads
Nazwa wyniku
count
Powyższa perspektywa powinna przedstawić ilość wątków.
Tabela 3.7. Perspektywa ilości wypowiedzi.
PostsCountView
Nazwa pola
.d
count(*)
Tabela lub widok
źródłowy
posts
Nazwa wyniku
count
w
Powyższa perspektywa powinna przedstawić ilość wypowiedzi.
w
w
Tabela 3.8. Perspektywa najnowszych wątków.
NewestThreadsView
Tabela lub widok
Nazwa pola
źródłowy
id
threads
name
threads
MAX(time)
posts
Nazwa wyniku
id
name
LastPostTime
Powyższa perspektywa powinna przedstawić listę wątków (ich id oraz nazwy) wraz z datą ostatniej wypowiedzi w
każdym z nich posortowaną od wątku zawierającego najmłodszą ostatnią wypowiedź.
Perspektywy
9
Tabela 3.9. Perspektywa wątków bez odpowiedzi.
ThreadsWithoutAnswerView
Tabela lub widok
Nazwa pola
źródłowy
parent
posts
name
threads
Nazwa wyniku
id
name
w
w
w
.d
zy
sz
la
.a
pl
u
s.
p
l
Powyższa perspektywa powinna przedstawić listę wątków (ich id oraz nazwy), w których znajduje się tylko jedna
wypowiedź (brak odpowiedzi) posortowaną od najnowszego wątku.
Relacje pomiędzy tabelami
10
zy
sz
la
.a
pl
u
s.
p
l
5. Relacje pomiędzy tabelami
Rysunek 4.1. Relacje pomiędzy tabelami.
Tabela 4.1. Relacje pomiędzy tabelami.
Tabela.pole
rodzica
users
.id
Tabela.pole
dziecka
monitoring
.userid
threads
.id
monitoring
.topicid
users
.id
readed
.userid
FK_READED_REFERENCE_THREADS
threads
.id
readed
.topicid
FK_THREADS_REFERENCE_THREADS
threads
.id
threads
.parent
FK_POSTS_REFERENCE_USERS
users
.id
posts
.user
.d
Nazwa relacji
w
FK_MONITORI_REFERENCE_USERS
w
FK_MONITORI_REFERENCE_THREADS
w
FK_READED_REFERENCE_USERS
Typ relacji
kaskadowa
przy
usuwaniu
kaskadowa
przy
usuwaniu
kaskadowa
przy
usuwaniu
kaskadowa
przy
usuwaniu
kaskadowa
przy
usuwaniu
restrykcyjna
Opis
Wskazują na monitorowane
wątki przez użytkownika
Wskazują na przeczytane
wątki przez użytkownika
Wskazuje hierarchię działów i
wątków w działach
Wskazuje na autora
wypowiedzi
Relacje pomiędzy tabelami
Nazwa relacji
FK_POSTS_REFERENCE_THREADS
FK_USERS_REFERENCE_CITIES
Tabela.pole
dziecka
posts
.parent
user
.city
city
.country
Typ relacji
restrykcyjna
restrykcyjna
kaskadowa
Opis
Wskazuje na przypisanie
wypowiedzi do wątku
Wskazuje na miasto
zamieszkania użytkownika
Wskazuje na państwo, w
jakim zlokalizowane jest
miasto
w
w
w
.d
zy
sz
la
.a
pl
u
s.
p
l
FK_CITIES_REFERENCE_COUNTRIE
Tabela.pole
rodzica
threads
.id
cities
.id
countries
.id
11
Wyzwalacze
12
6. Wyzwalacze
Szczególnym przypadkiem jest sytuacja dodania nowego postu. W tym momencie z tabeli readed powinny być
wykasowane wszystkie pozycje dotyczące wątku, do którego został dopisany post. Jednocześnie powinien być
dodany wpis dla tego wątku i dla użytkownika dodającego post. Nazwa wyzwalacza realizującego to zadanie to
NEW_POST_TRIGGER.
w
w
w
.d
zy
sz
la
.a
pl
u
s.
p
l
Również w takiej sytuacji warto byłoby powiadomić wszystkich monitorujących wątek o pojawieniu się nowego
postu. Niestety przekracza to funkcjonalność bazy danych Oracle, stąd nie ma takiego wyzwalacza.
Implementacja
13
7. Implementacja
7.1. Liczniki
CREATE SEQUENCE "cityID_sequence";
CREATE SEQUENCE "countryID_sequence";
CREATE SEQUENCE "postID_sequence";
CREATE SEQUENCE "threadID_sequence";
7.2. Tabele
CREATE TABLE "cities" (
"id"
NUMBER
"name"
VARCHAR2(255)
"country"
NUMBER
CONSTRAINT PK_CITIES PRIMARY KEY ("id")
);
pl
u
NOT NULL,
NOT NULL,
.a
zy
sz
la
CREATE TABLE "countries" (
"id"
NUMBER
"name"
VARCHAR2(255)
CONSTRAINT PK_COUNTRIES PRIMARY KEY ("id")
);
NOT NULL,
NOT NULL,
NOT NULL,
CREATE TABLE "monitoring" (
"topicid"
NUMBER
NOT NULL,
"userid"
NUMBER
NOT NULL,
CONSTRAINT PK_MONITORING PRIMARY KEY ("topicid", "userid")
);
NUMBER
NUMBER
NUMBER
CHAR(15),
DATE
LONG
PRIMARY KEY ("id")
.d
CREATE TABLE "posts" (
"parent"
"id"
"user"
"ip"
"time"
"text"
CONSTRAINT PK_POSTS
);
NOT NULL,
NOT NULL,
NOT NULL,
NOT NULL,
NOT NULL,
w
w
CREATE TABLE "readed" (
"topicid"
NUMBER
NOT NULL,
"userid"
NUMBER
NOT NULL,
CONSTRAINT PK_READED PRIMARY KEY ("topicid", "userid")
);
w
CREATE TABLE "threads" (
"parent"
NUMBER,
"id"
NUMBER
"order"
NUMBER(3)
"name"
VARCHAR2(255)
"DESC"
LONG,
"status"
NUMBER(1)
CONSTRAINT PK_THREADS PRIMARY KEY ("id")
);
CREATE TABLE "users"
"id"
"name"
"pass"
"status"
"regtime"
NOT NULL,
NOT NULL,
NOT NULL,
NOT NULL,
(
NUMBER
VARCHAR2(50)
VARCHAR2(50)
NUMBER(1)
DATE,
s.
p
l
CREATE SEQUENCE "userID_sequence";
NOT
NOT
NOT
NOT
NULL,
NULL,
NULL,
NULL,
Implementacja
"logtime"
"email"
"www"
"signature"
"city"
CONSTRAINT PK_USERS
14
DATE,
VARCHAR2(255),
VARCHAR2(255),
LONG,
NUMBER,
PRIMARY KEY ("id")
);
7.3. Indeksy
CREATE INDEX "City_index" ON "cities" (
"name" ASC
);
CREATE UNIQUE INDEX "Country_index" ON "countries" (
"name" ASC
);
s.
p
l
CREATE INDEX "userid_index2" ON "monitoring" (
"userid" ASC
);
CREATE INDEX "time_index" ON "posts" (
"time" ASC
);
pl
u
CREATE INDEX "parent_index" ON "posts" (
"parent" ASC
);
zy
sz
la
CREATE INDEX "Order_Index" ON "threads" (
"order" ASC
);
.a
CREATE INDEX "userid_index" ON "readed" (
"userid" ASC
);
CREATE INDEX "parent_index2" ON "threads" (
"parent" ASC
);
CREATE UNIQUE INDEX "username_index" ON "users" (
"name" ASC
);
.d
7.4. Relacje
w
ALTER TABLE "cities"
ADD CONSTRAINT FK_CITIES_REFERENCE_COUNTRIE FOREIGN KEY ("country")
REFERENCES "countries" ("id")
ON DELETE cascade;
w
w
ALTER TABLE "monitoring"
ADD CONSTRAINT FK_MONITORI_REFERENCE_USERS FOREIGN KEY ("userid")
REFERENCES "users" ("id")
ON DELETE cascade;
ALTER TABLE "monitoring"
ADD CONSTRAINT FK_MONITORI_REFERENCE_THREADS FOREIGN KEY ("topicid")
REFERENCES "threads" ("id")
ON DELETE cascade;
ALTER TABLE "posts"
ADD CONSTRAINT FK_POSTS_REFERENCE_THREADS FOREIGN KEY ("parent")
REFERENCES "threads" ("id")
ON DELETE cascade;
ALTER TABLE "posts"
ADD CONSTRAINT FK_POSTS_REFERENCE_USERS FOREIGN KEY ("user")
REFERENCES "users" ("id");
Implementacja
15
ALTER TABLE "readed"
ADD CONSTRAINT FK_READED_REFERENCE_USERS FOREIGN KEY ("userid")
REFERENCES "users" ("id")
ON DELETE cascade;
ALTER TABLE "readed"
ADD CONSTRAINT FK_READED_REFERENCE_THREADS FOREIGN KEY ("topicid")
REFERENCES "threads" ("id")
ON DELETE cascade;
ALTER TABLE "threads"
ADD CONSTRAINT FK_THREADS_REFERENCE_THREADS FOREIGN KEY ("parent")
REFERENCES "threads" ("id")
ON DELETE cascade;
ALTER TABLE "users"
ADD CONSTRAINT FK_USERS_REFERENCE_CITIES FOREIGN KEY ("city")
REFERENCES "cities" ("id");
s.
p
l
7.5. Perspektywy
.a
zy
sz
la
CREATE OR REPLACE VIEW "NewestThreadsView" AS
SELECT
"posts"."parent" threadID,
max("posts"."time") LastPostTime
FROM
"posts"
GROUP BY
"posts"."parent"
ORDER BY
LastPostTime DESC;
pl
u
CREATE OR REPLACE VIEW "ActiveUsersView" AS
SELECT
"users"."name",
"users"."logtime"
FROM
"users"
ORDER BY
"users"."logtime" DESC;
CREATE OR REPLACE VIEW "UsersCountView" AS
SELECT
COUNT(*) count
FROM
"users";
.d
CREATE OR REPLACE VIEW "PostsCountView" AS
SELECT
COUNT(*) count
FROM
"posts";
w
w
w
CREATE OR REPLACE VIEW "ThreadCountView" AS
SELECT
COUNT(*) count
FROM
"threads"
WHERE
"status" >= 3;
CREATE OR REPLACE VIEW "ForumStatView" AS
SELECT
"UsersCountView".count UsersCount,
"ThreadCountView".count ThreadsCount,
"PostsCountView".count PostsCount
FROM
"UsersCountView",
"ThreadCountView",
"PostsCountView";
CREATE OR REPLACE VIEW "ThreadsWithoutAnswerView" AS
SELECT
"posts"."parent" threadID
FROM
Implementacja
16
"posts"
HAVING
COUNT(*) = 1
GROUP BY
"posts"."parent";
s.
p
pl
u
zy
sz
la
.a
CREATE OR REPLACE VIEW "UsersView" AS
SELECT
"users"."name",
"users"."status",
"users"."regtime",
"users"."logtime",
"users"."email",
"users"."www",
"users"."signature",
"cities"."name" city,
"countries"."name" country,
"UserPostsCountView".wypowiedzi
FROM
"users",
"cities",
"countries",
"UserPostsCountView"
WHERE
"cities"."id" = "users"."city"
AND "countries"."id" = "cities"."country"
AND "UserPostsCountView".userid = "users"."id"
ORDER BY
"users"."name" ASC;
l
CREATE OR REPLACE VIEW "UserPostsCountView" AS
SELECT
"posts"."user" userid,
COUNT(*) wypowiedzi
FROM
"posts"
GROUP BY
"posts"."user"
UNION
SELECT
"id" userid,
0 wypowiedzi
FROM
"users"
WHERE
NOT EXISTS (SELECT "user" FROM "posts" WHERE "user"="users"."id");
7.6. Wyzwalacze
w
w
.d
CREATE TRIGGER NEW_POST_TRIGGER AFTER INSERT
ON "posts"
FOR EACH ROW
BEGIN
DELETE FROM "readed" WHERE "topicid"=:NEW."parent";
INSERT INTO "readed" VALUES (:NEW."parent",:NEW."user");
END;
/
w
7.7. Procedury i funkcje
CREATE OR REPLACE FUNCTION status(tid number) RETURN VARCHAR IS
BEGIN
DECLARE
res NUMBER;
opis VARCHAR(255);
CURSOR kursor IS
SELECT "status" FROM "threads" WHERE "id"=tid;
BEGIN
OPEN kursor;
FETCH kursor INTO res;
CLOSE kursor;
Implementacja
17
IF res=1 THEN opis:='Dzial otwarty';
ELSIF res=2 THEN opis:='Dzial zamkniety';
ELSIF res=3 THEN opis:='Watek otwarty';
ELSIF res=4 THEN opis:='Watek zamkniety';
ELSE res:=1;
END IF;
RETURN(opis);
END;
.d
zy
sz
la
.a
pl
u
s.
p
CREATE OR REPLACE PROCEDURE rebuild_users_logtime IS
BEGIN
DECLARE
CURSOR user_last_time_cursor IS
SELECT
max("time"),
"user"
FROM
"posts"
GROUP BY
"user";
user_id NUMBER;
CURSOR user_logtime_cursor IS
SELECT
"logtime"
FROM
"users"
WHERE
"id"=user_id;
user_last_time DATE;
user_logtime DATE;
BEGIN
OPEN user_last_time_cursor;
LOOP
FETCH user_last_time_cursor INTO user_last_time,user_id;
EXIT when user_last_time_cursor%NOTFOUND;
OPEN user_logtime_cursor;
FETCH user_logtime_cursor INTO user_logtime;
CLOSE user_logtime_cursor;
IF user_logtime<user_last_time THEN
UPDATE
"users"
SET
"logtime"=user_last_time
WHERE
"id"=user_id;
END IF;
END LOOP;
COMMIT;
CLOSE user_last_time_cursor;
END;
END;
/
l
END;
/
w
w
7.8. Przykładowe dane
INTO
INTO
INTO
INTO
INTO
"countries"
"countries"
"countries"
"countries"
"countries"
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
"cities"
w
INSERT
INSERT
INSERT
INSERT
INSERT
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
("countryID_sequence".NEXTVAL,'Polska');
("countryID_sequence".NEXTVAL,'Niemcy');
("countryID_sequence".NEXTVAL,'Czechy');
("countryID_sequence".NEXTVAL,'Slowacja');
("countryID_sequence".NEXTVAL,'USA');
("cityID_sequence".NEXTVAL,'Zory',1);
("cityID_sequence".NEXTVAL,'Katowice',1);
("cityID_sequence".NEXTVAL,'Opole',1);
("cityID_sequence".NEXTVAL,'Warszawa',1);
("cityID_sequence".NEXTVAL,'Wolsztyn',1);
("cityID_sequence".NEXTVAL,'Berlin',2);
("cityID_sequence".NEXTVAL,'Frankfurt',2);
("cityID_sequence".NEXTVAL,'Koln',2);
("cityID_sequence".NEXTVAL,'Bratyslawa',3);
("cityID_sequence".NEXTVAL,'Gorne Teplice',4);
("cityID_sequence".NEXTVAL,'Waszyngton',5);
("cityID_sequence".NEXTVAL,'New York',5);
Implementacja
18
INSERT INTO "cities" VALUES ("cityID_sequence".NEXTVAL,'Ohayo',5);
pl
u
s.
p
l
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Dzyszla', 'Dzyszla', 1, SYSDATE, NULL,
'[email protected]','www.dzyszla.aplus.pl','mgr inz. Dzyszla',1);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Kaczka', 'kaczka', 3, SYSDATE, NULL,
'[email protected]','www.prezydent.gov.pl','Prezydent RP',4);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Winger', 'win', 4, SYSDATE, NULL, NULL,
NULL,NULL,5);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Koltom', 'pkp', 2, SYSDATE, NULL, NULL,
'www.koltom.prv.pl','Koltom',1);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'smolki', 'smolki', 2, SYSDATE, NULL,
'[email protected]','www.idg.pl','Michal Smolinski',4);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Schreder', 'gotmituns', 4, SYSDATE, NULL,
NULL,'www.gov.de','Deutschland, Deutschland uber Alles',6);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Pepicek1', 'p1', 4, SYSDATE, NULL, NULL,
NULL,NULL,9);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Pepicek2', 'p2', 4, SYSDATE, NULL, NULL,
NULL,NULL,9);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'PepicekSK', 'psk', 4, SYSDATE, NULL, NULL,
NULL,NULL,10);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Bush', 'bush', 3, SYSDATE, NULL, NULL,
NULL,NULL,13);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Bush jr', 'bushjr', 3, SYSDATE, NULL,
NULL, NULL,NULL,11);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Emigrant', 'polak', 4, SYSDATE, NULL,
NULL, NULL,NULL,12);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Emigrant1', 'polak1', 4, SYSDATE, NULL,
NULL, NULL,NULL,12);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Emigrant2', 'polak2', 3, SYSDATE, NULL,
NULL, NULL,NULL,12);
INSERT INTO "users" VALUES ("userID_sequence".NEXTVAL, 'Emigrant3', 'polak3', 4, SYSDATE, NULL,
NULL, NULL,NULL,12);
.d
zy
sz
la
.a
INSERT INTO "threads" VALUES (NULL,”threadID_sequence”.NEXTVAL,1,'Ksiega gosci','Wpisz sie!',3);
INSERT INTO "threads" VALUES (NULL,”threadID_sequence”.NEXTVAL,100,'Jarmark','chcesz cos kupic,
sprzedac, zamienic? Wejdz tutaj!',1);
INSERT INTO "threads" VALUES (2,”threadID_sequence”.NEXTVAL,100,'Kupie','Oferty kupna',1);
INSERT INTO "threads" VALUES (2,”threadID_sequence”.NEXTVAL,101,'Sprzedam','Oferty
sprzedazy',1);
INSERT INTO "threads" VALUES (2,”threadID_sequence”.NEXTVAL,102,'Zamienie','Oferty
zamiany',1);
INSERT INTO "threads" VALUES (NULL,”threadID_sequence”.NEXTVAL,255,'Wolna strefa','Dyskusje o
wszystkim',1);
INSERT INTO "threads" VALUES (3,”threadID_sequence”.NEXTVAL,200,'Kupie lodz
podwodna','',3);
INSERT INTO "threads" VALUES (3,”threadID_sequence”.NEXTVAL,200,'Bomba atomowa
10MT','',3);
INSERT INTO "threads" VALUES (4,”threadID_sequence”.NEXTVAL,200,'Komplet
terrorystow','',3);
INSERT INTO "threads" VALUES (4,”threadID_sequence”.NEXTVAL,200,'Vodka, vodka,
vodka!!!','',4);
INSERT INTO "threads" VALUES (5,”threadID_sequence”.NEXTVAL,200,'Siekierke na
kijek! PILNE!!!','',3);
INSERT INTO "threads" VALUES (6,”threadID_sequence”.NEXTVAL,200,'Precz z
Kaczynskim!','',4);
w
w
w
INSERT INTO "posts" VALUES
wpis! Zapraszam wszystkich
INSERT INTO "posts" VALUES
sie wpisal!');
INSERT INTO "posts" VALUES
Fajne Forum!');
INSERT INTO "posts" VALUES
zamach na IV RP?');
INSERT INTO "posts" VALUES
here!');
INSERT INTO "posts" VALUES
INSERT INTO "posts" VALUES
juz internet?!?');
(1,”postID_sequence”.NEXTVAL,1,'217.126.12.1',SYSDATE,'To jest pierwszy
do wpisywania sie!');
(1,”postID_sequence”.NEXTVAL,4,'192.128.1.1',SYSDATE,'Koltom tu byl i
(1,”postID_sequence”.NEXTVAL,5,'19.12.10.10',SYSDATE,'Hej tu winger!
(1,”postID_sequence”.NEXTVAL,2,'0.0.0.0',SYSDATE,'Hmm... Czy to nie
(1,”postID_sequence”.NEXTVAL,6,'221.5.23.98',SYSDATE,'Ja wohl! Ich war
(1,”postID_sequence”.NEXTVAL,10,'1.10.0.1',SYSDATE,'USA love you!!!');
(1,”postID_sequence”.NEXTVAL,14,'1.112.11.0',SYSDATE,'To w Polsce jest
INSERT INTO "posts" VALUES (7,”postID_sequence”.NEXTVAL,11,'2.38.45.6',SYSDATE,'Jakby ktos miec
lodz podwodna, to ja kupic czerwona lub zolta!');
INSERT INTO "posts" VALUES (8,”postID_sequence”.NEXTVAL,6,'221.5.23.98',SYSDATE,'Wir haben kaine
Atom-bombe :( Aber wir wolte etwas kaufen aus USA.');
INSERT INTO "posts" VALUES (8,”postID_sequence”.NEXTVAL,10,'1.10.0.1',SYSDATE,'We have 10 boms!
$100 000 per one only!');
INSERT INTO "posts" VALUES (8,”postID_sequence”.NEXTVAL,6,'221.5.23.98',SYSDATE,'Das ist zu teuer!
Wir kann du nich mehr, als 10 000 Euro geben!');
Implementacja
19
INSERT INTO "posts" VALUES (8,”postID_sequence”.NEXTVAL,10,'1.10.0.1',SYSDATE,'No problem! We have
something extra from Iraq!');
INSERT INTO "posts" VALUES (9,”postID_sequence”.NEXTVAL,15,'1.160.6.101',SYSDATE,'Tu w ameryce
ksztalci sie pod okiem CIA tajna grupa terrorystow gotowa do walki w kazdej chwili. Jesli komus
potrzebna, to sprzedamy!');
INSERT INTO "posts" VALUES (10,”postID_sequence”.NEXTVAL,8,'133.130.130.1',SYSDATE,'Dobrydzen! Mam
Vodka, tanio! Jak ktos chce, to pisze na moj e-mail!');
INSERT INTO "posts" VALUES (10,”postID_sequence”.NEXTVAL,1,'217.126.12.1',SYSDATE,'Przepraszam,
temat zostanie zamkniety, bo wodka pochodzila z nielegalnego przemytu!');
INSERT INTO "posts" VALUES (11,”postID_sequence”.NEXTVAL,15,'1.16.142.12',SYSDATE,'Postarzalem
sie, a tu w Ameryce nie maja kijkow. Place koszta przesylki!!!');
INSERT INTO "posts" VALUES (12,”postID_sequence”.NEXTVAL,3,'217.6.112.111',SYSDATE,'Spieprzaj
dziadu!');
INSERT INTO "posts" VALUES (12,”postID_sequence”.NEXTVAL,2,'0.0.0.0',SYSDATE,'Czuje sie
obrazony!');
INSERT INTO "posts" VALUES (12,”postID_sequence”.NEXTVAL,1,'217.126.12.1',SYSDATE,'nie obrazamy
innych uczestnikow Forum!!!');
INTO
INTO
INTO
INTO
INTO
INTO
INTO
"readed"
"readed"
"readed"
"readed"
"readed"
"readed"
"readed"
(1,1);
(1,4);
(1,5);
(8,6);
(10,8);
(12,2);
(12,3);
w
w
w
.d
zy
sz
la
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
(1,1);
(1,4);
(7,11);
(9,1);
(9,6);
(9,10);
(11,15);
(13,15);
l
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
s.
p
"monitoring"
"monitoring"
"monitoring"
"monitoring"
"monitoring"
"monitoring"
"monitoring"
"monitoring"
pl
u
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
.a
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
Wnioski z testowania i uruchamiania
20
8. Wnioski z testowania i uruchamiania
Podczas wydania wszystkich powyższych poleceń oraz wprowadzenia danych testowych, system nie wygenerował
żadnych komunikatów o błędach ani ostrzeżeń.
Podczas wstawiania nowego postu, zawartość tabeli readed jest poprawnie modyfikowana przez wyzwalacz tabeli
posts.
Przed przystąpieniem do pracy warto zdefiniować format wyświetlania kolumn. Wykonano następujące polecenia:
SET linesize 100
COLUMN name FORMAT A20
SET pagesize 100
Rozpoczynając pracę, warto znać główny podział forum. W tym celu wydamy polecenie:
SELECT
l
"id","name","status"
s.
p
FROM
"threads"
WHERE
"parent" IS NULL
ORDER BY
"order" ASC;
name
status
-------------------- ---------Ksiega gosci
3
Jarmark
1
Wolna strefa
1
.a
id
---------1
2
6
pl
u
W wyniku otrzymano następujący rezultat:
SELECT
zy
sz
la
Status określa, czy mamy do czynienia z działem (1 lub 2), czy z wątkiem (3 lub 4). W powyższym przykładzie
Jarmark jest działem, więc chcąc wyświetlić jego zawartość wykonujemy analogiczne do poprzedniego polecenie:
"id","name","status"
FROM
"threads"
WHERE
"parent"=2
ORDER BY
"order" ASC;
name
status
-------------------- ---------Kupie
1
Sprzedam
1
Zamienie
1
w
id
---------3
4
5
.d
Należy zwrócić uwagę, że zmienił się warunek na parent=2, co oznacza, że chcemy wyświetlić działy/wątki, które
należą do działu 2 (por. poprzedni rysunek). W wyniku zapytania otrzymujemy:
w
w
Jeśli chcemy przejść do wątku (status 3 lub 4, np. Ksiega gosci o ID=1), to w celu wyświetlenia jego zawartości
wykonujemy polecenie:
Wnioski z testowania i uruchamiania
21
SELECT
"users"."name" AS Autor,
"users"."regtime",
"UserPostsCountView".wypowiedzi,
"posts"."ip",
"posts"."time",
"posts"."text",
"users"."signature"
FROM
"users",
"posts",
"UserPostsCountView"
WHERE
"posts"."user"="users"."id" AND
"posts"."user"="UserPostsCountView".userid AND
"posts"."parent"=1
ORDER BY
"posts"."time";
W wyniku takiego zapytania dostaniemy zawartość wątku Księga gości, wraz z autorem wypowiedzi, jego czasem
rejestracji, ilością udzielonych wypowiedzi oraz adresem IP, z którego napisał:
pl
u
s.
p
l
AUTOR
regtime
WYPOWIEDZI ip
time
-------------------------------------------------- --------- ---------- --------------- --------text
-------------------------------------------------------------------------------signature
-------------------------------------------------------------------------------Dzyszla
19-DEC-05
3 217.126.12.1
19-DEC-05
To jest pierwszy wpis! Zapraszam wszystkich do wpisywania sie!
mgr inz. Dzyszla
19-DEC-05
2 192.128.1.1
19-DEC-05
Kaczka
Hmm... Czy to nie zamach na IV RP?
Prezydent RP
19-DEC-05
2 0.0.0.0
19-DEC-05
19-DEC-05
2 192.128.1.1
19-DEC-05
smolki
Hej tu winger! Fajne Forum!
Michal Smolinski
19-DEC-05
1 19.12.10.10
19-DEC-05
Schreder
Ja wohl! Ich war here!
Deutschland, Deutschland uber Alles
19-DEC-05
3 221.5.23.98
19-DEC-05
Bush
USA love you!!!
19-DEC-05
3 1.10.0.1
19-DEC-05
19-DEC-05
1 1.112.11.0
19-DEC-05
.d
zy
sz
la
Koltom
Koltom tu byl i sie wpisal!
Koltom
.a
Koltom
Koltom tu byl i sie wpisal!
Koltom
w
w
Emigrant2
To w Polsce jest juz internet?!?
W prosty sposób możemy sprawdzić statystyki forum:
w
SELECT * FROM "ForumStatView";
A w wyniku otrzymamy liczbę użytkowników, liczbę wątków oraz liczbę wypowiedzi:
USERSCOUNT THREADSCOUNT POSTSCOUNT
---------- ------------ ---------15
7
20
Ciekawą może lista wszystkich użytkowników forum, którą otrzymamy korzystając ze wcześniej zdefiniowanego
widoku:
SELECT * FROM "UsersView";
W wyniku otrzymamy alfabetyczną listę użytkowników:
Wnioski z testowania i uruchamiania
22
name
status regtime
logtime
email
--------------- ---------- --------- --------- ------------------------signature
CITY
COUNTRY
---------------------------------------- --------------- --------------Bush
3 19-DEC-05
Ohayo
USA
Bush jr
www
--------------------WYPOWIEDZI
---------3
3 19-DEC-05
Waszyngton
Dzyszla
mgr inz. Dzyszla
1 19-DEC-05
Emigrant
4 19-DEC-05
Zory
Emigrant1
USA
1
[email protected]
Polska
www.dzyszla.aplus.pl
3
New York
USA
0
New York
USA
0
New York
USA
1
New York
USA
2
4 19-DEC-05
Emigrant2
3 19-DEC-05
3 19-DEC-05
Koltom
Koltom
2 19-DEC-05
Pepicek1
4 19-DEC-05
[email protected]
Warszawa
Polska
Zory
Polska
Bratyslawa
Pepicek2
4 19-DEC-05
PepicekSK
4 19-DEC-05
Winger
www.koltom.prv.pl
2
0
Czechy
1
Gorne Teplice
Slowacja
Berlin
Niemcy
www.gov.de
3
Polska
1
[email protected]
Warszawa
Polska
www.idg.pl
1
zy
sz
la
Schreder
4 19-DEC-05
Deutschland, Deutschland uber Alles
www.prezydent.gov.pl
2
Czechy
.a
Bratyslawa
s.
p
Kaczka
Prezydent RP
l
4 19-DEC-05
pl
u
Emigrant3
0
4 19-DEC-05
Wolsztyn
smolki
Michal Smolinski
2 19-DEC-05
Jeszcze innym ciekawym poleceniem może być uzyskanie spisu wątków, bez odpowiedzi:
SELECT
.d
"threads"."id",
"threads"."name"
FROM
"threads",
"ThreadsWithoutAnswerView"
w
WHERE
"threads"."id"="ThreadsWithoutAnswerView".threadid;
W wyniku otrzymamy:
name
-------------------Kupie lodz podwodna
Komplet terrorystow
Siekierke na kijek!
PILNE!!!
w
w
id
---------7
9
11
Wnioski z testowania i uruchamiania
23
Albo lista najnowszych wątków:
select
"threads"."id",
"threads"."name",
"NewestThreadsView".LastPostTime,
"threads"."desc"
from
"threads",
"NewestThreadsView"
where
"threads"."id"="NewestThreadsView".threadID;
id name
LASTPOSTT
---------- -------------------- --------desc
-------------------------------------------------------------------------------9 Komplet terrorystow 19-DEC-05
19-DEC-05
11 Siekierke na kijek!
PILNE!!!
19-DEC-05
19-DEC-05
19-DEC-05
8 Bomba atomowa 10MT
19-DEC-05
zy
sz
la
7 Kupie lodz podwodna
.a
1 Ksiega gosci
Wpisz sie!
pl
u
12 Precz z Kaczynskim!
s.
p
l
10 Vodka, vodka, vodka! 19-DEC-05
!!
Bardzo przydatną i często wykorzystywaną funkcją będzie pobieranie z bazy adresów e-mail, na które należy
rozesłać powiadomienia o modyfikacji wątku. Zakładając, że zmianie uległ wątek 1, polecenie będzie miało
następującą postać:
SELECT
"users"."email"
FROM
"users",
"monitoring"
WHERE
.d
"monitoring"."userid"="users"."id" AND
"monitoring"."topicid"=1 AND
"users"."email" IS NOT NULL;
w
email
[email protected]
w
w
Bardzo ciekawym może być także wyświetlenie takich danych o wskazanym wątku, jak jego autor, czas założenia,
kiedy ktoś dokonał ostatniej wypowiedzi i kto to był oraz ile jest wszystkich wypowiedzi. Uzyskać to można poprzez
wywołanie takiego złożonego zapytania:
Wnioski z testowania i uruchamiania
24
SELECT
"threads"."name" AS Watek,
(SELECT "name" FROM "users" WHERE "id"=p1."user") AS Autor,
p1."time" AS Zalozony,
(SELECT COUNT(*) FROM "posts" WHERE "parent"="threads"."id") AS Wypowiedzi,
p2."time" AS Ostatnia_wypowiedz,
(SELECT "name" FROM "users" WHERE "id"=p2."user") AS Ostatnio_mowil
FROM
"threads",
"posts" p1,
"posts" p2
WHERE
p1."id"=(SELECT MIN("id") FROM "posts" WHERE "parent"="threads"."id") AND
p2."id"=(SELECT MAX("id") FROM "posts" WHERE "parent"="threads"."id") AND
"threads"."id"=1;
W wyniku tego otrzymamy:
w
w
w
.d
zy
sz
la
.a
pl
u
s.
p
l
WATEK
AUTOR
ZALOZONY WYPOWIEDZI OSTATNIA_ OSTATNIO_MOWIL
------------------------------ --------------- --------- ---------- --------- --------------Ksiega gosci
Dzyszla
19-DEC-05
8 19-DEC-05 Emigrant2