Relacioni që përmban çelësin e huaj quhet. Kufizimet kryesore dhe të huaja. Fig.3.4. Një grup i normalizuar i marrëdhënieve

Përditësimi i fundit: 07/02/2017

Bazat e të dhënave mund të përmbajnë tabela që janë të ndërlidhura me lidhje të ndryshme. Një marrëdhënie përfaqëson një lidhje midis entiteteve të llojeve të ndryshme.

Kur zgjidhni një marrëdhënie, zgjidhet një tabelë primare ose prind (tabela e çelësit kryesor / tabela kryesore) dhe një tabelë e varur, fëmijë (tabela e çelësit të huaj / tabela e fëmijëve). Tabela e fëmijëve varet nga tabela e prindërve.

Çelësat e huaj përdoren për të organizuar komunikimin. Një çelës i huaj përfaqëson një ose më shumë kolona nga një tabelë që është gjithashtu një çelës i mundshëm nga një tabelë tjetër. Çelësi i huaj nuk duhet të përputhet me çelësin kryesor nga tabela kryesore. Megjithëse, si rregull, një çelës i huaj nga një tabelë e varur tregon një çelës primar nga tabela kryesore.

Marrëdhëniet ndërmjet tabelave janë të llojeve të mëposhtme:

    Nje pas nje

    Një për shumë

    shumë për shumë(Shumë për shumë)

Një me një komunikim

Ky lloj lidhjeje nuk gjendet shpesh. Në këtë rast, një objekt i një entiteti mund të shoqërohet vetëm me një objekt të një entiteti tjetër. Për shembull, në disa sajte një përdorues mund të ketë vetëm një blog. Kjo do të thotë, lind një marrëdhënie: një përdorues - një blog.

Shpesh ky lloj marrëdhënie përfshin ndarjen e një tavoline të madhe në disa të vogla. Tabela primar primar në këtë rast vazhdon të përmbajë të dhëna të aksesuara shpesh, ndërsa tabela e varur nga fëmijët zakonisht ruan të dhëna që aksesohen më rrallë.

Në këtë drejtim, çelësi primar i tabelës së varur është në të njëjtën kohë një çelës i huaj që i referohet çelësit primar të tabelës kryesore.

Për shembull, tabela e Përdoruesve përfaqëson përdoruesit dhe ka kolonat e mëposhtme:

    ID-ja e përdoruesit (id, çelësi kryesor)

    Emri (emri i përdoruesit)

Dhe tabela Blogs përfaqëson blogjet e përdoruesve dhe ka kolonat e mëposhtme:

    BlogId (identifikuesi, çelësi kryesor dhe i huaj)

    Emri (emri i blogut)

Në këtë rast, kolona BlogId do të ruajë vlerën nga kolona UserId nga tabela e përdoruesve. Kjo do të thotë, kolona BlogId do të veprojë si një çelës kryesor dhe një çelës i huaj.

Marrëdhënie një me shumë

Ky është lloji më i zakonshëm i lidhjes. Në këtë lloj marrëdhënieje, shumë rreshta nga një tabelë fëmijë varen nga një rresht i vetëm në tabelën mëmë. Për shembull, një blog mund të ketë disa artikuj. Në këtë rast, tabela e blogjeve është prindi dhe tabela e artikujve është fëmija. Kjo është, një blog - shumë artikuj. Ose një shembull tjetër, disa futbollistë mund të luajnë në një ekip futbolli. Dhe në të njëjtën kohë, një futbollist mund të luajë vetëm në një ekip në të njëjtën kohë. Kjo do të thotë, një ekip - shumë lojtarë.

Për shembull, le të kemi një tabelë të quajtur Artikuj që përfaqëson artikujt e blogut dhe ka kolonat e mëposhtme:

    ArticleId (id, çelësi primar)

    BlogId (çelës i huaj)

    Titulli (titulli i artikullit)

    Teksti (teksti i artikullit)

Në këtë rast, kolona BlogId nga tabela e artikujve do të ruajë vlerën nga kolona BlogId nga tabela e blogeve.

marrëdhënie shumë e shumë

Me këtë lloj marrëdhënieje, një rresht nga tabela A mund të shoqërohet me shumë rreshta nga tabela B. Nga ana tjetër, një rresht nga tabela B mund të shoqërohet me shumë rreshta nga tabela A. Një shembull tipik janë studentët dhe kurset: një student mund të marrin disa kurse, dhe në përputhje me rrethanat disa studentë mund të regjistrohen në një kurs.

Një shembull tjetër janë artikujt dhe etiketat: disa etiketa mund të përcaktohen për një artikull dhe një etiketë mund të përcaktohet për disa artikuj.

Por në SQL Server, në nivelin e bazës së të dhënave, ne nuk mund të krijojmë një marrëdhënie të drejtpërdrejtë shumë-me-shumë midis dy tabelave. Kjo bëhet përmes një tabele ndihmëse të skenës. Ndonjëherë të dhënat nga kjo tabelë skedike përfaqësojnë një entitet të veçantë.

Për shembull, në rastin e artikujve dhe etiketave, le të ketë një tabelë Etiketash që ka dy kolona:

    TagId (identifikuesi, çelësi kryesor)

    Teksti (teksti i etiketës)

Le të ketë gjithashtu një tabelë të ndërmjetme Artikull Tags me fushat e mëposhtme:

    TagId (identifikuesi, çelësi kryesor dhe i huaj)

    ArticleId (identifikuesi, çelësi kryesor dhe i huaj)

Teknikisht, ne do të marrim dy marrëdhënie një-me-shumë. Kolona TagId nga tabela ArticleTags do t'i referohet kolonës TagId nga tabela Tags. Dhe kolona ArticleId nga tabela ArticleTags do t'i referohet kolonës ArticleId nga tabela Artikuj. Kjo do të thotë, kolonat TagId dhe ArticleId në tabelën ArticleTags përfaqësojnë një çelës primar të përbërë dhe janë gjithashtu çelësa të huaj për marrëdhënien me tabelat Artikuj dhe Etiketa.

Integriteti i të dhënave referente

Kur ndryshoni çelësat kryesorë dhe të huaj, duhet të respektoni aspektin e mëposhtëm: integriteti i të dhënave referente(integriteti i referencës). Ideja e tij themelore është për dy tabela në një bazë të dhënash që ruajnë të njëjtat të dhëna për të ruajtur qëndrueshmërinë. Integriteti i të dhënave paraqet marrëdhënie të ndërtuara saktë ndërmjet tabelave me lidhje të sakta ndërmjet tyre. Në cilat raste mund të cenohet integriteti i të dhënave:

    Anomali e fshirjes(anomali e fshirjes). Ndodh kur një rresht fshihet nga tabela kryesore. Në këtë rast, çelësi i huaj nga tabela e varur vazhdon të referojë rreshtin e fshirë nga tabela kryesore

    Anomalia e futjes(anomalia e futjes). Ndodh kur një rresht futet në një tabelë të varur. Në këtë rast, çelësi i huaj nga tabela e varur nuk përputhet me çelësin primar të asnjë prej rreshtave nga tabela kryesore.

    Përditëso Anomalitë(anomalia e përditësimit). Me një anomali të tillë, disa rreshta të së njëjtës tabelë mund të përmbajnë të dhëna që i përkasin të njëjtit objekt. Kur ndryshoni të dhënat në një rresht, ato mund të bien ndesh me të dhënat në një rresht tjetër.

Anomali e fshirjes

