Główna zawartość
Programowanie
Kurs: Programowanie > Rozdział 3
Lekcja 3: Zapytania relacyjne w SQL- Rozdzielanie danych do powiązanych tabel
- Łączenie tabel przy użyciu polecenia JOIN
- Wyzwanie: Hobby Roberta
- Łączenie tabel przy użyciu połączeń typu "left outer join"
- Wyzwanie: Zamówienia klienta
- Łączenie tabel do samych siebie poprzez połączenia wewnątrz-tabelowe
- Wyzwanie: Sequel w SQL
- Łączenie wielu połączeń
- Wyzwanie: FriendBook
- Projekt: Znane postacie
- Bardziej wydajne SQL poprzez kolejkowanie zapytań i optymalizację
© 2023 Khan AcademyWarunki użytkowaniapolitykę prywatnościInformacja o plikach cookie
Rozdzielanie danych do powiązanych tabel
Do tej pory pracowaliśmy z tylko jedną tabelą w tym samym czasie i sprawdzaliśmy jakie interesujące dane możemy z niej odczytać. Ale w rzeczywistości, bardzo często spotkasz się z sytuacją, gdzie dane są rozproszone po wielu tabelach "powiązanych" ze sobą w jakiś sposób.
Na przykład, wyobraźmy sobie, że mamy tablicę w której umieścimy informacje o ocenach uczniów i na wszelki wypadek umieścimy w niej adresy email, gdybyśmy potrzebowali poinformować rodziców o problemach w nauce ich pociech:
imie_ucznia | email_ucznia | test | ocena |
---|---|---|---|
Piotruś Królik | peter@rabbit.com | Odżywianie | 95 |
Alicja Wonderland | alice@wonderland.com | Odżywianie | 92 |
Piotruś Królik | peter@rabbit.com | Chemia | 85 |
Alicja Wonderland | alice@wonderland.com | Chemia | 95 |
Możemy dodatkowo stworzyć drugą tablicę w której będziemy przechowywać informacje o książkach przeczytanych przez danego ucznia:
imie_ucznia | tytul_ksiazki | autor_ksiazki |
---|---|---|
Piotruś Królik | The Tale of Mrs. Tiggy-Winkle | Beatrix Potter |
Piotruś Królik | Jabberwocky | Lewis Carroll |
Alicja Wonderland | The Hunting of the Snark | Lewis Carroll |
Alicja Wonderland | Jabberwocky | Lewis Carroll |
Wypadałoby stworzyć tablicę ze szczegółowymi informacjami o uczniach:
id | imie_ucznia | nazwisko_ucznia | email_ucznia | phone | data_urodzenia |
---|---|---|---|---|---|
1 | Piotruś | Królik | peter@rabbit.com | 555-6666 | 2001-05-10 |
2 | Alicja | Wonderland | alice@wonderland.com | 555-4444 | 2001-04-02 |
Co sądzisz o tych tablicach? Czy zmieniłbyś je w jakiś sposób?
Musisz zdać sobie sprawę z jednej rzeczy o tych tabelach: opisują dane powiązane ze sobą - opisują dane, które są połączone. Każda z tych tabel opisuje dane odnoszące się do konkretnego ucznia i wiele tabel replikuje te same dane. Gdy te same dane są replikowane pomiędzy wieloma tabelami, mogą wystąpić ciekawe skutki uboczne.
Na przykład, co się stanie, gdy adres email ucznia się zmieni? Które tabele musielibyśmy zmienić?
Musielibyśmy zmienić tabelę z informacjami o uczniu, ale mamy tą informację także w tabeli z ocenami, więc musielibyśmy znaleźć każdy wiersz i zmienić w nim adres email.
Preferuje się posiadanie jednej informacji w jednym miejscu, dzięki czemu mamy mniej miejsc do aktualizacji i minimalizujemy ryzyko posiadania niezgodnych danych w różnych miejscach. Jeśli to zrobimy, musimy upewnić się, że mamy sposób na powiązanie danych z wielu tabel. Przejdziemy do tego później.
Załóżmy, że chcemy usunąć adres email z tabeli z ocenami, ponieważ zdaliśmy sobie sprawę z tego, że mamy adres email w tabeli z informacjami o uczniu. Tak wyglądałaby efekt:
imie_ucznia | test | ocena |
---|---|---|
Piotruś Królik | Odżywianie | 95 |
Alicja Wonderland | Odżywianie | 92 |
Piotruś Królik | Chemia | 85 |
Alicja Wonderland | Chemia | 95 |
Skąd mamy wiedzieć, który adres email należy do danego ucznia? Moglibyśmy znaleźć wiersz w tabeli z informacjami o uczniu szukając po imieniu. Co zrobić jeśli dwóch uczniów nazywa się tak samo? (Czy wiesz, że na Bali, każda osoba ma jedno z czterech imion?) Nie możemy polegać na imieniu i naprawdę nigdy nie powinniśmy polegać na czymś takim jak imię do jednoznacznego określenia czegokolwiek w tabeli.
Najlepszą rzeczą jaką możemy zrobić będzie zastąpienie
imie_ucznia
kolumną id_ucznia
, ponieważ jest to jednoznaczny identyfikator:id_ucznia | test | ocena |
---|---|---|
1 | Odżywianie | 95 |
2 | Odżywianie | 92 |
1 | Chemia | 85 |
2 | Chemia | 95 |
Powinniśmy wprowadzić tę samą zmianę do naszej tabeli z książkami, korzystając z kolumny
student_id
zamiast student_name
:id_ucznia | tytul_ksiazki | autor_ksiazki |
---|---|---|
1 | The Tale of Mrs. Tiggy-Winkle | Beatrix Potter |
1 | Jabberwocky | Lewis Carroll |
2 | The Hunting of the Snark | Lewis Carroll |
2 | Jabberwocky | Lewis Carroll |
Zauważyłeś jak powtórzyliśmy tytuł i autora dla Jabberwocky? To kolejny znak ostrzegawczy informujący nas, że powinniśmy rozdzielić tą tabelę na mniejsze tabele powiązane ze sobą w taki sposób, aby nie trzeba było zmieniać tych samych informacji o książce w wielu miejscach.
Możemy stworzyć tablicę z samymi książkami:
id | tytul_ksiazki | autor_ksiazki |
---|---|---|
1 | The Tale of Mrs. Tiggy-Winkle | Beatrix Potter |
2 | Jabberwocky | Lewis Carroll |
3 | The Hunting of the Snark | Lewis Carroll |
Wtedy nasza tablica
student_books
wygląda następująco:id_ucznia | id_ksiazki |
---|---|
1 | 1 |
1 | 2 |
2 | 3 |
2 | 2 |
Wiem, że ta tabela nie jest tak prosta do odczytania jak stara tabela, która miała wszystkie informacje w sobie. Musisz pamiętać, że tabele nie są zaprojektowane do czytania przez człowieka -- są zaprojektowane, aby były łatwe w utrzymaniu i jak najmniej wrażliwe na błędy. W wielu przypadkach najlepszym rozwiązaniem jest rozdzielenie informacji na wiele tabel połączonych ze sobą, dzięki czemu unikamy powtórzeń i niepotrzebnych aktualizacji.
Musisz zrozumieć jak SQL korzysta z danych rozdzielonych pomiędzy wiele połączonych tabel i łączy je ze sobą, gdy tego potrzebujesz. Łączymy dane za pomocą koncepcji "join" i nauczysz się z niej korzystać w następnej części.
Chcesz dołączyć do dyskusji?
- Czy można napisać funkcję, sprawdzającą ilość jedwabników?(3 głosy)