BAZY DANYCH · INF.03
phpMyAdmin i XAMPP — od bazy do tabeli
Baza nie powstaje w próżni: trzeba ją utworzyć, zaimportować i zabezpieczyć. Przejdziesz przez phpMyAdmin krok po kroku — od nowej bazy, przez typy danych i klucze, po import gotowego pliku SQL i eksport kopii.
XAMPP, phpMyAdmin i tworzenie bazy
XAMPP to zestaw programów, który zamienia zwykły komputer w lokalny serwer. W skład pakietu wchodzą między innymi Apache (serwer WWW), MySQL/MariaDB (serwer bazy danych), PHP (język skryptowy) oraz phpMyAdmin — graficzny panel do zarządzania bazą. Dzięki nim możesz ćwiczyć import, tworzenie tabel i zapytania SQL bez łączenia się z internetem i bez ryzyka, że zepsujesz prawdziwą stronę.
Pracę zaczynasz od uruchomienia XAMPP Control Panel. Przy modułach Apache i MySQL klikasz Start. Kiedy oba pola zmienią kolor na zielony, usługi działają. Jeśli MySQL nie startuje, najczęściej przyczyną jest inny program zajmujący port 3306 albo wcześniej uruchomiona druga kopia MySQL. Apache domyślnie używa portu 80; gdy jest zajęty, można zmienić port w konfiguracji i otwierać adres z numerem portu, na przykład localhost:8080.
Panel phpMyAdmin otwierasz w przeglądarce pod adresem http://localhost/phpmyadmin. Na lokalnym komputerze zwykle logujesz się jako root bez hasła — to wygodne w pracowni, ale nie nadaje się na publiczny serwer. Po zalogowaniu po lewej stronie widzisz listę baz, a w środkowej części zakładki Przeglądaj, Struktura, SQL, Import i Eksport.
Nową bazę tworzysz przyciskiem Nowa albo poleceniem SQL. Nazwa powinna być krótka, bez polskich znaków i spacji; dla całego kursu używamy biblioteka_szkolna. Kodowanie utf8mb4 pozwala przechować polskie litery, a porównywanie tekstów jest niewrażliwe na wielkość liter dzięki kolacji utf8mb4_unicode_ci. To ważne, bo w danych występują nazwiska typu „Wiśniewska” i „Żółć”, a nie tylko litery alfabetu angielskiego.
CREATE DATABASE IF NOT EXISTS biblioteka_szkolna
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
Gotowy plik z tabelami i danymi wgrywasz przez zakładkę Import. Jeśli baza biblioteka_szkolna już istnieje, wybierz ją w drzewie po lewej; jeśli jeszcze jej nie ma, otwórz Import na stronie głównej phpMyAdmin. Wskaż plik biblioteka-szkolna.sql, pozostaw format SQL i kodowanie UTF-8, a na końcu kliknij Wykonaj. Plik zawiera własne polecenie CREATE DATABASE i USE, więc sam utworzy bazę, jeśli trzeba. Po imporcie sprawdź, czy po lewej stronie pojawiło się jedenaście tabel.
USE biblioteka_szkolna;
SHOW TABLES;
SELECT id, tytul, cena
FROM ksiazki;
Polecenie USE wybiera bazę, z którą pracujesz. SHOW TABLES pokazuje listę tabel, a ostatnie zapytanie wyświetla wszystkie książki. W zakładce SQL możesz wpisać kilka poleceń, ale wykonają się tylko te zaznaczone albo całość po kliknięciu Wykonaj. Średnik kończy pojedyncze polecenie; brak średnika przed kolejnym poleceniem to częsta przyczyna błędu składni.
biblioteka_szkolna powstaje z pliku SQL. Zielone pola w panelu oznaczają, że usługa działa.| Element phpMyAdmin | Do czego służy | Na co uważać |
|---|---|---|
| Struktura | podgląd kolumn, typów, kluczy i indeksów | zmiana typu może obciąć zbyt długie wartości |
| SQL | wykonywanie zapytań i poleceń DDL | najpierw wybierz właściwą bazę po lewej |
| Import | wgranie pliku SQL z tabelami i danymi | kodowanie UTF-8 i właściwy plik |
| Eksport | zapis kopii bazy do pliku SQL | rób kopię przed każdą ryzykowną zmianą |
Przykłady z życia
1. Pierwsze uruchomienie w pracowni. Uczeń siada do komputera, otwiera XAMPP, klika Start przy Apache i MySQL, a następnie wpisuje w przeglądarce adres localhost/phpmyadmin. Jeśli strona się nie otwiera, sprawdza, czy oba moduły są zielone, zanim zacznie szukać błędu w SQL-u.
2. Import gotowej bazy. Nauczyciel rozdaje plik biblioteka-szkolna.sql. Zamiast przepisywać kilkaset poleceń, uczniowie wgrywają plik przez Import i sprawdzają liczbę tabel. To szybsze i mniej podatne na literówki niż kopiowanie całego skryptu do okna SQL.
3. Kopia przed próbą. Przed ćwiczeniem z usuwaniem danych bibliotekarz robi eksport bazy do pliku. Jeśli coś pójdzie nie tak, importuje kopię i wraca do stanu sprzed zmiany. Kopia jest też sposobem na przeniesienie bazy z komputera szkolnego na domowy.
Informatyczna pracownia: administrator serwera robi dokładnie to samo, tylko na większą skalę. Uruchamia usługi, sprawdza porty, konfiguruje konto bazy i wykonuje kopie zapasowe. Umiejętność czytania panelu i komunikatów błędów jest równie ważna jak pisanie zapytań.
Po utworzeniu bazy i zaimportowaniu tabel przejdziesz do modułu 03, gdzie napiszesz pierwsze zapytania SELECT. W module 04 dojdziesz do filtrowania i agregacji, a w module 08 przypomnisz sobie kopie zapasowe i bezpieczeństwo. Cały proces od importu do raportu powtórzysz w module 09.
Biuro: pracownik biura często dostaje plik CSV albo SQL i musi go wczytać do systemu. Zanim to zrobi, sprawdza, czy plik ma właściwe kodowanie i czy nie nadpisze istniejących danych. Ta sama ostrożność obowiązuje w phpMyAdmin.
Kolega uruchomił XAMPP, ale po wejściu na localhost/phpmyadmin widzi błąd połączenia, a po imporcie pliku ma tylko część tabel. Opisz krok po kroku, jak sprawdzić stan usług, wybrać właściwą bazę i bezpiecznie powtórzyć import. Wskaż dwa możliwe powody niepowodzenia i sposób ich rozpoznania. Na końcu podaj, jak potwierdzisz, że baza zawiera jedenaście tabel i dane startowe.
Pokaż przykładowe rozwiązanie i kryteria
Przykład: najpierw otwieram XAMPP Control Panel i sprawdzam, czy Apache oraz MySQL mają status Running. Jeśli MySQL nie startuje, sprawdzam port 3306 i komunikat w logu. Potem w phpMyAdmin wybieram bazę biblioteka_szkolna i sprawdzam listę tabel. Jeśli import przerwał się w połowie, usuwam niekompletne tabele lub tworzę bazę od nowa, a następnie wgrywam cały plik jeszcze raz, pilnując kodowania UTF-8. Na końcu wykonuję SHOW TABLES i liczę jedenaście nazw oraz sprawdzam kilka wierszy w ksiazki i uczniowie.
Kryteria: (1) kolejność — uczeń najpierw sprawdza usługi, potem połączenie, a na końcu dane; (2) diagnostyka — podaje konkretny powód, np. zajęty port albo import do złej bazy; (3) bezpieczeństwo — nie nadpisuje danych bez kopii i wie, kiedy zacząć od czystej bazy; (4) weryfikacja — potwierdza liczbę tabel i wybrane wiersze zapytaniem, a nie tylko „na oko”.
Typy danych i kolumny tabeli
W arkuszu kalkulacyjnym komórka „przyjmie” wszystko: datę, tekst i liczbę. W bazie danych tak nie jest. Każda kolumna ma typ danych, który określa, jakie wartości mogą się w niej znaleźć i jak baza ma je przechowywać. Dobry typ to nie kosmetyka — to pierwsza linia obrony przed błędami, które później trudno naprawić.
Liczby całkowite przechowujemy w typach INT, TINYINT lub SMALLINT. Dodatek UNSIGNED zabrania wartości ujemnych, co pasuje do identyfikatorów, stanu magazynowego i liczby miejsc. Typ TINYINT(1) jest w schemacie biblioteki używany jako flaga 0/1: dostepna w tabeli ksiazki oraz aktywny w tabeli uczniowie. Nie oznacza to, że można wpisać tam dowolną liczbę — sens flagi jest umowny i aplikacja powinna pilnować wartości 0 albo 1.
Pieniądze wymagają szczególnej ostrożności. Typ DECIMAL(6,2) oznacza sześć cyfr znaczących, z czego dwie po przecinku, więc mieści cenę do 9999,99. Typ FLOAT bywa kuszący, ale przechowuje przybliżenia i potrafi „zgubić” grosz przy dodawaniu. W bibliotece cena książki to DECIMAL(6,2), podobnie kara w tabeli wypozyczenia — DECIMAL(6,2). Dzięki temu 49,90 zł pozostaje dokładnie 49,90 zł.
Tekst dzielimy na VARCHAR i CHAR. VARCHAR(150) przechowuje napis o zmiennej długości i zabiera tyle miejsca, ile potrzeba; nadaje się na tytuł, imię czy e-mail. CHAR(13) ma stałą długość i jest dobry dla ISBN, który zawsze ma trzynaście znaków. Kod kategorii CHAR(3) również ma stałą długość. Jeśli wpiszesz za długi napis, baza w trybie ścisłym zgłosi błąd, a nie po cichu obetnie tekst — to zachowanie, którego chcemy.
Daty przechowujemy w typie DATE, rok wydania w YEAR, a godzinę w TIME. Status wypożyczenia jest typu ENUM z wartościami w trakcie, zwrocone i przeterminowane. Dzięki temu baza odrzuci literówkę „zwrocona” albo „przeterminowany”. ENUM jest wygodny dla krótkiej, zamkniętej listy, ale dodanie nowej wartości wymaga zmiany definicji tabeli — nie nadaje się dla danych, które mają rosnąć bez końca.
CREATE TABLE czytelnie (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(80) NOT NULL,
pojemnosc INT UNSIGNED NOT NULL DEFAULT 0,
dostepna TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (id),
UNIQUE KEY uq_czytelnie_nazwa (nazwa)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
To przykładowa tabela, której nie ma w bazie startowej. Zwróć uwagę na trzy ograniczenia. NOT NULL oznacza, że kolumna musi mieć wartość. DEFAULT 0 podstawia zero, gdy nie podasz liczby miejsc. AUTO_INCREMENT sprawia, że baza sama nada kolejny numer id. Na końcu definiujemy klucz podstawowy i unikalną nazwę czytelni, aby nie powstały dwie sale o tej samej nazwie.
SELECT tytul, cena, stan, dostepna
FROM ksiazki
ORDER BY id;
Wynik pokazuje, jak typy przekładają się na dane: cena ma dwa miejsca po przecinku, stan jest liczbą całkowitą, a dostepna przyjmuje 0 lub 1. Jeśli w kolumnie cena pojawi się napis „dziesięć złotych”, to znak, że ktoś wybrał zły typ albo importował dane bez sprawdzenia. Poprawny projekt nie pozwala na taki wpis.
| Typ | Przykład w bibliotece | Do czego pasuje | Typowa pułapka |
|---|---|---|---|
INT UNSIGNED |
id, stan |
identyfikatory i liczby całkowite bez minusów | za mały typ dla dużych zbiorów |
TINYINT(1) |
dostepna, aktywny |
flaga prawda/fałsz | wpisanie wartości 2 bez sprawdzenia w aplikacji |
DECIMAL(6,2) |
cena, kara |
kwoty pieniężne | użycie FLOAT i zaokrąglenia |
VARCHAR(n) |
tytul, imie, email |
tekst o zmiennej długości | zbyt krótki limit i utrata końcówki napisu |
CHAR(n) |
isbn, kod |
kody o stałej długości | dodawanie spacji lub myślników do kodu |
DATE |
data_urodzenia, termin_zwrotu |
daty bez godziny | zapis jako tekst i błędne sortowanie |
YEAR |
rok_wydania |
sam rok | wpisanie tekstu „rok 1993” |
ENUM |
status w wypożyczeniach |
krótka lista dopuszczalnych wartości | literówka odrzucona przez bazę; trudne rozszerzanie listy |
YEAR przechowuje lata od 1901 do 2155. W pliku kursowym są książki wydane w 1834, 1890 i 1896 roku oraz autorzy urodzeni przed 1901 rokiem. W phpMyAdmin zobaczysz dla nich 0000, bo domyślna konfiguracja XAMPP używa łagodnego trybu zapisu; w trybie ścisłym import zatrzyma się z błędem 1264. W edytorze kursu dane demonstracyjne zachowują pełne lata. Projektując własną bazę z datami historycznymi, wybierz SMALLINT albo DATE, a nie YEAR. W schemacie kursu zostawiamy YEAR, bo tak wygląda oryginalny zrzut — dzięki temu zobaczysz to ograniczenie w praktyce.
Przykłady z życia
1. Numer telefonu. Numer „600 100 101” zawiera spacje i może zaczynać się od zera. Jeśli zapiszesz go jako liczbę całkowitą, stracisz spacje i początkowe zero. W bazie biblioteki telefon jest tekstem VARCHAR(20), choć wygląda jak liczba — bo nim nie jest.
2. Cena w sklepie. Cena 49,90 zł musi pozostać dokładna przy sumowaniu wielu pozycji. Typ DECIMAL liczy jak w księgowości, a FLOAT może dać wynik 49,9000001. Dlatego ceny i kary w bibliotece mają dwa miejsca po przecinku.
3. Data zwrotu. Data zapisana jako tekst „05.11.2026” sortuje się inaczej niż data w typie DATE. Typ daty pozwala też obliczyć spóźnienie i porównać termin z dniem dzisiejszym. To nie jest tylko wygoda — to warunek poprawnych raportów.
Informatyczna pracownia: formularz HTML z polem „rok wydania” może mieć atrybut maxlength, ale użytkownik może go obejść. Dopiero typ YEAR i ograniczenia w bazie dają pewność, że do tabeli nie trafi tekst. Projektant aplikacji musi myśleć o obu warstwach: wygodzie formularza i rygorze bazy.
W poprzedniej sekcji uruchomiliśmy XAMPP i utworzyliśmy bazę. Typy kolumn zobaczą skutki w module 03, gdy posortujesz daty i ceny, oraz w module 07, gdy będziesz dodawać i aktualizować wiersze. W module 08 wrócisz do raportów i bezpieczeństwa danych, a w module 09 sprawdzisz cały projekt w zadaniu egzaminacyjnym.
Biuro: w arkuszu można wpisać datę jako tekst i tylko wygląda ona poprawnie. W bazie typ DATE od razu ujawnia, że „31.02.2026” nie istnieje. To różnica między dokumentem, który tylko wygląda dobrze, a danymi, na których można polegać.
Klucze, relacje, import i eksport
W phpMyAdmin tabelę można utworzyć klikając kolumny w formularzu, ale w zadaniach egzaminacyjnych i w prawdziwych projektach wygodniej zapisać definicję w SQL-u. Polecenie CREATE TABLE określa nazwy kolumn, ich typy oraz ograniczenia. To ostatnie jest szczególnie ważne: klucz podstawowy, klucz unikalny i klucz obcy nie są ozdobą, lecz regułami, których baza pilnuje przy każdym wpisie.
CREATE TABLE czytelnie (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(80) NOT NULL,
pojemnosc INT UNSIGNED NOT NULL DEFAULT 0,
dostepna TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (id),
UNIQUE KEY uq_czytelnie_nazwa (nazwa)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
PRIMARY KEY (id) czyni z kolumny id główny identyfikator wiersza. UNIQUE KEY pilnuje, aby nazwa czytelni nie powtórzyła się. Silnik InnoDB jest potrzebny do obsługi kluczy obcych i transakcji, a kodowanie utf8mb4 do polskich znaków. Jeśli tworzysz tabelę w phpMyAdmin, te same ustawienia wybierasz w formularzu, ale warto umieć je zapisać ręcznie, bo wtedy dokładnie wiesz, co powstało.
Klucz obcy tworzymy w tabeli podrzędnej i wskazujemy tabelę nadrzędną. Najpierw musi istnieć tabela pracownicy i czytelnie, dopiero potem można utworzyć dyzury, które się do nich odwołują. Jeśli tworzyłeś już tabelę czytelnie w poprzedniej sekcji, pomiń jej polecenie CREATE TABLE i wykonaj tylko definicję dyzury. Typy po obu stronach muszą być zgodne: INT UNSIGNED wskazuje INT UNSIGNED. MySQL nie zgodzi się na klucz obcy do kolumny o innym typie, bo wtedy porównania mogłyby być nieprzewidywalne.
CREATE TABLE dyzury (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
pracownik_id INT UNSIGNED NOT NULL,
czytelnia_id INT UNSIGNED NOT NULL,
data_dyzuru DATE NOT NULL,
godzina_od TIME NOT NULL,
godzina_do TIME NOT NULL,
PRIMARY KEY (id),
CONSTRAINT fk_dyzury_pracownik
FOREIGN KEY (pracownik_id) REFERENCES pracownicy (id),
CONSTRAINT fk_dyzury_czytelnia
FOREIGN KEY (czytelnia_id) REFERENCES czytelnie (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Nazwy fk_dyzury_pracownik i fk_dyzury_czytelnia nie są obowiązkowe, ale pomagają w diagnozie błędów. Gdy próbujesz dodać dyżur dla pracownika numer 99, baza zgłasza naruszenie klucza obcego, bo taki pracownik nie istnieje. To dokładnie ta ochrona, której oczekujemy. W schemacie biblioteki klucz obcy ksiazki_autorzy.ksiazka_id ma dodatkowo ON DELETE CASCADE: usunięcie książki usuwa jej powiązania z autorami, ale nie usuwa samych autorów.
Eksport to zapis bazy do pliku SQL. W phpMyAdmin wybierasz bazę, zakładkę Eksport, metodę szybką, format SQL i klikasz Eksportuj. Powstaje plik z poleceniami CREATE TABLE i INSERT, który można później wgrać przez Import. Eksport przed ryzykowną zmianą to najprostsza kopia bezpieczeństwa. Pamiętaj, że plik zawiera dane — nie publikuj go, jeśli w bazie są informacje prywatne.
Import wykonuje polecenia z pliku w podanej kolejności. Jeśli plik tworzy tabelę podrzędną przed nadrzędną, MySQL zgłosi błąd 1215 lub 1452. Jeśli w pliku brakuje USE biblioteka_szkolna, zobaczysz błąd 1046 „No database selected”. Jeśli importujesz do bazy, w której tabele już istnieją, polecenia CREATE TABLE mogą zakończyć się błędem 1050, a DROP TABLE IF EXISTS z pliku kursowego usunie stare dane. Dlatego przed importem zawsze sprawdzaj, do której bazy trafia plik.
SHOW CREATE TABLE ksiazki;
SHOW CREATE TABLE wypozyczenia;
Polecenie SHOW CREATE TABLE pokazuje pełną definicję tabeli: kolumny, typy, klucze i silnik. To najlepszy sposób, aby sprawdzić, czy import rzeczywiście utworzył to, czego oczekiwałeś. Samo „widzę tabelę na liście” nie wystarcza — tabela może mieć inne typy albo brakować klucza obcego.
| Kod błędu | Komunikat | Najczęstsza przyczyna |
|---|---|---|
| 1046 | No database selected | brak USE lub niewybrana baza w panelu |
| 1050 | Table already exists | tabela o tej nazwie już jest w bazie |
| 1062 | Duplicate entry | powtórzony klucz podstawowy lub unikalny |
| 1064 | Syntax error | brak średnika, literówka, zły cudzysłów |
| 1146 | Table doesn't exist | zła nazwa tabeli albo import do innej bazy |
| 1215 / 1452 | Cannot add foreign key / constraint fails | brak tabeli nadrzędnej, niezgodny typ lub brak rekordu |
Przykłady z życia
1. Kopia przed remontem. Przed zmianą wystroju biblioteki robisz zdjęcia i spisujesz ustawienie półek. Eksport bazy jest takim zdjęciem: jeśli nowa wersja okaże się zła, wracasz do stanu sprzed zmiany. Kopia leży w pliku, więc nie zależy od tego, czy pamiętasz wszystkie kroki.
2. Import do nowego komputera. Przenosisz bazę z pracowni na laptopa. Eksportujesz ją na starym komputerze, kopiujesz plik, tworzysz pustą bazę na nowym i importujesz. Jeśli plik zawiera CREATE DATABASE, baza powstanie sama; jeśli nie, musisz ją najpierw utworzyć.
3. Błąd kolejności tabel. Kolega importuje plik, w którym wypozyczenia powstaje przed uczniowie. MySQL nie może dodać klucza obcego do nieistniejącej tabeli. Rozwiązanie to zmiana kolejności poleceń albo chwilowe wyłączenie sprawdzania kluczy, ale po imporcie trzeba je koniecznie włączyć z powrotem.
Informatyczna pracownia: w firmie wdrożenie nowej wersji bazy poprzedza się kopią i testem na środowisku staging. Nikt rozsądny nie uruchamia skryptu zmieniającego tabele najpierw na produkcji. W XAMPP masz bezpieczne środowisko lokalne — korzystaj z niego, zanim cokolwiek zrobisz na prawdziwych danych.
W poprzedniej sekcji dobieraliśmy typy kolumn. Teraz zakładamy klucze i relacje. Klucze obce staną się naprawdę widoczne w module 05, gdy połączysz tabele JOIN-em, oraz w module 07, gdy dodasz i usuniesz powiązane wiersze. W module 08 wrócisz do kopii zapasowych i bezpieczeństwa, a w module 09 wykonasz pełny import i raport na czas.
Biuro: eksport i import to codzienność przy wymianie danych między programami. Faktura wystawiona w jednym systemie trafia do drugiego jako plik, a klucze klienta i towaru muszą się zgadzać. Jeśli numer klienta nie istnieje w nowym systemie, import się zatrzyma — dokładnie jak przy naruszeniu klucza obcego.
Masz dodać do biblioteki nowe tabele czytelnie i dyzury. Opisz kolejność działań: co zrobisz przed zmianą, jak utworzysz tabele, jak sprawdzisz klucze i jak odtworzysz bazę, jeśli eksperyment się nie uda. Wskaż, dlaczego tabela dyzury nie może powstać przed czytelnie, i co zrobisz, gdy import zgłosi błąd 1452. Uwzględnij weryfikację po odtworzeniu.
Pokaż przykładowe rozwiązanie i kryteria
Przykład: najpierw eksportuję całą bazę do pliku biblioteka-przed-zmiana.sql. Tworzę tabelę czytelnie z kluczem podstawowym i unikalną nazwą, a dopiero potem dyzury z dwoma kluczami obcymi. Sprawdzam definicje przez SHOW CREATE TABLE i dodaję próbny dyżur dla istniejącego pracownika. Jeśli import kopii zgłosi 1452, sprawdzam, czy plik tworzy tabele nadrzędne przed podrzędnymi i czy dane nie odwołują się do brakujących rekordów. Po odtworzeniu liczę tabele i sprawdzam wybrane wiersze.
Kryteria: (1) kopia — uczeń wykonuje eksport przed zmianą i wie, jak go użyć; (2) kolejność — tworzy tabele nadrzędne przed podrzędnymi; (3) klucze — poprawnie definiuje PK i FK oraz sprawdza ich działanie; (4) weryfikacja — po odtworzeniu potwierdza strukturę i dane, zamiast zakładać, że import się udał.
Ćwiczenia SQL
Zadania do samodzielnego wykonania w edytorze SQL.
- 1Nowa tabela czytelniUtwórz tabelę czytelnie z kluczem i dodaj trzy przykładowe wiersze.Zadanie i podpowiedzi →
- 2Plan dyżurów bibliotekiUtwórz tabelę dyżurów z kluczem obcym do pracowników i dodaj dwa terminy.Zadanie i podpowiedzi →
- 3Nowa kategoria w kataloguDodaj do tabeli kategorie nową kategorię Poradniki z trzyliterowym kodem.Zadanie i podpowiedzi →
- 4Książka z nowej dostawyDodaj do katalogu książkę o identyfikatorze 25, z kategorią, wydawnictwem, ISBN i ceną.Zadanie i podpowiedzi →