Për të zgjidhur një anomali të fshirjes, duhet të vendosni një nga dy kufizimet në një çelës të huaj:

    Nëse një rresht nga një tabelë e varur kërkon domosdoshmërisht një rresht nga tabela kryesore, atëherë vendoset një fshirje në kaskadë për çelësin e huaj. Kjo do të thotë, kur një rresht fshihet nga tabela kryesore, rreshtat e lidhur fshihen nga tabela e varur.

    Nëse një rresht nga një tabelë e varur nuk lejon asnjë lidhje me një rresht nga tabela kryesore (d.m.th., një lidhje e tillë është opsionale), atëherë çelësi i huaj vendoset në NULL kur rreshti përkatës fshihet nga tabela kryesore. Kolona e çelësit të huaj duhet të jetë e pavlefshme.

Anomalia e futjes

Për të zgjidhur një anomali të futjes kur shtoni të dhëna në një tabelë të varur, kolona që përfaqëson çelësin e huaj duhet të jetë e pavlefshme. Dhe kështu, nëse objekti i shtuar nuk ka lidhje me tabelën kryesore, atëherë kolona e çelësit të huaj do të përmbajë një vlerë NULL.

Përditëso anomalitë

Për të zgjidhur problemin e anomalisë së përditësimit, përdoret normalizimi, i cili do të diskutohet më vonë.

Përditësimi i fundit: 27.04.2019

Çelësat e huaj ju lejojnë të vendosni marrëdhënie midis tabelave. Një çelës i huaj vendoset në kolonat nga një tabelë e varur, e varur dhe tregon njërën nga kolonat nga tabela kryesore. Në mënyrë tipike, një çelës i huaj tregon një çelës primar nga një tabelë kryesore përkatëse.

Sintaksa e përgjithshme për vendosjen e një çelësi të huaj në nivelin e tabelës është:

ÇELËSI I HUAJ (kolona1, kolona 2, ... kolonaN) REFERENCAT tabela_kryesore (tabela_kryesore_kolona1, tabela_kryesore_kolona2, ... kryesore_tabela_kolonaN)

Për të krijuar një kufizim të çelësit të huaj, pas ÇELËSIT TË HUAJ ju specifikoni kolonën e tabelës që do të përfaqësojë çelësin e huaj. Dhe pas fjalës kyçe REFERENCAT, tregohet emri i tabelës përkatëse, dhe më pas në kllapa emri i kolonës përkatëse në të cilën do të tregojë çelësi i huaj. Pas shprehjes REFERENCES janë shprehjet ON DELETE dhe ON UPDATE, të cilat specifikojnë veprimin kur fshihet dhe përditësohet një rresht nga tabela kryesore, përkatësisht.

Për shembull, le të përcaktojmë dy tabela dhe t'i lidhim ato duke përdorur një çelës të huaj:

KRIJO klientë TABELE (ID INT PRIMARY KEY AUTO_INCREMENT, Mosha INT, Emri VARCHAR(20) NOT NULL, Mbiemri VARCHAR(20) NOT NULL, Telefon VARCHAR(20) NOT NULL UNIQUE); KRIJO TABELA E porosive (ID INT PRIMARY KEY AUTO_INCREMENT, CustomerId INT, CreatedAtDate, ÇELËSI I HUAJ (CustomerId) REFERENCAT Klientët (Id));

Në këtë rast, përcaktohen tabelat Klientët dhe Porositë. Klienti është kryesori dhe përfaqëson klientin. Porositë janë të varura dhe përfaqësojnë porosinë e bërë nga klienti. Tabela e porosive është e lidhur përmes kolonës CustomerId me tabelën e klientëve dhe kolonën e saj ID. Kjo do të thotë, kolona CustomerId është një çelës i huaj që tregon kolonën Id nga tabela Customers.

Ju mund të përdorni operatorin CONSTRAINT për të specifikuar një emër për një kufizim të çelësit të huaj:

CREATE TABLE Orders (ID INT PRIMARY KEY AUTO_INCREMENT, CustomerId INT, CreatedAt Date, CONSTRAINT orders_custonmers_fk ÇELËSI I HUAJ (CustomerId) REFERENCAT Klientët (Id));

NË FSHIJE dhe NË PËRDITËSIM

Duke përdorur deklaratat ON DELETE dhe ON UPDATE, mund të vendosni veprimet që kryhen kur një rresht i lidhur fshihet ose modifikohet, përkatësisht, nga tabela kryesore. Opsionet e mëposhtme mund të përdoren si veprim:

    CASCADE: Fshin ose modifikon automatikisht rreshtat nga një tabelë e varur kur rreshtat e lidhur në tabelën kryesore fshihen ose modifikohen.

    SET NULL: Kur fshini ose përditësoni një rresht të lidhur nga tabela kryesore, vendos kolonën e çelësit të huaj në NULL. (Në këtë rast, kolona e çelësit të huaj duhet të mbështesë cilësimin NULL)

    RESTRICT: Refuzon fshirjen ose modifikimin e rreshtave në tabelën kryesore nëse ka rreshta të lidhur në tabelën e varur.

    JO VEPRIM: njësoj si KUFIZIMI.

    SET DEFAULT: Kur fshini një rresht të lidhur nga tabela kryesore, vendos kolonën e çelësit të huaj në vlerën e paracaktuar që është specifikuar duke përdorur atributin DEFAULT. Përkundër faktit se ky opsion është i disponueshëm në parim, motori InnoDB nuk e mbështet këtë shprehje.

Fshirje në kaskadë

Fshirja Cascading ju lejon të fshini automatikisht të gjitha rreshtat e lidhur nga tabela e varur kur fshini një rresht nga tabela kryesore. Për ta bërë këtë, përdorni opsionin CASCADE:

KRIJO TABELA E porosive (ID INT PRIMARY KEY AUTO_INCREMENT, CustomerId INT, CreatedAt Date, ÇELËSI I HUAJ (CustomerId) REFERENCAT Klientët (ID) ON DELETE CASCADE);

Shprehja ON UPDATE CASCADE funksionon në mënyrë të ngjashme. Kur ndryshoni vlerën e një çelësi primar, vlera e çelësit të huaj të lidhur me të ndryshon automatikisht. Sidoqoftë, meqenëse çelësat parësorë ndryshojnë shumë rrallë dhe në përgjithësi nuk rekomandohet përdorimi i kolonave me vlera të ndryshueshme si çelësa kryesorë, shprehja ON UPDATE përdoret rrallë në praktikë.

Vendosja NULL

Kur vendosni opsionin SET NULL për një çelës të huaj, kolona e çelësit të huaj duhet të lejohet nga NULL:

KRIJO TABELA E porosive (ID INT PRIMARY KEY AUTO_INCREMENT, CustomerId INT, CreatedAt Date, ÇELËSI I HUAJ (CustomerId) REFERENCAT Klientët (Id) NË DELETE SET NULL);

Figura tregon një tabelë (një raport i shkallës 5) që përmban disa informacione për punonjësit e një ndërmarrje hipotetike. Rreshtat e tabelave korrespondojnë me tuples. Çdo rresht është në fakt një përshkrim i një objekti të botës reale (në këtë rast, një punëtori), karakteristikat e të cilit përmbahen në kolona. Marrëdhëniet relacionale korrespondojnë me grupe entitetesh dhe tuplet korrespondojnë me entitetet. Kolonat në një tabelë që përfaqësojnë një marrëdhënie relacionale quhen atributet.

Çdo atribut përcaktohet në një domen, kështu që një domen mund të mendohet si grupi i vlerave të vlefshme për një atribut të caktuar. Atribute të shumta të së njëjtës marrëdhënie, madje edhe atribute të marrëdhënieve të ndryshme, mund të përcaktohen në të njëjtin domen.

