Mam następującą strukturę bazy danych (tutaj wersja dla PostgreSQL).
CREATE TABLE uzytkownicy ( uzytkownik_id serial, uzytkownik_nazwa VARCHAR(16) NOT NULL, uzytkownik_imie VARCHAR(20) NOT NULL, uzytkownik_nazwisko VARCHAR(30) NOT NULL, CONSTRAINT pk_uzytkownicy PRIMARY KEY (uzytkownik_id), CONSTRAINT check_nazwa CHECK (uzytkownik_nazwa <> ''), CONSTRAINT check_imie CHECK (uzytkownik_imie <> ''), CONSTRAINT check_nazwisko CHECK (uzytkownik_nazwisko <> ''), CONSTRAINT uqe_uzytkownik_nazwa UNIQUE (uzytkownik_nazwa) ); CREATE TABLE wiadomosci ( wiadomosc_id serial, wiadomosc_temat VARCHAR(128) NOT NULL, wiadomosc_tresc TEXT NOT NULL, CONSTRAINT pk_wiadomosc PRIMARY KEY (wiadomosc_id), CONSTRAINT check_temat CHECK (wiadomosc_temat <> ''), CONSTRAINT check_tresc CHECK (wiadomosc_tresc <> '') ); CREATE TABLE uzytkownicy_wiadomosci ( uzytkownik_id integer NOT NULL, wiadomosc_id integer NOT NULL, CONSTRAINT pk_uzytownicy_wiadomosci PRIMARY KEY (uzytkownik_id, wiadomosc_id), CONSTRAINT rel_uzytkownicy_wiadomosci_1 FOREIGN KEY (uzytkownik_id) REFERENCES uzytkownicy(uzytkownik_id) ON DELETE RESTRICT ON UPDATE RESTRICT, CONSTRAINT rel_uzytkownicy_wiadomosci_2 FOREIGN KEY (wiadomosc_id) REFERENCES wiadomosci(wiadomosc_id) ON DELETE RESTRICT ON UPDATE RESTRICT ); CREATE INDEX idx_uzytkownik_id ON uzytkownicy_wiadomosci(uzytkownik_id); CREATE INDEX idx_wiadomosc_id ON uzytkownicy_wiadomosci(wiadomosc_id);
Cóż o tej strukturze tabel można powiedzieć: tabela użytkownicy, tabela wiadomości ->> połączone za pomocą tabeli łączące (relacja wiele do wielu).
Moje pytania:
1) jak wygląda wydajność przy wyszukiwaniu danych przy takim układzie tabel
2) mam dwa takie zapytania (chcę pobrać listę wszystkich użytkowników którzy napisali wszystkie wiadomości – oczywiście napisane przez nich).
a)
SELECT uzytkownik_imie AS imie, uzytkownik_nazwisko AS nazwisko, wiadomosc_temat AS temat, wiadomosc_tresc AS tresc FROM uzytkownicy u, wiadomosci w, uzytkownicy_wiadomosci u_w WHERE u.uzytkownik_id = u_w.uzytkownik_id AND w.wiadomosc_id = u_w.wiadomosc_id

SELECT uzytkownicy.uzytkownik_nazwa, uzytkownicy.uzytkownik_imie, wiadomosci.wiadomosc_temat, wiadomosci.wiadomosc_tresc FROM uzytkownicy INNER JOIN uzytkownicy_wiadomosci ON (uzytkownicy.uzytkownik_id = uzytkownicy_wiadomosci.uzytkownik_id) INNER JOIN wiadomosci ON (uzytkownicy_wiadomosci.wiadomosc_id = wiadomosci.wiadomosc_id)
Jaka jest różnica pomiędzy tymi zapytaniami (styl, „profesjonalizm zapisu”, szybkość wykonywania)

PostgreSQL poleceniem EXPLAIN wyrzucił coś takiego:
Zapytanie 1)
Kod
Hash Join (cost=5.31..8.10 rows=20 width=171)
Hash Cond: ("outer".uzytkownik_id = "inner".uzytkownik_id)
-> Hash Join (cost=3.42..5.75 rows=53 width=118)
Hash Cond: ("outer".wiadomosc_id = "inner".wiadomosc_id)
-> Seq Scan on wiadomosci w (cost=0.00..1.53 rows=53 width=118)
-> Hash (cost=2.94..2.94 rows=194 width=8)
-> Seq Scan on uzytkownicy_wiadomosci u_w (cost=0.00..2.94 rows =194 width=8)
-> Hash (cost=1.71..1.71 rows=71 width=61)
-> Seq Scan on uzytkownicy u (cost=0.00..1.71 rows=71 width=61)
(9 rows)
Hash Cond: ("outer".uzytkownik_id = "inner".uzytkownik_id)
-> Hash Join (cost=3.42..5.75 rows=53 width=118)
Hash Cond: ("outer".wiadomosc_id = "inner".wiadomosc_id)
-> Seq Scan on wiadomosci w (cost=0.00..1.53 rows=53 width=118)
-> Hash (cost=2.94..2.94 rows=194 width=8)
-> Seq Scan on uzytkownicy_wiadomosci u_w (cost=0.00..2.94 rows =194 width=8)
-> Hash (cost=1.71..1.71 rows=71 width=61)
-> Seq Scan on uzytkownicy u (cost=0.00..1.71 rows=71 width=61)
(9 rows)
Zapytanie 2)
Kod
Hash Join (cost=5.31..8.10 rows=20 width=158)
Hash Cond: ("outer".uzytkownik_id = "inner".uzytkownik_id)
-> Hash Join (cost=3.42..5.75 rows=53 width=118)
Hash Cond: ("outer".wiadomosc_id = "inner".wiadomosc_id)
-> Seq Scan on wiadomosci (cost=0.00..1.53 rows=53 width=118)
-> Hash (cost=2.94..2.94 rows=194 width=8)
-> Seq Scan on uzytkownicy_wiadomosci (cost=0.00..2.94 rows=194
width=8)
-> Hash (cost=1.71..1.71 rows=71 width=48)
-> Seq Scan on uzytkownicy (cost=0.00..1.71 rows=71 width=48)
(9 rows)
Hash Cond: ("outer".uzytkownik_id = "inner".uzytkownik_id)
-> Hash Join (cost=3.42..5.75 rows=53 width=118)
Hash Cond: ("outer".wiadomosc_id = "inner".wiadomosc_id)
-> Seq Scan on wiadomosci (cost=0.00..1.53 rows=53 width=118)
-> Hash (cost=2.94..2.94 rows=194 width=8)
-> Seq Scan on uzytkownicy_wiadomosci (cost=0.00..2.94 rows=194
width=8)
-> Hash (cost=1.71..1.71 rows=71 width=48)
-> Seq Scan on uzytkownicy (cost=0.00..1.71 rows=71 width=48)
(9 rows)