Przeczytaj
Baza i narzędzia
System bazodanowy SQLite nie wymaga instalacji i konfiguracji serwera. Do jego obsługi wystarczy narzędzie wiersza poleceń, program z interfejsem graficznym lub biblioteka w wybranym języku programowania, np. Python, PHP czy C++. Dlatego SQLite często wykorzystywany jest do nauki i rozwijania znajomości języka SQL.
Program SQLiteStudio
To otwartoźródłowa aplikacja z interfejsem graficznym. Program pobieramy ze strony sqlitestudio.pl
w postaci archiwum TAR.XZ – dla systemów Linux, lub ZIP – dla systemu Windows. Po rozpakowaniu archiwum w katalogu SQLiteStudio
znajdziemy plik sqlitestudio
(Linux) lub sqlitestudio.exe
, za pomocą którego uruchamiamy program.
Zamiast wersji portable możemy pobrać instalator z rozszerzeniem .run
dla systemów Linux lub .exe
dla systemów Windows. W systemie Linux we właściwościach pliku instalatora należy zaznaczyć zezwolenie na uruchamianie jako program. Po uruchomieniu instalatora program można zainstalować dla wszystkich użytkowników (co wymaga uprawnień administratora) lub dla bieżącego użytkownika.
Domyślnie program uruchamia się z interfejsem w języku angielskim. Aby włączyć polską wersję językową, wybieramy Tools
| Open Configuration dialog
, klikamy sekcję Look & feel
po lewej stronie i po prawej stronie wskazujemy na rozwijalnej liście język polski.
Po uruchomieniu programu SQLiteStudio otwieramy lub tworzymy bazę danych. Wybieramy polecenie Baza danych
| Dodaj bazę danych
. W otwartym oknie klikamy ikonę katalogu, aby otworzyć istniejącą bazę lub ikonę białego plusa na zielonym tle, kiedy tworzymy nową. Wtedy podajemy również nazwę pliku, np. studenci.db
. Po zatwierdzeniu dwa razy klikamy nazwę bazy w lewym panelu, aby nawiązać z nią połączenie.