Një atribut vlera e të cilit identifikon në mënyrë unike tuplet quhet Celës (ose thjesht Celës). Çelësi është atributi "Numri i personelit", pasi vlera e tij është unike për secilin punonjës të ndërmarrjes. Nëse tuplet identifikohen vetëm duke bashkuar vlerat e disa atributeve, atëherë lidhja thuhet se ka një çelës të përbërë.

Çelesi primar- në një model të dhënash relacionale, një nga çelësat e mundshëm të një marrëdhënieje, i zgjedhur si çelësi kryesor (ose çelësi i paracaktuar).

Një lidhje mund të përmbajë çelësa të shumtë. Një nga çelësat deklarohet gjithmonë fillore, vlerat e tij nuk mund të përditësohen. Të gjithë çelësat e tjerë të lidhjes thirren çelësat e mundshëm.

Nga pikëpamja teorike, të gjithë çelësat e mundshëm (të mundshëm) të lidhjes janë ekuivalent, domethënë kanë të njëjtat karakteristika unike dhe minimale. Sidoqoftë, çelësi kryesor zakonisht zgjidhet nga çelësat e mundshëm që është më i përshtatshëm për qëllime të caktuara praktike, për shembull, për krijimin e jashtme çelësat në aspekte të tjera ose për të krijuar një indeks të grupuar. Prandaj, si rregull, si çelës primar zgjidhet ai që ka madhësinë më të vogël (ruajtjen fizike) dhe/ose përfshin numrin më të vogël të atributeve.

Nëse çelesi primar përbëhet nga një atribut i vetëm, ai quhet me një çelës të thjeshtë.

Nëse çelesi primar përbëhet nga dy ose më shumë atribute, quhet çelësi i përbërë. Pra, emri, mbiemri, patronimi, numri i pasaportës, seria e pasaportave nuk mund të jenë çelësa kryesorë individualisht, pasi mund të jenë të njëjtë për dy ose më shumë persona. Por nuk ka dy dokumente personale të të njëjtit lloj me të njëjtën seri dhe numër. Prandaj, në një lidhje që përmban të dhëna për njerëzit, çelësi kryesor mund të jetë një nëngrup atributesh që përbëhet nga lloji i dokumentit personal, seria dhe numri i tij.



Ndryshe nga modelet e të dhënave hierarkike dhe të rrjetit, ai relacional nuk ka konceptin e një marrëdhënie grupi. Për të pasqyruar lidhjet midis tupave të marrëdhënieve të ndryshme, përdoret dyfishimi i çelësave të tyre.

Quhen atributet që janë kopje të çelësave të marrëdhënieve të tjera çelësat e huaj.

Për shembull, marrëdhënia ndërmjet marrëdhënieve DEPARTMENT dhe PUNONJËS krijohet duke kopjuar çelësin primar "Numri_departamenti" nga marrëdhënia e parë në të dytën. Kështu, për të marrë një listë të punonjësve të një departamenti të caktuar, është e nevojshme: 1) Nga tabela DEPARTMENT, vendosni vlerën e atributit "Numri_departamenti" , që korrespondon me këtë “Emri_Departamenti”. 2) zgjidhni të gjitha të dhënat nga tabela EMPLOYEE, vlera e atributit "Numri_departamenti" e cila është e barabartë me atë të marrë në hapin e mëparshëm. Për të zbuluar se në cilin departament punon një punonjës, duhet të kryeni operacionin e kundërt: 1) Përcaktoni "Numri_departamenti" nga tabela E PUNONJËSVE. 2) Duke përdorur vlerën e fituar gjejmë hyrjen në tabelën DEPARTAMENT.


18. Normalizimi në bazat e të dhënave relacionale, koncepti i formës normale në hartimin e bazës së të dhënave.

Forma normale - një veti e një marrëdhënieje në një model të të dhënave relacionale, duke e karakterizuar atë nga pikëpamja e tepricës, e cila potencialisht mund të çojë në rezultate logjikisht të gabuara të kampionimit ose ndryshimit të të dhënave. Forma normale përkufizohet si një grup kërkesash që një marrëdhënie duhet të plotësojë.

Procesi i konvertimit të bazës së të dhënave në formë normale quhet normalizimi . Normalizimi synon të sjellë strukturën e bazës së të dhënave në një formë që siguron tepricë minimale, domethënë, normalizimi nuk synon të zvogëlojë ose rrisë produktivitetin e punës ose të zvogëlojë ose rrisë vëllimin e bazës së të dhënave. Qëllimi përfundimtar i normalizimit është të zvogëlojë mospërputhjen e mundshme të informacionit të ruajtur në bazën e të dhënave.



Eliminimi i tepricës kryhet, si rregull, duke zbërthyer marrëdhëniet në atë mënyrë që në çdo relacion të ruhen vetëm faktet parësore (d.m.th. fakte që nuk konkludohen nga faktet e tjera të ruajtura).

Varësitë funksionale.

Një bazë të dhënash relacionale përmban informacione strukturore dhe semantike. Struktura e një baze të dhënash përcaktohet nga numri dhe lloji i marrëdhënieve që ajo përmban, dhe nga marrëdhëniet një-në-shumë që ekzistojnë midis tupleve të këtyre marrëdhënieve. Pjesa semantike përshkruan grupin e varësive funksionale që ekzistojnë midis atributeve të këtyre marrëdhënieve. Le të përcaktojmë varësinë funksionale.

19. 1NF: Përkufizimet bazë dhe rregullat e transformimit.

Për të diskutuar formën e parë normale, nevojiten dy përkufizime:

Atribut i thjeshtë - një atribut vlerat e të cilit janë atomike (të pandashme).

Atribut kompleks - fitohet duke lidhur disa atribute atomike që mund të përcaktohen në domene të njëjta ose të ndryshme (quhet edhe vektor ose agregat i të dhënave).

Përkufizimi i formës së parë normale:

një lidhje është në 1NF nëse vlerat e të gjitha atributeve të saj janë atomike. . Përndryshe, nuk është fare tabelë dhe atributet e tilla duhet të zbërthehen.

Le të shohim një shembull:

Në bazën e të dhënave të departamentit të burimeve njerëzore të ndërmarrjes, është e nevojshme të ruhen informacione për punonjësit që mund të tentohen të paraqiten në lidhje me

PUNONJËS (NUMRI_EMPLOYEE, EMRI, DATA E LINDJES, HISTORIA_PUNËS, FËMIJËT).

Nga një shqyrtim i kujdesshëm i kësaj marrëdhënieje del se atributet "historia_pune" Dhe "fëmijët" janë komplekse, për më tepër, atributi "historia_pune" përfshin një atribut tjetër kompleks "histori_paga".
Këto njësi duken kështu:

 JOB_HISTORY (RECEPTION_DATE, EMRI, SALARY_HISTORY),

 SALARY_HISTORY (DATA_APPOINTMENT, PAGË),

 CHILDREN (CHILD_NAME, BIRTH_YEAR).

Lidhja e tyre është paraqitur në Fig. 3.3.

Fig.3.3. Qëndrimi fillestar.

Për ta sjellë relacionin origjinal SERVANT në formën e parë normale, është e nevojshme ta zbërthejmë atë në katër relacione, siç tregohet në figurën e mëposhtme:

Fig.3.4. Një grup i normalizuar i marrëdhënieve.

Këtu, çelësi kryesor i secilës marrëdhënie theksohet me një kornizë blu, emrat e çelësave të huaj janë me font blu. Kujtoni që çelësat e huaj përdoren për të përfaqësuar varësitë funksionale që ekzistojnë në relacionin burimor. Këto varësi funksionale tregohen me vija me shigjeta.

