Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!
Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.
Witam,
mam tabelki:
1) ksiazka (id, tytul, rok_wydania)
2) autor (id, nazwisko)
3) ksiazka_autor (id, id_ksiazki, id_autora)
4) ksiazka_gatunek (id, id_ksiazki, numer_gatunku)
mamy książki, każda książka może mieć wielu autorów (książki z ich autorami łączy tabela ksiazka_autor), każda książka może należeć do wielu gatunków.
I teraz jak wyświetlić listę książek wraz z ich autorami i gatunkami. Np. 20 pierwszych książek z pełnymi informacjami o nich.
Mogę wyciągnąć sobie z bazy najpierw same książki, wziąć ich numery id do tablicy, po czym pobrać listę autorów pasujących do tych id a następnie połączyć wszystko w php :) Ale musi się dać prościej. W praktycznie każdym serwisie z bazą danych występują relację wiele do wielu, więc musi być jakiś prosty sposób na radzenie sobie z takim czymś.
Dodam, że chciałbym to później zrobić w ZendFrameworku, ale najpierw w czystym php.
pozdrawiam!
Offline
select ksiazka.tytul, ksiazka.rok_wydania, autor.nazwisko, gatunek.nazwa from ksiazka inner join ksiazka_autor on ksiazka_autor.id_ksiazka = ksiazka.id inner join autor on autor.id = ksiazka_autor.id_autor inner join ksiazka_gatunek on ksiazka_gatunek.id_ksiazki = ksiazka.id inner join gatunek on gatunek.id = ksiazka_gatunek.numer_gatunku
Osobiście pewnie inaczej bym zrobił schemat, a już na pewno powyższy trzeba było by uzupełnić o relację gatunek oraz usunąć id w ksiazka_gatunek,podobnie w ksiazka_autor (mozna zrobić klucz podwójny) oraz podorabiac foreing key dla ksiazka_autor (jeden do ksiazka, drugi do autor), by zachować hmm poprawność. Oraz foreing key dla ksiazka_gatunek do ksiazka i gatunek. Ale ogolne schemet coś dziwny, tzn. czuje podświadomie, że jeszcze czegoś brak/czegoś nie uwzględnia.
EDIT: mysql ma coś takiego jak group_concat(column)
select ksiazka.tytul, ksiazka.rok_wydania, ( select group_concat(autor.nazwisko) from autor inner join ksiazka_autor on ksiazka_autor.id_autor = autor.id where ksiazka_autor.id_ksiazki = ksiazka.id ) as autorzy, ( select group_concat(gatunek.nazwa) from gatunek inner join ksiazka_gatunek on ksiazka_gatunek.numer_gatunku = gatunek.id where ksiazka_gatunek.id_ksiazki = ksiazka.id ) as gatunki from ksiazka;
Hmm? Powinno działać?
MySQL chyba ma limit do okreslania ile pierwszy z offset'em ile pominąć pierwszych.
Ostatnio edytowany przez paoolo (2011-02-18 19:30:04)
Offline
Z tego co widzę to pierwszym przypadku dostane każdą jedną książkę w wielu(jeżeli ma wielu autorów/gatunki) wierszach i muszę sobie to chyba już w php obrobić? Do głowy przychodzi mi tylko wrzucenie tego do tablic i wywalanie duplikatów, można by uniwersalną funkcję zrobić do tego - w sumie spoko, nie wiem jak z wydajnością tego. Ciekawi mnie jak to jest rozwiązywane przez programistów w prawdziwych projektach.
Ten drugi przypadek z pozoru super, ale jeżeli np. w tabelce autor dodałbym więcej kolumn, np. data ur. autora, imie, itd. to mi to poskleja w jeden ciąg chyba.
Ostatnio edytowany przez johny (2011-02-18 21:22:18)
Offline
W przypadku drugim, wrzuciłbym dwa pola do group_contact, albo gotowego contact'a na dwóch polach. W przypadku pierwszym - wydajnością zajmują się spece od serwera bazy danych - to jak zadajesz pytanie nie warunkuje (prawie ;) jak to zrobi serwer bazy danych - ty tylko oczekujesz wyników zgodne z warunkami jakie podałeś, ale fakt - im bardzie skopane zapytanie, tym gorzej dla serwera, a tym bardziej, jeśli schemat nie jest poprawny (bo zakłada się jak teoria podaje, że te schematy są w 3 formie normalnej). Można jeszcze podciągać schemat poprzez wykorzystanie odpowiednich silników w MySQL przy tworzeniu relacji (InnoDB powinno się chyba stosować, MyISAM jest default'owy, tu jest porównanie pomiędzy nimi). Także ustawiając indeksy itd.
Offline