Wykonywanie zapytań w programie SQLiteStudio możliwe jest po uruchomieniu edytora SQL: Narzędzia
| Otwórz edytor SQL
. W zakładce Zapytanie
wpisujemy lub wklejamy zapytania zakończone średnikiem. Klikamy ikonę niebieskiej strzałki lub naciskamy klawisz F9
, aby wykonać zapytanie, w którym ustawiony jest kursor.
![Ilustracja przedstawia Edytor poleceń SQL w programie SQLiteStudio. Okno zatytułowane jest: SQLiteStudio (3.4.1) – [Edytor SQL 1]. W górnej części paska menu widoczne są zakładki: Bazy danych, Struktura, Widoki, Narzędzia, Pomoc. Po lewej stronie, pod napisem Bazy danych znajduje się pionowe okno zatytułowane: Filtruj po nazwie. Poniżej znajduje się pozycja: studenci (SQLite 3), pod którą znajduje się napis: Tabele (1) oraz Widoki. W środkowej części znajdują się trzy równoległe okna. W górnym oknie znajdują się dwie zakładki: Zapytanie, Historia. Wybrana jest zakładka: Zapytanie. Wewnątrz tabeli widoczne jest 10 wierszy: 1 CREATE TABLE uczelnie ( 2 id_uczelni INTEGER PRIMARY KEY AUTOINCREMENT, nazwa VARCHAR(30) NOT NULL 4 ) ; 5 6 CREATE TABLE miasta ( 7 id_miasta INTEGER PRIMARY KEY AUTOINCREMENT, 8 nazwa VARCHAR(30) NOT NULL, kod CHAR (6) DEFAULT ‘ ‘ ); Cztery pierwsze wiersze są zaznaczone niebieskim kolorem. W środkowym oknie znajdują się dwie zakładki: Widok siatki, Widok formularza. Wybrana jest zakładka: Widok siatki. Okno jest puste. W dolnym oknie zatytułowanym Status znajduje się tekst: [20:51:01] Nowe aktualizacje są dostępne: Kliknij aby poznać szczegóły. [20:51:07 Zapytanie ukończone w 0,024 sekund(y). Na dole, w pasku po lewej stronie znajduje się prostokątne pole z napisem: Edytor SQL 1.](https://static.zpe.gov.pl/portal/f/res-minimized/RjL39pxG4IVaB/1690815814/2EQFtPlwj4kkFd1z0utFWF4Msu4kJywm.png)
Wiersz poleceń bazy SQLite3
To narzędzie opcjonalne i dlatego wymaga instalacji. W systemach Linux wiersz poleceń SQLite3 instalujemy za pomocą menedżera pakietów. Np. w systemach opartych na Debianie możemy użyć graficznego menedżera oprogramowania lub polecenia w terminalu: sudo apt install sqlite3
.
W systemie Windows ze strony www.sqlite.org
pobieramy archiwum o nazwie sqlite‑tools‑win32‑x86‑wersja.zip
i wypakowujemy jego zawartość do katalogu umieszczonego w ścieżce systemowej.
Narzędzie uruchamiamy w systemowym wierszu poleceń, wpisując nazwę: sqlite3
. Program uruchomi się, jeżeli będzie dostępny w ścieżce systemowej lub w bieżącym katalogu.

Pliki CSV
Dysponujemy zbiorem danych o studentach zawartym w pliku studenci.txt
. Nasze zadanie polega na zaprojektowaniu i utworzeniu odpowiedniej bazy danych w języku SQL, którą będzie można wykorzystać do analizy informacji dotyczących studentów, np. odpowiedzi na pytanie, ilu studentów ma dochód powyżej 1500 zł.
studenci.txt
.Otwórz plik studenci.txt
w edytorze tekstu, najlepiej programistycznymprogramistycznym. Postaraj się ustalić sposób kodowania polskich znaków i oznaczenie końca wierszy.

Po otwarciu pliku powinniśmy zobaczyć dane podzielone na wiersze. Znaki w plikach tekstowych zapisywane są z zastosowaniem różnych standardów kodowania, a także z różnymi oznaczeniami końca linii. Aktualnie obowiązującym standardem kodowania, stosowanym w systemach operacyjnych i internecie, jest system UTF‑8. Natomiast koniec wiersza kodowany jest inaczej w systemie Windows, gdzie oznaczany jest dwoma znakami specjalnymi: CR (ang. carriage return) i LF (ang. line Feed). Inaczej dzieje się w systemach Linux czy Mac OS, w których używa się pojedynczego znaku LF.
Edytory programistyczne zazwyczaj wyświetlają informacje o użytym systemie kodowania i o znakach końca linii w polu statusu. Umożliwiają również ewentualne konwersje. Jeżeli w otwartym pliku z danymi nie ma właściwego podziału na wiersze lub nie wyświetlają się znaki narodowe, powinniśmy dokonać konwersji dostosowanej do używanego systemu.
Po zbadaniu pliku studenci.txt
w edytorze programistycznym powinniśmy zauważyć, że użyto w nim kodowania UTF‑8 i znaku LF jako delimitera wierszydelimitera wierszy. Dalsze obserwacje:
pierwszy wiersz zawiera nagłówki kolumn,
w kolejnych wierszach znajdują się wartości poszczególnych pól dla danego studenta, czyli rekordy,
wartości w wierszach oddzielone są tym samym znakiem, w tym przypadku średnikiem.
Tego typu pliki tekstowe wykorzystują format CSVformat CSV (ang. comma‑separated values), jeden z najpowszechniejszych sposobów przechowywania i udostępniania (eksportowania/importowania) danych. Jak sama nazwa sugeruje, najczęstszym separatorem pól jest przecinek, ale mogą to też być inne znaki, np. średnik, spacja czy tabulator.
W obrębie jednego pliku należy używać jednego separatora. Jeżeli w wartościach pól występuje separator, należy go ujmować w podwójne cudzysłowy. Jeżeli w wartości występuje cudzysłów, należy wpisać go dwukrotnie, np.: 1;2020‑05‑01;"Tytuły: ""Ferdydurke""; ""Mistrz i Małgorzata""."
Format CSV jest bardzo dobrze obsługiwany przez arkusze kalkulacyjne (LibreOffice Calc, Microsoft Excel), bazy danych (LibreOffice Base, Microsoft Access) czy języki programowania (np. PHP, Python).
Projekt bazy
Dane w bazach relacyjnych przechowujemy w tabelach. W omawianym wypadku jeden plik źródłowy sugeruje, że moglibyśmy umieścić dane w jednej tabeli. Zastanówmy się, czy to dobry pomysł.

studenci.txt
zaimportowany do arkusza kalkulacyjnego.Zauważmy dublowanie się danych, np. w polu Uczelnia. W polu Miejsce_zam nie tylko powtarzają się wartości, ale nazwy miast połączone są z kodem pocztowym. Jeżeli dane umieścilibyśmy w jednej tabeli, otrzymalibyśmy dobry przykład tak zwanych anomalii baz danych, które dotyczą:
redundancji – powtarzanie informacji w różnych polach;
modyfikacji – zmiana informacji w różnych polach; informacja zostanie zmodyfikowana w pewnych krotkach, a w innych nie; ciężko zweryfikować wówczas, która informacja jest prawdziwa;
usuwania – usuwanie części informacji skutkuje usunięciem całości;
dodawania – wymóg dysponowania wszystkimi częściami informacji w celu jej dodania.
Normalizacja
Aby uniknąć wymienionych anomalii, stosuje się tak zwaną normalizacjęnormalizację, której głównym celem jest pozbycie się z bazy nadmiarowości informacji. W zależności od stopnia usunięcia redundancji mówimy o kolejnych postaciach normalnych bazy.
Teoria wyróżnia pięć postaci normalnych, w praktyce stosuje się tylko pierwsze trzy.
Nie wnikając w szczegóły kolejnych postaci, możemy zoptymalizować projekt bazy, kierując się następującymi zasadami:
informacje składające się z wielu części umieszczamy w osobnych kolumnach,
informacje powtarzające się rozdzielamy na różne tabele powiązane relacjami.
Jeśli zastosujemy te zasady, otrzymamy trzy pliki z danymi i odpowiadające im trzy tabele. Plik studenci.csv
będzie zawierał wiersze z następującymi kolumnami:
id_studenta – unikalny identyfikator studenta,
imie, nazwisko – imię, nazwisko,
id_uczelni – identyfikator uczelni,
id_miasta – identyfikator miasta,
rok_studiow – oznaczenie roku studiów,
dochod_na_osobe – dochód na osobę.
Plik uczelnie.csv
:
id_uczelni – unikalny identyfikator uczelni,
nazwa – nazwa uczelni.
Plik miasta.csv
:
id_miasta – unikalny identyfikator miasta,
nazwa – nazwa miasta (miejsca zamieszkania),
kod_pocztowy – kod pocztowy miasta.
Biorąc pod uwagę, że w obrębie jednego miasta może występować wiele kodów pocztowych, moglibyśmy rozważyć umieszczenie niepowtarzających się kodów pocztowych w osobnym pliku kody.csv
, który zawierałby dwie kolumny:
id_kodu – unikalny liczbowy identyfikator kodu,
kod_pocztowy – kod pocztowy miasta.
Wtedy z pliku miasta.csv
kolumnę kod_pocztowy
usunęlibyśmy. Natomiast do pliku studenci.csv
musielibyśmy dodać pole id_kodu
. Relacje między tabelami w bazie utworzonej do przechowywania danych w takim przypadku wyglądałby następująco:

Studenci
z osobną tabelę kody.Ponieważ w analizowanych danych każde miasto ma tylko jeden kod pocztowy, ograniczymy się do trzech opisanych plików.
Operację rozdzielenia powtarzających się informacji na osobne pliki najłatwiej przeprowadzić w arkuszu kalkulacyjnym. Proces ten omówiony jest w sekcji „Prezentacja multimedialna”.
Dane z poszczególnych plików przechowamy w trzech odpowiadających im tabelach:
Studenci | |
id | – liczba całkowita, klucz główny |
imie | – tekst |
nazwisko | – tekst |
id_uczelni | – liczba całkowita, klucz obcy |
id_miasta | – liczba całkowita, klucz obcy |
rok_studiow | – tekst |
dochod | – liczba dziesiętna |
Uczelnie | |
id | – liczba całkowita, klucz główny |
nazwa | – tekst |
Miasta | |
id | – liczba całkowita, klucz główny |
nazwa | – tekst |
kod_pocztowy | – tekst |
Definiowanie tabeli w języku SQL
Nazwy tabel, nazwy i typy kolumn (pól) oraz wskazanie kluczy głównych i obcych określają schemat bazy danychschemat bazy danych. Znając go, możemy napisać zapytanie, które utworzy odpowiednie tabele w bazie danych.
Instrukcje manipulujące bazą i tabelami należą do podgrupy poleceń SQL. Nazywa się ją skrótowo DDL (ang. Data Definition Language), czyli językiem definiowania danych. Do tworzenia tabel wykorzystamy klauzulę CREATE
.
Na podstawie schematu bazy można zauważyć, że pliki uczelnie.csv
i miasta.csv
zawierają dane charakterystyczne dla tabel słownikowychtabel słownikowych. Zacznijmy od ich definicji:
Instrukcja CREATE
tworzy tabelę o podanej nazwie. W okrągłych nawiasach definiujemy pola, to znaczy podajemy nazwę pola, następnie typ danych i ewentualne ograniczenia. Kolejne definicje pól oddzielamy przecinkiem.
Użyliśmy następujących typów danych:
INTEGER
– liczba całkowita,VARCHAR(30)
– ciąg o zmiennej długości, maksimum 30‑znakowy,CHAR(6)
– ciąg o stałej długości sześciu znaków.
Wprowadziliśmy również dodatkowe ograniczenia, precyzujące wymagania wobec wartości przechowywanych w kolejnych polach:
NOT NULL
– pole nie może zawierać wartościNULL
, czyli być puste,DEFAULT ''
– jeżeli nie podano wartości, użyta zostanie wartość domyślna, w tym wypadku pusty ciąg znaków.
Wartość NULL
oznacza brak wartości i nie jest tym samym, co pusty ciąg znaków, czyli ''
.
Analizując definicje obu tabel, możemy zauważyć, że:
klucz główny, czyli niepowtarzająca się w obrębie kolumny wartość, najczęściej jest liczbą całkowitą (typ INTEGER),
pola przechowujące tekst bywają różnie definiowane w zależności od systemu bazodanowego i rodzaju danych.
Spróbujmy teraz przetestować dotychczasowy kod. W programie SQLiteStudio tworzymy bazę studenci.db
, następnie uruchamiamy edytor SQL i wklejamy omówione zapytania. Wykonujemy pierwsze, a następnie drugie zapytanie. Na koniec w lewym panelu możemy rozwinąć listę Tabele
, aby przekonać się o ich utworzeniu.
![Ilustracja przedstawia Edytor poleceń SQL w programie SQLiteStudio. Okno zatytułowane jest: SQLiteStudio (3.4.1) – [Edytor SQL 1]. W górnej części paska menu widoczne są zakładki: Bazy danych, Struktura, Widoki, Narzędzia, Pomoc. Po lewej stronie, pod napisem Bazy danych znajduje się pionowe okno zatytułowane: Filtruj po nazwie. Poniżej znajduje się pozycja: studenci (SQLite 3), pod którą znajduje się napis: Tabele (2) z pozycjami pod spodem: miasta, Kolumny (3), id_miasta, nazwa, kod, Indeksy, Wyzwalacze, napis uczenie z pozycjami pod spodem: Kolumny (2), id_uczelni, nazwa, Indeksy, Wyzwalacze oraz z napisem Widoki. W środkowej części znajdują się trzy równoległe, poziome okna. W górnym oknie znajdują się dwie zakładki: Zapytanie, Historia. Wybrana jest zakładka: Zapytanie. Wewnątrz tabeli widoczne jest 10 wierszy: 1 CREATE TABLE uczelnie ( 2 id_uczelni INTEGER PRIMARY KEY AUTOINCREMENT, nazwa VARCHAR(30) NOT NULL 4 ) ; 5 6 CREATE TABLE miasta ( 7 id_miasta INTEGER PRIMARY KEY AUTOINCREMENT, 8 nazwa VARCHAR(30) NOT NULL, kod CHAR (6) DEFAULT ‘ ‘ ); Pięć ostatnich wierszy jest zaznaczonych niebieskim kolorem. W środkowym oknie znajdują się dwie zakładki: Widok siatki, Widok formularza. Wybrana jest zakładka: Widok siatki. Okno jest puste. W dolnym oknie zatytułowanym Status znajduje się tekst: [20:51:01] Nowe aktualizacje są dostępne: Kliknij aby poznać szczegóły. [20:51:07] Zapytanie ukończone w 0,024 sekund(y). [20:51:11] Zapytanie ukończone w 0,024 sekund(y). [20:51:13] Zapytanie ukończone w 0,024 sekund(y). Na dole, w pasku po lewej stronie znajduje się prostokątne pole z napisem: Edytor SQL 1.](https://static.zpe.gov.pl/portal/f/res-minimized/RBWMBtLkb02Bp/1690815816/1RlfcyXlEEa4TfwUoD138FHUMqNCwrNK.png)
Jak widać, w bazie są dwie tabele utworzone za pomocą użytych definicji.
Usuwanie tabel
Jeżeli spróbujemy wykonać przedstawione zapytania kolejny raz, otrzymamy komunikat: Błąd podczas wykonywania zapytania SQL
na bazie studenci: table uczelnie already exists
, który informuje, że dana tabela istnieje już w bazie. Dlatego dobrą praktyką jest poprzedzanie instrukcji CREATE
następującą klauzulą:
Instrukcja DROP TABLE IF EXISTS
usuwa podaną tabelę, jeżeli taka istnieje. Uwaga: razem z tabelą usuwane są dane! Alternatywnie można rozważyć użycie instrukcji:
W tym wypadku tabela zostanie utworzona, jeżeli jeszcze nie istnieje.
Dodaj pierwsze z przedstawionych poleceń przed definicjami obydwu tabel. Wykonaj kilka razy zapytania i zwróć uwagę na komunikaty w oknie Status
, informujące o tym, czy udało się je wykonać poprawnie.
Podczas pracy w programie SQLiteStudio w edytorze SQL upewnij się, że podłączona jest tylko jedna baza. W razie potrzeby kliknij nazwę nieużywanej bazy prawym klawiszem w panelu i wybierz polecenie Rozłącz się z bazą danych
.
Relacje
Przechodzimy do definicji tabeli studenci, która jest nieco trudniejsza, ponieważ tabela zawiera klucze obce, tworzące relacje z dwoma pozostałymi tabelami.
Zanim omówimy relacje, warto zwrócić uwagę na typ danych pola dochod. DECIMAL
służy do przechowywania liczb stałej precyzji, pierwsza cyfra w nawiasie oznacza maksymalną liczbę wszystkich cyfr, druga liczba – liczbę cyfr po separatorze. Maksymalna liczba, jaką można zapisać w polu, to 9999.99
– zwróćmy uwagę, że separatorem części ułamkowej jest kropka.
Relacje między tabelami wymagają klucza głównego (ang. primary key) w tabeli rodzica i klucza obcego (ang. foreign key) w tabeli dziecka. Klauzulę ograniczenia FOREIGN KEY ... REFERENCES ...
umieszczamy na końcu definicji pól, podając w nawiasach okrągłych nazwę klucza obcego, a następnie nazwę tabeli i klucza głównego w nawiasach okrągłych.
Typ pola będącego kluczem obcym musi odpowiadać typowi pola klucza głównego, którego wartość będzie w nim przechowywana.
Definiując relacje między tabelami, możemy określić, co ma się stać, gdy klucz główny w tabeli nadrzędnej zostanie usunięty – ON DELETE
lub zmieniony – ON UPDATE
. Do dyspozycji mamy następujące działania:
NO ACTIONS
– brak działania,RESTRICT
– oznacza, że zabraniamy usuwania/zmieniania klucza głównego, jeżeli istnieją powiązane z nim klucze obce,SET NULL
– w przypadku usunięcia/zmiany klucza głównego wartość zależnych kluczy obcych ustawiana jest naNULL
,SET DEFAULT
– w przypadku usunięcia/zmiany klucza głównego wartość zależnych kluczy obcych ustawiana jest na wartość domyślną,CASCADE
– usunięcie/zmiana klucza głównego powoduje usunięcie/zmianę klucza(y) obcego(ych).
Przykładowa definicja:
Składnia alternatywna dla definiowania relacji pozwala umieszczać klauzulę za definicją pola, np.
Należy jednak pamiętać, że przy użyciu składni alternatywnej nie możemy odwoływać się do złożonych kluczy głównych, to jest do takich, które składają się z dwóch lub więcej pól.
SQL w wierszu poleceń bazy
Pełny kod SQL, definiujący tabele bazy, zapisujemy w osobnym pliku o nazwie studenci.sql
. Kod SQL zapisany w pliku tekstowym można wykonać za pomocą wiersza poleceń wybranego systemu bazodanowego lub skryptu języka programowania, np. Python lub PHP.
Jeżeli wiersz poleceń nie jest dostępny w naszym systemie, kod możemy wykonać w edytorze SQL programu SQLiteStudio.
Użyjemy teraz systemowego wiersza poleceń, uruchomionego w katalogu z plikiem studenci.sql
. Wywołamy wiersz poleceń SQLite3 i wpiszemy kolejne instrukcje:

W pierwszym poleceniu po nazwie bazy używamy przekierowania (< studenci.sql
), aby wczytać plik z definicjami tabel. Brak komunikatów oznacza, że w pliku nie ma błędów składniowych. W drugim poleceniu otwieramy bazę danych w wierszu poleceń SQLite3. Poleceniem .table
wyświetlamy listę tabel, a następnie sprawdzamy ustawienia ograniczeń kluczy obcych.
W bazach SQLite3 ograniczenia FOREIGN KEY
są domyślnie wyłączone i jeżeli chcemy z nich korzystać, należy je włączyć instrukcją PRAGMA foreign_keys = ON;
.
Po włączeniu ograniczeń, próbujemy wykonać zapytanie dodające dane do tabeli studenci. Ponieważ podajemy nieistniejące w tabelach uczelnie i miasta identyfikatory jako wartości kluczy obcych, otrzymujemy błąd naruszenia ograniczeń: Error: FOREIGN KEY constraint failed
.
Słownik
znacznik końca wiersza
program do edycji plików źródłowych i pisania kodu w różnych językach programowania, prezentuje dokładne informacje o formacie pliku, wyposażony jest zazwyczaj w mechanizmy ułatwiające kodowanie, np. podświetlanie i uzupełnianie składni
standard zapisywania informacji z bazy danych w pliku tekstowym, w którym pola każdego rekordu oddzielone separatorem (np. przecinkiem), zapisywane są w kolejnych wierszach
przypisanie znakom (literom, cyfrom, znakom specjalnym) kodów liczbowych według określonego standardu, pozwalające zamienić tekst na reprezentację liczbową przetwarzaną przez komputer; podstawowym kodowaniem znaków używanym w informatyce jest kod ASCII; obecnie najczęściej stosuje się kodowanie Unicode UTF‑8, pozwalające zapisać każdy znak ze wszystkich alfabetów i pism na świecie
proces projektowania bazy danych eliminujący nadmiarowość danych i wynikające z niej anomalie poprzez odpowiednią organizację danych w tabelach oraz zdefiniowanie relacji
(ang. constraints) reguły definiujące, a później wymuszające cechy wartości przechowywanych w danym polu
schematyczny opis tabel (zwanych encjami), ich atrybutów (pól, kolumn) oraz ich typów danych, a także związków między tabelami, czyli relacji
tabela zawierająca listę wartości, np. nazwy miast, które powtarzają się w innej tabeli