Algoritmi i normalizimit përshkruhet nga E.F. Codd si më poshtë:

  • Duke filluar me relacionin në krye të pemës (Figura 3.3.), merret çelësi i saj primar, dhe çdo lidhje e varur menjëherë zgjerohet duke futur një domen ose kombinim domenesh të atij çelësi primar.
  • Çelësi Primar i çdo relacioni të zgjeruar në këtë mënyrë përbëhet nga Çelësi Primar që ka pasur relacioni para shtrirjes dhe Çelësi Primar i shtuar i relacionit prind.
  • Pas kësaj, të gjitha domenet jo të thjeshta fshihen nga relacioni prind, hiqet nyja e sipërme e pemës dhe e njëjta procedurë përsëritet për secilën nga nënpemët e mbetura.

20. 2NF: Përkufizime bazë dhe rregullat e transformimit.

Shumë shpesh, çelësi kryesor i një marrëdhënieje përfshin disa atribute (në këtë rast quhet të përbëra) - shih, për shembull, relacionin FËMIJËT e paraqitur në Fig. 3.4 pyetja 19. Në të njëjtën kohë, futet koncepti varësia e plotë funksionale.

Përkufizimi:

një atribut jo kyç është funksionalisht plotësisht i varur nga një çelës i përbërë nëse është funksionalisht i varur nga i gjithë çelësi në tërësi, por nuk është funksionalisht i varur nga asnjë prej atributeve të tij përbërës.

Shembull:

Le të ketë një lidhje FURNIZIM (N_FURNIZUES, PRODUKT, ÇMIM).
Një furnizues mund të furnizojë produkte të ndryshme, dhe i njëjti produkt mund të furnizohet nga furnizues të ndryshëm. Atëherë çelësi i marrëdhënies është "N_furnizues + produkt". Lërini të gjithë furnizuesit të furnizojnë mallra me të njëjtin çmim. Atëherë kemi këto varësi funksionale:

  • N_furnizues, produkt -> çmimi
  • produkt -> çmimi

Varësia jo e plotë funksionale e atributit të çmimit nga çelësi çon në anomalinë e mëposhtme: kur çmimi i një artikulli ndryshon, kërkohet një pamje e plotë e marrëdhënies në mënyrë që të ndryshohen të gjitha të dhënat për furnizuesit e tij. Kjo anomali është pasojë e faktit se dy fakte semantike janë të kombinuara në një strukturë të dhënash. Zgjerimi i mëposhtëm jep marrëdhëniet në 2NF:

  • DORGIMI (N_FURNIZUES, PRODUKT)
  • PRODUCT_PRICE (PRODUCT, PRICE)

Kështu që ju mund të jepni

Përkufizimi i formës së dytë normale: Një lidhje është në 2NF nëse është në 1NF dhe çdo atribut jo kyç është plotësisht i varur funksionalisht nga çelësi.

21. 3NF: Përkufizime bazë dhe rregullat e transformimit.

Përpara se të diskutohet forma e tretë normale, është e nevojshme të prezantohet koncepti: varësia funksionale kalimtare.

Përkufizimi:

Le të jenë X, Y, Z tre atribute të ndonjë relacioni. Në këtë rast, X --> Y dhe Y --> Z, por nuk ka korrespondencë të kundërt, d.m.th. Z -/-> Y dhe Y -/-> X. Atëherë Z varet kalimisht nga X.
Le të ketë një lidhje STORAGE ( FIRMA, magazina, volumi), i cili përmban informacione për kompanitë që marrin mallra nga magazinat dhe vëllimet e këtyre magazinave. Atributi kryesor - "i fortë". Nëse secila kompani mund të marrë mallra nga vetëm një depo, atëherë në këtë drejtim ekzistojnë varësitë funksionale të mëposhtme:

  • të fortë -> aksioneve
  • aksioneve -> vëllimi

Në këtë rast, lindin anomali:

  • nëse për momentin asnjë kompani nuk merr mallra nga magazina, atëherë të dhënat për vëllimin e saj nuk mund të futen në bazën e të dhënave (pasi atributi kryesor nuk është i përcaktuar)
  • nëse vëllimi i magazinës ndryshon, është e nevojshme të shikoni të gjithë marrëdhënien dhe të ndryshoni kartat për të gjitha kompanitë që lidhen me këtë magazinë.

Për të eliminuar këto anomali, është e nevojshme të zbërthehet relacioni origjinal në dy:

  • RUAJTJA ( FIRMA, Aksione)
  • STORAGE_VOLUME ( stoku, VËLLIMI)

Përkufizimi i formës së tretë normale:

Një lidhje është në 3NF nëse është në 2NF dhe çdo atribut jo kyç nuk varet në mënyrë kalimtare nga çelësi primar.

InterBase mund të përdorë llojet e mëposhtme të kufizimeve:
  • ÇELËSI PRIMARY - çelësi primar i tabelës.
  • UNIK - çelësi unik i tabelës.
  • ÇELËSI I HUAJ- çelësi i huaj, siguron një lidhje me një tabelë tjetër dhe garanton integritetin referencial midis prindit dhe tavolina për fëmijë.

Një shënim për terminologjinë

Nëse jeni si autori i këtij kursi në atë që ju pëlqen të kërkoni përgjigje për një pyetje që ju intereson në mënyrë gjithëpërfshirëse, në vepra të ndryshme nga autorë të ndryshëm, atëherë nuk mund të mos vini re një konfuzion në përkufizimet kryesore (mjeshtër) -> vartëse (detaje) tabelat. Kujtoni se tabela kryesore shpesh quhet tabela mëmë, dhe tabela e varur shpesh quhet tabela e fëmijëve.

Kjo ndoshta është për shkak të mënyrës sesi interpretohen këto përkufizime në DBMS-të e serverëve lokalë dhe SQL.

Në DBMS-të lokale, tabela kryesore është ajo që përmban të dhënat kryesore, dhe tabela e varur përmban të dhëna shtesë. Le të marrim, për shembull, tre tabela të lidhura. E para përmban të dhëna për shitjet, e dyta - për produktet dhe e treta - për klientët:


Oriz. 18.1.

Këtu informacioni kryesor ruhet në tabelën e shitjeve, pra është tabela kryesore (mëmë). Informacione shtesë ruhen në tabelat e produktit dhe klientëve, që do të thotë se ata janë fëmijë. Kjo është e kuptueshme: një vajzë nuk mund të ketë dy nëna biologjike, por një nënë është mjaft e aftë të lindë dy vajza.

Por në serverët e bazës së të dhënave SQL ekziston një përkufizim i ndryshëm i marrëdhënieve: kur një fushë në një tabelë i referohet një fushe në një tabelë tjetër, ajo quhet çelësi i huaj. Dhe fusha të cilës i referohet quhet prindi ose çelesi primar. Një tabelë që ka një çelës të huaj (një lidhje me një regjistrim në një tabelë tjetër) shpesh quhet fëmijë, dhe një tabelë me çelësi prind- prindërore. Gjithashtu në përkufizimin e marrëdhënieve ata thonë se një prind mund të ketë vetëm një rekord unik, i cili mund të referohet nga disa rekorde tavolinë për fëmijë.

