{"id":519,"date":"2022-12-17T16:19:13","date_gmt":"2022-12-17T15:19:13","guid":{"rendered":"https:\/\/piotrgabriel.pl\/wiki\/?p=519"},"modified":"2023-09-05T09:20:05","modified_gmt":"2023-09-05T07:20:05","slug":"typy-relacji-bazy-danych-na-przykladzie-mysql","status":"publish","type":"post","link":"https:\/\/piotrgabriel.pl\/wiki\/typy-relacji-bazy-danych-na-przykladzie-mysql\/","title":{"rendered":"Typy relacji bazy danych na przyk\u0142adzie MySQL"},"content":{"rendered":"<p>Relacje w bazach danych s\u0105 u\u017cywane do okre\u015blenia sposobu, w jaki dane s\u0105 powi\u0105zane ze sob\u0105. Dowiedz si\u0119 jakie s\u0105 typy relacji w bazach danych. <!--more--><\/p>\n<h2>Importancja kluczy obcych<\/h2>\n<p>Aby zrozumie\u0107 relacje, wa\u017cne jest tak\u017ce zrozumienie koncepcji kluczy obcych. Klucz obcy to kolumna lub zestaw kolumn w jednej tabeli, kt\u00f3re odnosz\u0105 si\u0119 do klucza g\u0142\u00f3wnego w innej tabeli. Klucze obce s\u0142u\u017c\u0105 do \u0142\u0105czenia tabel i utrzymania integralno\u015bci danych.<\/p>\n<h2>Relacje i normalizacja<\/h2>\n<p>Relacje w bazach danych s\u0105 r\u00f3wnie\u017c kluczem do procesu zwanego normalizacj\u0105. Normalizacja to proces organizowania danych w bazie danych w celu zmniejszenia nadmiarowo\u015bci i unikni\u0119cia niepo\u017c\u0105danych cech, takich jak anomalie wstawiania, aktualizacji i usuwania. Poprzez odpowiednie stosowanie relacji, mo\u017cna osi\u0105gn\u0105\u0107 dobrze znormalizowan\u0105 baz\u0119 danych, kt\u00f3ra jest wydajna i \u0142atwa w zarz\u0105dzaniu.<\/p>\n<h2>Wykorzystanie relacji w praktyce<\/h2>\n<p>Kiedy projektujemy baz\u0119 danych, wa\u017cne jest, aby dok\u0142adnie przemy\u015ble\u0107 relacje mi\u0119dzy tabelami. Dobrze zaprojektowane relacje pomog\u0105 zapewni\u0107, \u017ce baza danych b\u0119dzie skalowalna, wydajna i \u0142atwa w utrzymaniu.<\/p>\n<p>Zastan\u00f3wmy si\u0119, jakie mog\u0105 by\u0107 potencjalne problemy z nieprawid\u0142owo zaprojektowanymi relacjami:<\/p>\n<ul>\n<li><strong>Niesp\u00f3jno\u015b\u0107 danych<\/strong>: Je\u015bli relacje nie s\u0105 prawid\u0142owo zaprojektowane, mo\u017cemy napotka\u0107 problemy z niesp\u00f3jno\u015bci\u0105 danych. Na przyk\u0142ad, je\u015bli mamy tabel\u0119 &#8222;Klienci&#8221; i tabel\u0119 &#8222;Zam\u00f3wienia&#8221;, ale nie mamy odpowiedniej relacji mi\u0119dzy nimi, mo\u017ce si\u0119 zdarzy\u0107, \u017ce usuniemy klienta, ale jego zam\u00f3wienia nadal b\u0119d\u0105 istnia\u0142y w bazie danych.<\/li>\n<li><strong>Nadmiarowe dane<\/strong>: Bez odpowiednich relacji mo\u017cemy mie\u0107 nadmiarowe dane w bazie danych. Na przyk\u0142ad, je\u015bli mamy tabel\u0119 &#8222;Klienci&#8221; i ka\u017cdy klient ma adres, ale nie mamy osobnej tabeli &#8222;Adresy&#8221; po\u0142\u0105czonej relacj\u0105 z tabel\u0105 &#8222;Klienci&#8221;, ka\u017cdy rekord klienta b\u0119dzie musia\u0142 zawiera\u0107 pe\u0142ne informacje adresowe, co prowadzi do nadmiaru danych.<\/li>\n<li><strong>Trudno\u015bci w aktualizacji<\/strong>: Bez odpowiednich relacji aktualizacja danych w bazie danych mo\u017ce by\u0107 trudna. Na przyk\u0142ad, je\u015bli chcemy zmieni\u0107 adres klienta, ale nie mamy odpowiedniej relacji mi\u0119dzy tabelami &#8222;Klienci&#8221; i &#8222;Adresy&#8221;, musimy wyszuka\u0107 ka\u017cde miejsce, w kt\u00f3rym ten adres jest przechowywany, i zaktualizowa\u0107 go r\u0119cznie.<\/li>\n<\/ul>\n<h2>Przyk\u0142ady zastosowania r\u00f3\u017cnych typ\u00f3w relacji w bazach danych<\/h2>\n<p>W systemach zarz\u0105dzania bazami danych, takich jak MySQL, istniej\u0105 r\u00f3\u017cne typy relacji, kt\u00f3re mo\u017cna utworzy\u0107 mi\u0119dzy tabelami. Oto kilka przyk\u0142ad\u00f3w:<\/p>\n<ol>\n<li><strong>Jedno do jednego (1:1)<\/strong> &#8211; ta relacja wyst\u0119puje, gdy ka\u017cdy rekord w jednej tabeli ma dok\u0142adnie jeden odpowiadaj\u0105cy rekord w drugiej tabeli. Przyk\u0142adem mo\u017ce by\u0107 relacja mi\u0119dzy tabelami &#8222;klienci&#8221; i &#8222;adresy&#8221;, gdzie ka\u017cdy klient ma dok\u0142adnie jeden adres.<\/li>\n<li><strong>Jedno do wielu (1:n)<\/strong> &#8211; ta relacja wyst\u0119puje, gdy jeden rekord w jednej tabeli mo\u017ce mie\u0107 wiele odpowiadaj\u0105cych rekord\u00f3w w drugiej tabeli. Przyk\u0142adem mo\u017ce by\u0107 relacja mi\u0119dzy tabelami &#8222;produkty&#8221; i &#8222;zam\u00f3wienia&#8221;, gdzie jeden produkt mo\u017ce by\u0107 zamawiany wielokrotnie przez r\u00f3\u017cnych klient\u00f3w.<\/li>\n<li><strong>Wiele do wielu (n:m)<\/strong> &#8211; ta relacja wyst\u0119puje, gdy rekordy w jednej tabeli mog\u0105 mie\u0107 wiele odpowiadaj\u0105cych rekord\u00f3w w drugiej tabeli, a rekordy w drugiej tabeli mog\u0105 mie\u0107 wiele odpowiadaj\u0105cych rekord\u00f3w w pierwszej tabeli. Przyk\u0142adem mo\u017ce by\u0107 relacja mi\u0119dzy tabelami &#8222;klienci&#8221; i &#8222;produkty&#8221;, gdzie jeden klient mo\u017ce kupi\u0107 wiele produkt\u00f3w, a jeden produkt mo\u017ce by\u0107 kupiony przez wielu klient\u00f3w.<\/li>\n<\/ol>\n<h3>Przyk\u0142ad relacji Jeden do jednego (1:1)<\/h3>\n<p>W bazie danych firmy mo\u017ce by\u0107 tabela &#8222;Pracownicy&#8221; zawieraj\u0105ca informacje o pracownikach, oraz tabela &#8222;Samochody&#8221; zawieraj\u0105ca informacje o samochodach, kt\u00f3re pracownicy mog\u0105 wynaj\u0105\u0107. Relacja jeden do jednego mi\u0119dzy tymi tabelami pozwoli nam po\u0142\u0105czy\u0107 ka\u017cdego pracownika z jednym samochodem, tak aby\u015bmy mogli sprawdzi\u0107, kt\u00f3ry pracownik wynajmuje dany samoch\u00f3d.<\/p>\n<p>Aby utworzy\u0107 relacj\u0119 jeden do jednego w MySQL, mo\u017cemy doda\u0107 do tabeli &#8222;Pracownicy&#8221; kolumn\u0119 zawieraj\u0105c\u0105 klucz obcy z tabeli &#8222;Samochody&#8221;, a do tabeli &#8222;Samochody&#8221; kolumn\u0119 zawieraj\u0105c\u0105 klucz obcy z tabeli &#8222;Pracownicy&#8221;. Nast\u0119pnie mo\u017cemy skorzysta\u0107 z polecenia CREATE INDEX, aby utworzy\u0107 indeksy na tych kolumnach, co umo\u017cliwi szybkie wyszukiwanie i \u0142\u0105czenie rekord\u00f3w z obu tabel.<\/p>\n<p>Na przyk\u0142ad, polecenie:<\/p>\n<p><code>CREATE TABLE Pracownicy ( id INT PRIMARY KEY, imie VARCHAR(255), nazwisko VARCHAR(255), samochod_id INT, FOREIGN KEY (samochod_id) REFERENCES Samochody(id) );<\/code><\/p>\n<p><code>CREATE TABLE Samochody ( id INT PRIMARY KEY, marka VARCHAR(255), model VARCHAR(255), pracownik_id INT, FOREIGN KEY (pracownik_id) REFERENCES Pracownicy(id) );<\/code><\/p>\n<p><code>CREATE INDEX idx_pracownicy_samochod ON Pracownicy (samochod_id); CREATE INDEX idx_samochody_pracownik ON Samochody (pracownik_id);<\/code><\/p>\n<p>Mo\u017cemy teraz dla przyk\u0142adu doda\u0107 nowego pracownika za pomoc\u0105 polecenia INSERT:<\/p>\n<p><code>INSERT INTO Pracownicy (id, imie, nazwisko, samochod_id) VALUES (1, 'Jan', 'Kowalski', 1);<\/code><\/p>\n<p>Mo\u017cemy tak\u017ce doda\u0107 nowy samoch\u00f3d za pomoc\u0105 polecenia INSERT:<\/p>\n<p><code>INSERT INTO Samochody (id, marka, model, pracownik_id) VALUES (1, 'Ford', 'Focus', 1);<\/code><\/p>\n<p>Po dodaniu tych rekord\u00f3w, relacja jeden do jednego mi\u0119dzy tabelami &#8222;Pracownicy&#8221; i &#8222;Samochody&#8221; b\u0119dzie w pe\u0142ni aktywna. Mo\u017cemy teraz wyszukiwa\u0107 informacje o pracownikach i samochodach, \u0142\u0105cz\u0105c je za pomoc\u0105 kluczy obcych.<\/p>\n<p>Na przyk\u0142ad, mo\u017cemy wy\u015bwietli\u0107 imi\u0119 i nazwisko pracownika oraz mark\u0119 i model samochodu za pomoc\u0105 z\u0142\u0105czenia tabel za pomoc\u0105 polecenia SELECT:<\/p>\n<p><code>SELECT Pracownicy.imie, Pracownicy.nazwisko, Samochody.marka, Samochody.model FROM Pracownicy JOIN Samochody ON Pracownicy.samochod_id = Samochody.id;<\/code><\/p>\n<h3>Przyk\u0142ad relacji Jeden do wielu (1:n)<\/h3>\n<p>Relacja jeden do wielu w MySQL mo\u017ce by\u0107 reprezentowana przez dwa tabele po\u0142\u0105czone kluczem obcym. Na przyk\u0142ad, tabela &#8222;Rodzice&#8221; mo\u017ce mie\u0107 kolumn\u0119 &#8222;ID Rodzica&#8221; jako klucz g\u0142\u00f3wny, a tabela &#8222;Dzieci&#8221; mo\u017ce mie\u0107 kolumn\u0119 &#8222;ID Rodzica&#8221; jako klucz obcy, kt\u00f3ry odnosi si\u0119 do kolumny &#8222;ID Rodzica&#8221; w tabeli &#8222;Rodzice&#8221;. W takim przypadku relacja mi\u0119dzy tabelami jest jeden do wielu, poniewa\u017c jeden rodzic mo\u017ce mie\u0107 wiele dzieci, ale ka\u017cde dziecko ma tylko jednego rodzica.<\/p>\n<p><code>CREATE TABLE Rodzice (<\/code><br \/>\n<code>ID Rodzica INT PRIMARY KEY,<\/code><br \/>\n<code>Imie VARCHAR(255),<\/code><br \/>\n<code>Nazwisko VARCHAR(255)<\/code><br \/>\n<code>);<\/code><\/p>\n<p><code>CREATE TABLE Dzieci (<\/code><br \/>\n<code>ID Dziecka INT PRIMARY KEY,<\/code><br \/>\n<code>ID Rodzica INT,<\/code><br \/>\n<code>Imie VARCHAR(255),<\/code><br \/>\n<code>FOREIGN KEY (ID-Rodzica) REFERENCES Rodzice(ID Rodzica)<\/code><br \/>\n<code>);<\/code><\/p>\n<p><code>INSERT INTO Rodzice (ID-Rodzica, Imie, Nazwisko)<\/code><br \/>\n<code>VALUES<\/code><br \/>\n<code>(1, 'Jan', 'Kowalski'),<\/code><br \/>\n<code>(2, 'Anna', 'Nowak');<\/code><\/p>\n<p><code>INSERT INTO Dzieci (ID-Dziecka, ID Rodzica, Imie)<\/code><br \/>\n<code>VALUES<\/code><br \/>\n<code>(1, 1, 'Janek'),<\/code><br \/>\n<code>(2, 1, 'Ania'),<\/code><br \/>\n<code>(3, 2, 'Piotrek');<\/code><\/p>\n<p>Teraz, \u017ceby wy\u015bwietli\u0107 wszystkie dzieci, rodzica o na przyklad ID-Rodzica r\u00f3wnym 2, piszemy<\/p>\n<p><code><span class=\"hljs-keyword\">SELECT<\/span> Imie <span class=\"hljs-keyword\">FROM<\/span> Dzieci <span class=\"hljs-keyword\">WHERE<\/span> ID-Rodzica <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">2<\/span>;<\/code><\/p>\n<p>Ta kwerenda pobierze wszystkie rekordy z tabeli &#8222;Dzieci&#8221;, gdzie kolumna &#8222;ID Rodzica&#8221; ma warto\u015b\u0107 2, i wy\u015bwietli imiona tych dzieci. W przyk\u0142adzie danych podanym wcze\u015bniej, ta kwerenda zwr\u00f3ci jeden rekord: &#8222;Piotrek&#8221;.<\/p>\n<h3>Przyk\u0142ad relacji wielu do wielu (n:m)<\/h3>\n<p>Relacja wiele do wielu w MySQL mo\u017ce by\u0107 reprezentowana przez trzy tabele: dwie tabele reprezentuj\u0105ce obie strony relacji oraz trzeci\u0105 tabel\u0119, kt\u00f3ra \u0142\u0105czy te dwie tabele. Na przyk\u0142ad, je\u015bli chcemy utworzy\u0107 relacj\u0119 mi\u0119dzy tabelami &#8222;U\u017cytkownicy&#8221; i &#8222;Grupy&#8221;, mo\u017cemy utworzy\u0107 tabel\u0119 &#8222;U\u017cytkownicy-Grupy&#8221;, kt\u00f3ra b\u0119dzie zawiera\u0142a dwie kolumny &#8222;ID U\u017cytkownika&#8221; i &#8222;ID Grupy&#8221; jako klucze obce odnosz\u0105ce si\u0119 do odpowiednich kolumn w tabelach &#8222;U\u017cytkownicy&#8221; i &#8222;Grupy&#8221;.<\/p>\n<p>W takim przypadku relacja mi\u0119dzy tabelami jest wiele do wielu, poniewa\u017c wiele u\u017cytkownik\u00f3w mo\u017ce nale\u017ce\u0107 do wielu grup, a wiele grup mo\u017ce zawiera\u0107 wiele u\u017cytkownik\u00f3w.<\/p>\n<p><code>CREATE TABLE Uzytkownicy (<\/code><br \/>\n<code>ID-Uzytkownika INT PRIMARY KEY,<\/code><br \/>\n<code>Imie VARCHAR(255),<\/code><br \/>\n<code>Nazwisko VARCHAR(255)<\/code><br \/>\n<code>);<\/code><\/p>\n<p><code>CREATE TABLE Grupy (<\/code><br \/>\n<code>ID Grupy INT PRIMARY KEY,<\/code><br \/>\n<code>Nazwa Grupy VARCHAR(255)<\/code><br \/>\n<code>);<\/code><\/p>\n<p><code>CREATE TABLE Uzytkownicy-Grupy (<\/code><br \/>\n<code>ID U\u017cytkownika INT,<\/code><br \/>\n<code>ID Grupy INT,<\/code><br \/>\n<code>PRIMARY KEY (ID-Uzytkownika, ID Grupy),<\/code><br \/>\n<code>FOREIGN KEY (ID-Uzytkownika) REFERENCES Uzytkownicy(ID-Uzytkownika),<\/code><br \/>\n<code>FOREIGN KEY (ID-Grupy) REFERENCES Grupy(ID-Grupy)<\/code><br \/>\n<code>);<\/code><\/p>\n<p><code>INSERT INTO Uzytkownicy (ID-Uzytkownika, Imie, Nazwisko)<\/code><br \/>\n<code>VALUES (1, 'Jan', 'Kowalski'), (2, 'Anna', 'Nowak'), (3, 'Piotr', 'Wi\u015bniewski');<\/code><\/p>\n<p><code>INSERT INTO Grupy (ID-Grupy, Nazwa-Grupy)<\/code><br \/>\n<code>VALUES (1, 'Grupa 1'), (2, 'Grupa 2'), (3, 'Grupa 3');<\/code><\/p>\n<p><code>INSERT INTO Uzytkownicy-Grupy (ID-Uzytkownika, ID Grupy)<\/code><br \/>\n<code>VALUES (1, 1), (1, 2), (2, 2), (2, 3), (3, 1), (3, 3);<\/code><\/p>\n<p>Aby wy\u015bwietli\u0107 wszystkich u\u017cytkownik\u00f3w z grupy o ID 2, mo\u017cna u\u017cy\u0107 nast\u0119puj\u0105cej kwerendy:<\/p>\n<p><code>SELECT Imie, Nazwisko FROM Uzytkownicy<\/code><br \/>\n<code>JOIN Uzytkownicy-Grupy ON Uzytkownicy.ID Uzytkownika = Uzytkownicy-Grupy.ID-Uzytkownika<\/code><br \/>\n<code>WHERE Uzytkownicy-Grupy.ID-Grupy = 2;<\/code><\/p>\n<p>Ta kwerenda \u0142\u0105czy tabele &#8222;U\u017cytkownicy&#8221; i &#8222;U\u017cytkownicy-Grupy&#8221; za pomoc\u0105 operatora <code>JOIN<\/code> i ogranicza wynik do tych rekord\u00f3w, kt\u00f3re spe\u0142niaj\u0105 warunek &#8222;U\u017cytkownicy-Grupy.ID Grupy = 2&#8221;. W przyk\u0142adzie danych podanym wcze\u015bniej, ta kwerenda zwr\u00f3ci dwa rekordy: &#8222;Jan Kowalski&#8221; i &#8222;Anna Nowak&#8221;.<\/p>\n<h2>Wnioski<\/h2>\n<p>Zrozumienie relacji w bazach danych i ich prawid\u0142owe stosowanie jest kluczem do tworzenia wydajnych, skalowalnych i \u0142atwych w zarz\u0105dzaniu baz danych. Poprzez efektywne wykorzystanie relacji, mo\u017cemy zapewni\u0107 integralno\u015b\u0107 danych, eliminowa\u0107 nadmiarowo\u015b\u0107 i upro\u015bci\u0107 proces aktualizacji danych.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Relacje w bazach danych s\u0105 u\u017cywane do okre\u015blenia sposobu, w jaki dane s\u0105 powi\u0105zane ze sob\u0105. Dowiedz si\u0119 jakie s\u0105 typy relacji w bazach danych.<\/p>\n","protected":false},"author":1,"featured_media":155,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48],"tags":[224,24],"class_list":["post-519","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bazy-danych","tag-bazy-danych","tag-mysql"],"_links":{"self":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/519","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/comments?post=519"}],"version-history":[{"count":0,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/519\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/media\/155"}],"wp:attachment":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/media?parent=519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/categories?post=519"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/tags?post=519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}