Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: zapytania
Forum PHP.pl > Forum > Bazy danych
mhs
Witam serdecznie,

Mam następującą strukturę bazy danych (tutaj wersja dla PostgreSQL).
  1. CREATE TABLE uzytkownicy (
  2. uzytkownik_id serial,
  3. uzytkownik_nazwa VARCHAR(16) NOT NULL,
  4. uzytkownik_imie VARCHAR(20) NOT NULL,
  5. uzytkownik_nazwisko VARCHAR(30) NOT NULL,
  6.  
  7. CONSTRAINT pk_uzytkownicy PRIMARY KEY (uzytkownik_id),
  8.  
  9. CONSTRAINT check_nazwa CHECK (uzytkownik_nazwa <> ''),
  10. CONSTRAINT check_imie CHECK (uzytkownik_imie <> ''),
  11. CONSTRAINT check_nazwisko CHECK (uzytkownik_nazwisko <> ''),
  12.  
  13. CONSTRAINT uqe_uzytkownik_nazwa UNIQUE (uzytkownik_nazwa)
  14. );
  15.  
  16. CREATE TABLE wiadomosci (
  17. wiadomosc_id serial,
  18. wiadomosc_temat VARCHAR(128) NOT NULL,
  19. wiadomosc_tresc TEXT NOT NULL,
  20.  
  21. CONSTRAINT pk_wiadomosc PRIMARY KEY (wiadomosc_id),
  22.  
  23. CONSTRAINT check_temat CHECK (wiadomosc_temat <> ''),
  24. CONSTRAINT check_tresc CHECK (wiadomosc_tresc <> '')
  25. );
  26.  
  27. CREATE TABLE uzytkownicy_wiadomosci (
  28. uzytkownik_id integer NOT NULL,
  29. wiadomosc_id integer NOT NULL,
  30.  
  31. CONSTRAINT pk_uzytownicy_wiadomosci PRIMARY KEY (uzytkownik_id, wiadomosc_id),
  32.  
  33. CONSTRAINT rel_uzytkownicy_wiadomosci_1 FOREIGN KEY (uzytkownik_id) REFERENCES uzytkownicy(uzytkownik_id) ON DELETE RESTRICT ON UPDATE RESTRICT,
  34. CONSTRAINT rel_uzytkownicy_wiadomosci_2 FOREIGN KEY (wiadomosc_id) REFERENCES wiadomosci(wiadomosc_id) ON DELETE RESTRICT ON UPDATE RESTRICT
  35. );
  36.  
  37. CREATE INDEX idx_uzytkownik_id ON uzytkownicy_wiadomosci(uzytkownik_id);
  38. 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)
  1. SELECT
  2. uzytkownik_imie AS imie,
  3. uzytkownik_nazwisko AS nazwisko,
  4. wiadomosc_temat AS temat,
  5. wiadomosc_tresc AS tresc
  6. FROM uzytkownicy u,
  7. wiadomosci w,
  8. uzytkownicy_wiadomosci u_w
  9. WHERE u.uzytkownik_id = u_w.uzytkownik_id AND w.wiadomosc_id = u_w.wiadomosc_id


cool.gif

  1. SELECT
  2. uzytkownicy.uzytkownik_nazwa,
  3. uzytkownicy.uzytkownik_imie,
  4. wiadomosci.wiadomosc_temat,
  5. wiadomosci.wiadomosc_tresc
  6. FROM uzytkownicy INNER JOIN uzytkownicy_wiadomosci ON (uzytkownicy.uzytkownik_id = uzytkownicy_wiadomosci.uzytkownik_id)
  7. INNER JOIN wiadomosci ON (uzytkownicy_wiadomosci.wiadomosc_id = wiadomosci.wiadomosc_id)


Jaka jest różnica pomiędzy tymi zapytaniami (styl, „profesjonalizm zapisu”, szybkość wykonywania)questionmark.gif

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)



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)
ins@ne
Moge Ci powiedziec tylko czym sie roznia te dwa rodzaje zapytan. Ten pierwszy (bez joinow) jest to stara notacja (ale czesto dalej stosowana), natomiast ten z joinami to notacja nowa...
mhs
Cytat(ins@ne @ 2005-01-07 20:53:27)
Moge Ci powiedziec tylko czym sie roznia te dwa rodzaje zapytan. Ten pierwszy (bez joinow) jest to stara notacja (ale czesto dalej stosowana), natomiast ten z joinami to notacja nowa...

dzięki:)

chyba będę musiał sobie pogrzebać po kolejnych wersjach SQL'a
popbart
Ja przystaje przy używaniu inner join.
Dlaczego? Jak masz doczynienia ze skomplikowanymi zapytaniami to czasami jest fajnie gdy masz oddzieloną cześć odpowiedzialną za relację z innymi warunkami.
Generalnie czytelność smile.gif

edit---
Zapomniałem jeszcze dodać że przy inner join można stosować using
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.