Pra, në shembullin e mësipërm, tabela e shitjeve ka dy çelësa të huaj: ID-në e produktit dhe ID-në e klientit. Dhe të dyja tabelat në anën e djathtë të figurës kanë çelësi prind"Identifikues". Meqenëse i njëjti klient ose produkt mund të shfaqet në mënyrë të përsëritur në tabelën e shitjeve, rezulton se të dy tabelat në anën e djathtë të figurës janë prindër, dhe tabela në të majtë është një fëmijë. Sepse tani jemi duke studiuar InterBase - SQL serveri i bazës së të dhënave, ne do të udhëhiqemi nga këto përkufizime në leksionet vijuese. Për të mos e trazuar më tej trurin tonë për këtë konfuzion, le të biem dakord menjëherë: tavolinë për fëmijë ka një çelës të huaj (ÇELËS I HUAJ) në një tabelë tjetër.

ÇELESI PRIMAR

ÇELESI PRIMAR- çelësi primar është një nga llojet kryesore të kufizimeve në një bazë të dhënash. Çelësi primar është krijuar për të identifikuar në mënyrë unike një rekord në një tabelë dhe duhet të jetë unik. Çelësat primar PRIMARY KEY ndodhen në tabela, të cilat zakonisht quhen prind (Parent). Çelësi primar nuk duhet të ngatërrohet me indekset kryesore të bazave të të dhënave lokale; çelësi primar nuk është një indeks, por një kufizim. Kur krijoni një çelës primar NdërBazë automatikisht krijon për të indeks unik. Megjithatë, nëse krijojmë indeks unik, kjo nuk do të krijojë kufizimet kryesore kryesore. Një tabelë mund të ketë vetëm një çelës primar, PRIMARY KEY.

Le të themi se keni një tabelë me një listë të punonjësve. Fusha Emri i Mbiemrit mund të përmbajë vlera të kopjuara (emra), kështu që nuk mund të përdoret si çelës kryesor. Është e rrallë, por ka emra që, përveç kësaj, kanë të njëjtët emra. Edhe më rrallë, ka emra të plotë, kështu që edhe të tre fushat "Mbiemri" + "Emri" + "Patronimi" nuk mund të garantojnë veçantinë e rekordit dhe nuk mund të jenë çelësi kryesor. Në këtë rast, zgjidhja, si më parë, është të shtoni një fushë identifikuese që përmban numrin serial të këtij personi. Fusha të tilla zakonisht bëhen me rritje automatike (ne do të flasim për organizimin e fushave me rritje automatike në leksionet e ardhshme). Kështu që,

Çelesi primar është një ose më shumë fusha në një tabelë, kombinimi i të cilave është unik për çdo rekord.

Nëse çelësi primar përmban një kolonë të vetme (siç ndodh më shpesh), specifikuesi PRIMARY KEY përdoret kur përcaktimi i kolonës:

KRIJO TABELE Prim_1(Stolbec1 INT JO NULL ÇELËSI PRIMAR, Stolbec2 VARCHAR(50))

Nëse çelësi primar është ndërtuar në disa kolona, ​​atëherë specifikuesi vendoset pas përcaktimit të të gjitha fushave:

KRIJO TABELA Prim_2(Stolbec1 INT JO NULL, Stolbec2 VARCHAR(50) JO NULL, ÇELËSI PRIMAR (Stolbec1, Stolbec2))

Siç mund të shihet nga shembujt, çelësi kryesor duhet të ketë një kufizim NOT NULL kolonë(s)..

UNIKE

UNIKE- çelësi unik. Specifikimi UNIQUE tregon se të gjitha vlerat e kësaj fushe duhet të jenë unike; prandaj, fusha të tilla gjithashtu nuk mund të përmbajnë vlera I PAVLEFSHËM. Mund të thuash që një çelës UNIQUE është një alternativë ndaj çelësit primar, por ka dallime. Dallimi kryesor është se duhet të ketë vetëm një çelës primar, ndërsa mund të ketë disa çelësa unikë. Për më tepër, një kufizim UNIQUE nuk mund të ndërtohet në të njëjtin grup kolonash që është përdorur për një ÇELËS KRYESOR ose një kufizim tjetër UNIQUE. Çelësat unikë, si çelësat kryesorë, gjenden në tabela që janë prindër të tabelave të tjera.

Një kolonë e deklaruar me një kufizim UNIQUE, si një çelës primar, mund të përdoret për të zbatuar integritetin referues midis prindit të saj dhe tavolina për fëmijë. Në këtë rast, çelësi i huaj tavolinë për fëmijë do t'i referohet kësaj fushe. Ashtu si me një çelës primar, kur krijohet një çelës unik, a indeks unik. Por jo anasjelltas. Një shembull i krijimit të një tabele me një çelës kryesor dhe dy çelësa unikë:

KRIJO TABELE Prim_3(Stolbec1 INT JO NULL ÇELËS PRIMAR, Stolbec2 VARCHAR(50) JO NULL UNIK, Stolbec3 FLOAT JO NULL UNIK)

ÇELËSI I HUAJ

ÇELËSI I HUAJ- çelësi i jashtëm. Ky është një mjet shumë i fuqishëm për të siguruar integritetin referencial midis tabelave, i cili ju lejon jo vetëm të monitoroni praninë e lidhjeve të sakta, por edhe t'i menaxhoni ato automatikisht. Çelësat e huaj përmbahen në tabela që janë fëmijë (Fëmijë) të tabelave të tjera. Integriteti i referencës sigurohet pikërisht nga një çelës i huaj që i referohet primarit ose

Dhe kështu, në heshtje, ne iu afruam një teme shumë të rëndësishme - çelësat kryesorë dhe të huaj. Nëse të parët përdoren pothuajse nga të gjithë, atëherë të dytat disi injorohen. Por më kot. Çelësat e huaj nuk janë problem, ata janë një ndihmë e vërtetë në integritetin e të dhënave.

1.2.5. Çelesi primar

Ne kemi folur tashmë shumë për fushat kryesore, por nuk i kemi përdorur kurrë ato. Gjëja më interesante është se gjithçka funksionoi. Ky është një avantazh, ose ndoshta një disavantazh i bazave të të dhënave të Microsoft SQL Server dhe MS Access. Ky truk nuk do të funksionojë në tabelat Paradox dhe pa një fushë kyçe tabela do të jetë vetëm për lexim.

Në një farë mase, çelësat janë kufizime dhe ato mund të konsiderohen së bashku me deklaratën CHECK sepse deklarimi ndodh në një mënyrë të ngjashme dhe madje përdor deklaratën CONSTRAINT. Le ta shohim këtë proces me një shembull. Për ta bërë këtë, ne do të krijojmë një tabelë me dy fusha "udhëzues" dhe "vcName". Kjo vendos fushën "udhëzues" si çelësin kryesor:

KRIJO TABLE_Globally_Unique_Data (identifikuesi unik i udhëzuesit DEFAULT NEWID(), vcName varchar(50), KUFIZUAR PK_guid ÇELËSI PRIMAR (Udhëzues))

Pjesa më e mirë këtu është linja KUFIZIM. Siç e dimë, pas kësaj fjale kyçe vjen emri i kufizimit, dhe deklarata kryesore nuk bën përjashtim. Për të emërtuar një çelës primar, rekomandoj të përdorni një emër si PK_name, ku emri është emri i fushës që duhet të bëhet çelësi kryesor. Shkurtesa PK vjen nga çelësi kryesor.

Pas kësaj, në vend të fjalës kyçe CHECK, të cilën e kemi përdorur në kufizime, është operatori PRIMARY KEY, që tregon se nuk kemi nevojë për kontroll, por për një çelës primar. Një ose më shumë fusha që do të përbëjnë çelësin tregohen në kllapa.

Mos harroni se asnjë dy rresht nuk mund të ketë të njëjtën vlerë në një fushë kyçe, në të cilën një kufizim kryesor i çelësit është identik me një kufizim unik. Kjo do të thotë se nëse e bëni çelësin kryesor fushën për ruajtjen e mbiemrit, atëherë nuk do të jetë e mundur të shkruani dy Ivanov me emra të ndryshëm në një tabelë të tillë. Kjo shkel kufizimin e çelësit primar. Kjo është arsyeja pse çelësat janë kufizime dhe deklarohen në të njëjtën mënyrë si një kufizim CHECK. Por kjo nuk është e vërtetë vetëm për çelësat kryesorë dhe çelësat dytësorë me veçanti.

Në këtë shembull, çelësi primar është një fushë e tipit identifikues unik (GUID). Vlera e paracaktuar për këtë fushë është rezultat i procedurës së serverit NEWID.

Kujdes

Vetëm një çelës kryesor mund të krijohet për një tabelë

Për të thjeshtuar shembujt, këshillohet përdorimi i një tipi numerik si çelës dhe nëse e lejon baza e të dhënave, do të ishte më mirë nëse ai është i tipit “autoincrement” (numri në rritje/zvogëlim automatik). Në MS SQL Server kjo fushë është IDENTITY, dhe në MS Access është një fushë e tipit "counter".

Shembulli i mëposhtëm tregon se si të krijoni një tabelë produkti me një fushë të numrit të plotë që rritet automatikisht si çelës kryesor:

KRIJO TABELA Produkte (id int IDENTITY(1, 1), produkt varchar(50), Çmimi para, Sasia numerike(10, 2), KUFIZIM PK_id ÇELËSI PRIMAR (id))

Ky është lloji i çelësit që do të përdorim më shpesh, sepse fusha e çelësit do të ruajë numra që janë të lehtë për t'u kuptuar dhe do të jenë më të lehtë dhe më vizuale për të punuar.

Një çelës primar mund të përbëhet nga më shumë se një kolonë. Shembulli i mëposhtëm krijon një tabelë në të cilën fushat "id" dhe "Produkt" formojnë çelësin kryesor, që do të thotë se një indeks unik do të krijohet në të dyja fushat:

KRIJON TABELA Produkte1 (id int IDENTITY(1, 1), produkt varchar(50), Çmimi para, Sasia numerike (10, 2), KUFIZIM PK_id ÇELËSI PRIMARY (id, [Emri i produktit]))

Shumë shpesh programuesit krijojnë një bazë të dhënash me një fushë kyçe në formën e një numri të plotë, por në të njëjtën kohë detyra thotë qartë se disa fusha duhet të jenë unike. Pse të mos krijoni menjëherë një çelës primar nga ato fusha që duhet të jenë unike dhe nuk do të ketë nevojë të krijohen zgjidhje të veçanta për këtë problem.

E vetmja pengesë e një çelësi primar me shumë kolona është problemi i krijimit të marrëdhënieve. Këtu ju duhet të dilni prej tij duke përdorur metoda të ndryshme, por problemi ende mund të zgjidhet. Thjesht duhet të futni një fushë të tipit identifikues unik dhe të bëni një lidhje duke përdorur atë. Po, në këtë rast marrim një çelës primar unik dhe një fushë të tipit identifikues unik, por kjo tepricë si rezultat nuk do të jetë më e madhe se e njëjta tabelë ku çelësi primar është identifikues unik, dhe një kufizim unike vendoset në fushat që duhet të Behu unik. Çfarë të zgjidhni? Varet nga detyra specifike dhe me çfarë jeni më rehat të punoni.

1.2.6. Çelësi i jashtëm

Një çelës i huaj është gjithashtu një kufizim CONSTRAINT dhe përfaqëson marrëdhënien midis dy tabelave. Le të themi se keni dy tabela:

  • Emrat – përmban emrat e njerëzve dhe përbëhet nga fusha identifikuese (fusha kryesore), emri.
  • Telefonat është një tabelë telefonike që përbëhet nga një identifikues (fusha kryesore), një çelës i huaj për t'u lidhur me tabelën e emrave dhe një fushë vargu për ruajtjen e numrit të telefonit.

Një person mund të ketë disa telefona, kështu që ne e ndamë ruajtjen e të dhënave në tabela të ndryshme. Figura 1.4 tregon vizualisht marrëdhënien midis dy tabelave. Nëse tashmë keni punuar me tabela të lidhura, atëherë kjo do t'ju mjaftojë. Nëse po dëgjoni për lidhjet për herë të parë, atëherë le të përpiqemi ta hedhim një vështrim më të afërt të problemit.

Për shembull, le të marrim një tryezë me tre persona. Tabela 1.3 tregon përmbajtjen e tabelës "Emrat". Ka vetëm tre rreshta dhe secila ka çelësin e vet unik kryesor. Për unike, kur krijojmë një tabelë, ne do ta bëjmë çelësin një fushë automatikisht në rritje.

Tabela 1.3 Përmbajtja e tabelës Emrat

Tabela 1.4. Përmbajtja e tabelës së telefonave

Tabela 1.4 përmban pesë numra telefoni. Fusha kryesore kryesore përmban gjithashtu një çelës unik master, i cili gjithashtu mund të rritet automatikisht. Një çelës dytësor është një lidhje me çelësin kryesor të tabelës Emrat. Si funksionon kjo lidhje? Petrov ka numrin 1 si çelës kryesor në tabelën Emrat. Në tabelën Phones, në çelësin dytësor, ne kërkojmë numrin 1 dhe marrim numrat e telefonit të Petrov. E njëjta gjë vlen edhe për pjesën tjetër të hyrjeve. Vizualisht lidhja mund të shihet në Figurën 1.5.

Ky lloj i ruajtjes së të dhënave është shumë i përshtatshëm. Nëse nuk do të ishte e mundur të krijoheshin tabela të lidhura, atëherë në tabelën Emrat do të duhej të fusnim të gjithë numrat e telefonit në një fushë. Kjo është e papërshtatshme nga pikëpamja e përdorimit, mirëmbajtjes dhe rikthimit të të dhënave.

Ju mund të krijoni disa fusha Emra në një tabelë, por lind pyetja - sa. Një person mund të ketë vetëm 1 telefon, por unë, për shembull, kam 3, pa llogaritur ato të punës. Një numër i madh fushash çon në tepricë të të dhënave.

Mund të krijoni një rresht të veçantë me mbiemrin për secilin telefon në tabelën Emrat, por kjo është e lehtë vetëm për një shembull kaq të thjeshtë, kur ju duhet vetëm të vendosni mbiemrin dhe mund të bëni lehtësisht disa hyrje për Petrov me disa telefona. numrat. Po sikur të ketë 10 ose 20 fusha? Pra, krijimi i dy tabelave të lidhura me një çelës të huaj mund të shihet në Listimin 1.6.

Listimi 1.6. Krijimi i tabelave të lidhura me një çelës të huaj

KRIJO Emra TABELE (idName int IDENTITY(1,1), vcName varchar(50), KUFIZIM PK_guid ÇELËSI KRYESOR (idName),) KRIJO TABELA TELEFONAVE (idPhone int IDENTITY(1,1), idName int, vcPhone(10), KUFIZIM PK_idPhone ÇELËSI PRIMAR (idPhone), KUFIZIM FK_idName ÇELËSI I HUAJ (idName) REFERENCAT Emrat (idName))

Ju lutemi rishikoni me kujdes përmbajtjen e listimit. Është mjaft interesante sepse përdor disa nga operatorët që kemi mbuluar tashmë dhe një shembull shtesë do të ishte i dobishëm. Për të dyja tabelat krijohet një fushë kyçe, e cila vjen e para, është e tipit int dhe rritet automatikisht, duke filluar nga 1 në rritje të një. Fusha kryesore është bërë çelësi kryesor duke përdorur një kufizim KUFIZIM.

Në përshkrimin e tabelës Phones, rreshti i fundit përmban një deklaratë të re për ne, përkatësisht, deklaratën e një çelësi të huaj duke përdorur operatorin FOREIGN KEY. Siç mund ta shihni, ky është gjithashtu një kufizim dhe pak më vonë do të shihni pse. Fusha e tabelës që duhet të lidhet me një tabelë tjetër tregohet në kllapa. Pas kësaj vjen kryefjala REFERENCAT (lidhja), emri i tabelës me të cilën duhet të jetë lidhja (Emrat) dhe në kllapa emri i fushës ("idName"). Kështu, ne kemi bërë një lidhje, e cila është paraqitur në figurën 1.4.

Kujdes!

Një çelës i huaj mund t'i referohet vetëm çelësit kryesor të një tabele tjetër ose një kufizimi unik. Kjo do të thotë që pas fjalës kyçe REFERENCES duhet të ketë një emër tabele dhe vetëm një çelës primar ose një fushë me një kufizim UNIQUE mund të specifikohet në kllapa. Fushat e tjera nuk mund të specifikohen.

Tani, nëse mund të plotësoni tabelat me të dhëna. Tre skuadrat e ardhshme shtojnë tre emrat që pamë në tabelën 1.3:

INSERT INTO Emrat(vcName) VALUES("Petrov") INSERT INTO Names(vcName) VALUES("Ivanov") INSERT INTO Emrat(vcName) VALUES("Sidorov")

Nëse keni punuar tashmë me SQL, mund të shtoni hyrje për tabelën e telefonit. Unë do t'i heq këto komanda, por ju mund t'i shihni ato në skedarin Foreign_keys.sql në drejtorinë Chapter1 në CD.

Detyra jonë tani është të shohim se cilat janë veprimet kufizuese të një çelësi të huaj, le ta kuptojmë. Ne kemi specifikuar një marrëdhënie të qartë midis dy fushave në tabela të ndryshme. Nëse përpiqeni të shtoni një regjistrim në tabelën e telefonit me një identifikues në fushën "idName" që nuk ekziston në fushën me të njëjtin emër (emri mund të ndryshohet në një tjetër) në tabelën me mbiemrat, do të ndodhë një gabim. . Kjo do të prishë marrëdhënien midis dy tabelave dhe kufizimi i çelësit të huaj nuk do të lejojë që regjistrimet të ekzistojnë pa lidhjen.

Kufizimi vlen edhe kur ndryshoni ose fshini të dhënat. Për shembull, nëse përpiqeni të fshini një rresht me mbiemrin Petrov, do të ndodhë një gabim i kufizimit të çelësit të huaj. Ju nuk mund të fshini të dhënat që kanë rreshta të lidhur nga jashtë. Së pari, duhet të fshini të gjithë numrat e telefonit për këtë hyrje, dhe vetëm pas kësaj do të jetë e mundur të fshini rreshtin me mbiemrin Petrov.

Kur krijoni një çelës të huaj, mund të specifikoni ON DELETE CASCADE ose ON ON UPDATE CASCADE. Në këtë rast, nëse fshini rekordin e Petrov nga tabela Emrat ose ndryshoni identifikuesin, atëherë të gjitha të dhënat në tabelën e telefonave të lidhur me rreshtin e Petrov do të përditësohen automatikisht. kurrë. Jo, duhet të shkruhet me shkronja të mëdha: KURRË mos e bëj këtë. Çdo gjë duhet të fshihet ose ndryshohet manualisht. Nëse një përdorues fshin aksidentalisht një hyrje nga tabela Emrat, atëherë telefonat përkatës fshihen gjithashtu. Nuk ka kuptim të krijoni një çelës të huaj nëse gjysma e kufizimeve të tij zhduken! Gjithçka duhet të bëhet me dorë dhe nuk rekomandohet kurrë të ndryshoni identifikuesit.

Fshirja e vetë tabelave duhet të fillojë gjithashtu me tabelën e varur, domethënë Telefonat, dhe vetëm atëherë mund të fshini tabelën kryesore Emrat.

Më në fund, unë do t'ju tregoj se si të gjeni bukur një përputhje midis emrave dhe numrave të telefonit nga dy tabela:

SELECT vcName, vcPhone FROM Emrat, Phones WHERE Names.idName=Phones.idName

Për pyetje të tilla do të flasim më në detaje në Kapitullin 2. Për momentin, unë dhashë një shembull vetëm që të mund të shihni fuqinë e tabelave të lidhura.

Një tabelë mund të përmbajë deri në 253 çelësa të huaj, gjë që është mjaft e mjaftueshme edhe për bazat e të dhënave më komplekse. Personalisht, më duhej të punoja me bazat e të dhënave ku numri i çelësave të huaj nuk i kalonte 7 për tabelë. Nëse është më shumë, atëherë ka shumë të ngjarë që baza e të dhënave të jetë projektuar gabimisht, megjithëse ka përjashtime.

Tabela në vetvete mund të ketë gjithashtu një maksimum prej 253 çelësash të huaj. Çelësat e huaj në një tabelë janë më pak të zakonshëm, zakonisht jo më shumë se 3. Më shpesh, një tabelë mund të ketë shumë lidhje me tabela të tjera.

Një çelës i huaj mund t'i referohet të njëjtës tabelë në të cilën është krijuar. Për shembull, ju keni një tabelë të titujve të punës në një organizatë, siç tregohet në tabelën 1.5. Tabela përbëhet nga tre fusha: çelësi kryesor, çelësi i huaj dhe titulli i punës. Çdo organizatë mund të ketë shumë pozicione, por do të ishte mjaft logjike të shfaqeshin emrat e tyre dhe struktura e vartësisë në një tabelë. Për ta bërë këtë, çelësi i huaj duhet të shoqërohet me çelësin kryesor të tabelës së pozicionit.

Tabela 1.5. Tabela me lidhjen e brendshme

Si rezultat, marrim se drejtori i përgjithshëm ka një çelës të huaj zero, d.m.th. ky pozicion qëndron në krye të gjithë të tjerëve. Për drejtorin komercial dhe drejtorin e punëve të përgjithshme, çelësi i jashtëm tregon grindjen e drejtorit të përgjithshëm. Kjo do të thotë që këto dy pozicione i raportojnë drejtpërdrejt CEO. Dhe kështu me radhë.

Le të shohim se si mund t'i krijojmë të gjitha këto si një pyetje SQL:

KRIJO TABELARE Pozicionet (idPosition int IDENTITY(1,1), idParentPosition int, vcName varchar(30), KUFIZUAR PK_idPosition ÇELËSI PRIMARY (idPosition), KUFIZIM FK_idParentPosition FOREIGN KEY (idParentPositions)

Siç mund ta shihni, çelësi i huaj thjesht i referohet të njëjtës tabelë që ne po krijojmë. Në CD, në drejtorinë Chapter1, mund të shihni në skedarin Foreign_keys_to_self.sql një shembull të krijimit të kësaj tabele, plotësimit të saj me të dhëna dhe shfaqjes së pozicioneve duke marrë parasysh vartësinë e tyre. Në kapitullin vijues do të shikojmë më në detaje mundësinë e punës me tabela të tilla.

Një për një marrëdhënie

Deri më tani, ne kemi parë marrëdhënien klasike, kur një rresht i tabelës kryesore të të dhënave korrespondon me një rresht nga tabela përkatëse. Kjo marrëdhënie quhet një me shumë. Por ka lidhje të tjera, dhe tani do të shikojmë një tjetër - një me një, kur një rekord në tabelën kryesore lidhet me një rekord të një tjetri. Për ta zbatuar këtë, mjafton të lidhni çelësat kryesorë të të dy tabelave. Meqenëse çelësat kryesorë nuk mund të përsëriten, vetëm një rresht mund të lidhet në të dyja tabelat.

Shembulli i mëposhtëm krijon dy tabela që kanë një lidhje kryesore kryesore:

KRIJO Emra TABLE (identifikues unik iidName DEFAULT NEWID(), vcEmri varchar(50), KUFIZUAR PK_guid ÇELËSI KRYESOR (idName)) KRIJO Telefona TABLE (identifikues unik iidPhone DEFAULT NEWID(), vcPhone CONSTRAINTHOINThone KUFIZIM FK_idPhone ÇELËSI I HUAJ (idPhone) REFERENCAT Emrat (idName))

Vetëm njëra prej tabelave ka nevojë për një çelës të huaj. Meqenëse marrëdhënia është një me një, nuk ka rëndësi se në cilën tabelë do ta krijoni atë.

shumë për shumë

Marrëdhënia më komplekse është shumë-me-shumë, ku shumë regjistrime nga një tabelë përputhen me shumë rekorde nga një tabelë tjetër. Për ta zbatuar këtë, nuk mjaftojnë dy tabela, nevojiten tre tabela.

Fillimisht duhet të kuptojmë se kur mund të përdoret një marrëdhënie shumë-për-shumë? Le të themi se keni dy tabela: një listë të banorëve të shtëpisë dhe një listë me numra telefoni. Një apartament mund të ketë më shumë se një numër, që do të thotë se një mbiemër mund të ketë dy numra telefoni. Rezulton se ka një marrëdhënie një me shumë. Nga ana tjetër, në një apartament mund të ketë dy familje (një apartament komunal ose thjesht një qiramarrës që përdor telefonin e pronarit), që do të thotë se lidhja midis telefonit dhe banorit është gjithashtu një me shumë. Dhe opsioni më i vështirë është të kesh dy telefona në një apartament komunal. Në këtë rast, të dy numrat përdoren nga disa banorë të banesës. Pra, rezulton se "shumë" familje mund të përdorin "shumë" telefona (komunikim shumë-për-shumë).

Si të zbatoni një marrëdhënie shumë me shumë? Në pamje të parë, kjo është e pamundur në modelin relacional. Rreth 10 vjet më parë, kalova një kohë të gjatë duke kërkuar opsione të ndryshme dhe si rezultat thjesht krijova një tabelë që ishte e mbushur me të dhëna të tepërta. Por një ditë, më dhanë një detyrë, falë së cilës doli një zgjidhje e shkëlqyer nga kushtet - më duhej të krijoja dy tabela të banorëve të apartamenteve dhe numrat e telefonit dhe të vendosja vetëm një çelës primar në to. Çelësat e huaj nuk nevojiten në këtë tabelë. Por lidhja midis tabelave duhet të bëhet përmes një tabele të tretë lidhëse. Në pamje të parë, kjo është e vështirë dhe e paqartë, por sapo ta kuptoni këtë metodë, do të shihni fuqinë e plotë të kësaj zgjidhjeje.

Tabelat 1.6 dhe 1.7 tregojnë shembuj të tabelave të mbiemrit dhe telefonit, përkatësisht. Dhe Tabela 1.8 tregon tabelën lidhëse.

Tabela 1.6. Tabela e mbiemrit

Tabela 1.7. Tabela e telefonit

Tabela 1.8. Tabela e telefonit

Le të shohim tani se si do të jetë logjika e kërkimit të të dhënave në një marrëdhënie shumë-për-shumë. Le të themi se duhet të gjejmë të gjithë telefonat që i përkasin Ivanovit. Çelësi primar i Ivanovit është i barabartë me 1. Në tabelën lidhëse gjejmë të gjitha rekordet për të cilat fusha "Marrëdhënia me emrin" është e barabartë me 1. Këto do të jenë regjistrimet 1 dhe 2. Në këto të dhëna në fushën "Marrëdhënia me telefonin" atje janë përkatësisht identifikuesit 1 dhe 2, dhe kjo do të thotë se Ivanov zotëron numrat nga tabela telefonike, të cilët ndodhen në rreshtat 1 dhe 2.

Tani le të zgjidhim problemin e kundërt - të përcaktojmë se kush ka akses në numrin e telefonit 567575677. Ky numër në tabelën e telefonit ka çelësin 3. Po kërkojmë të gjitha regjistrimet në tabelën lidhëse, ku në fushën "Lidhja me telefon" është e barabartë me 3. Bëhet fjalë për regjistrime me numrat 4 dhe 5, të cilët në fushën "Lidhja e emrit" përmbajnë respektivisht vlerat 2 dhe 3. Nëse tani shikoni tabelën e mbiemrave, do të shihni Petrov dhe Sidorov në numrat 2 dhe 3. Kjo do të thotë se këta dy banorë përdorin numrin e telefonit 567575677.

Rishikoni të tria tabelat dhe sigurohuni që të kuptoni se cilët numra telefoni i përkasin cilit banorë dhe anasjelltas. Nëse e shihni këtë lidhje, do të kuptoni se është e thjeshtë sa tre qindarka dhe mund ta zbatoni shpejt në projektet tuaja.

KRIJO TABLE Emra (identifikues unik iidName DEFAULT NEWID(), vcEmri varchar(50), KUFIZUAR PK_guid ÇELËSI KRYESOR (idName)) KRIJO Telefona TABLE (identifikues unik iidPhone DEFAULT NEWID(), vcPhone varchar(50) KRIJO TABELË Lidhjeje TABELA (identifikues unik i idLinkTable DEFAULT NEWID(), identifikues unik i idName, identifikues unik i idPhone, ÇELËSI PRIMAR PK_idLinkTable (idLinkTable), KUFIZIM FK_idPhone ÇELËSI I HUAJ (idPIDRENMET) ÇELËSI I HUAJ (idName) REFERONI ENCES Emrat (idName ) )

Tabela lidhëse ka dy çelësa të huaj që lidhen me emrat dhe tabelat e telefonit dhe një çelës kryesor që siguron që regjistrimet të jenë unike.

Zgjodha fushën GUID si çelësin kryesor sepse është më i përshtatshëm për zgjidhjen e këtij problemi të veçantë. Fakti është se ne duhet të fusim të dhënat në dy tabela dhe në të dyja rastet duhet të specifikojmë të njëjtin çelës. Vlera GUID mund të gjenerohet dhe më pas të përdoret kur futni të dhëna në të dyja tabelat.

Ju gjithashtu mund të përdorni një fushë në rritje automatike si çelës, por në këtë rast problemi është pak më i vështirë për t'u zgjidhur, ose më saktë, është i papërshtatshëm për të zgjidhur problemin. Për shembull, kur shtoni një numër telefoni, së pari duhet të futni rreshtin përkatës në tabelë, pastaj ta gjeni, të përcaktoni çelësin që i është caktuar rreshtit dhe më pas të bëni lidhjen.

Në këtë fazë ne jemi të kufizuar vetëm në krijimin e tabelave, por në seksionin 2.8 do t'i kthehemi kësaj teme dhe do të mësojmë dhe mësojmë se si të punojmë me tabela përkatëse. Puna me një marrëdhënie një me një dhe një me shumë nuk është shumë e ndryshme, sepse vetëm dy tabela përfshihen në këtë skemë. Marrëdhëniet shumë-me-shumë janë pak më të komplikuara për shkak të tabelës lidhëse, kështu që ne do ta mbulojmë atë veçmas në seksionin 2.27.




Top