Jedan key per table (dizajnersko pitanje)

e ovako kreirajući tablice sinula mi je ideja da bi možda veću mogučnost nadogradnje baze dobio tako kad bi foregin key isključivo spajao u posebnim tablicama. Znači niti jedna tablica u sebi nebi imala dva ključa, pod time mislim na foregin i primary.
Dvostruke ključeve nikad nisam primjenjivao iako sam tražio razloge da ih primjenim. No njih bi isto izbacio iz igre.

Dali ste se okušali u takvom dizajnu talice, dali je za vas normalno da tako radite ili vas sama ideja o premreženosti foregin key-evima jednostavno smeta.

[quote=“gorrc”]e ovako kreirajući tablice sinula mi je ideja da bi možda veću mogučnost nadogradnje baze dobio tako kad bi foregin key isključivo spajao u posebnim tablicama. Znači niti jedna tablica u sebi nebi imala dva ključa, pod time mislim na foregin i primary.
Dvostruke ključeve nikad nisam primjenjivao iako sam tražio razloge da ih primjenim. No njih bi isto izbacio iz igre.

Dali ste se okušali u takvom dizajnu talice, dali je za vas normalno da tako radite ili vas sama ideja o premreženosti foregin key-evima jednostavno smeta.[/quote]

Foreign key != Composite key (ili dvostruki kako ga ti zoves, iako moze biti i trostruki, cetverostruki, itd.)

U trecoj tablici se spajaju postoji potreba za tim - npr. kad je odnos visestruki, npr. kad na jedan ili vise zapisa iz tablice A vezes jedan ili vise zapisa iz tablice B.

Na kakvu nadogradnju mislis?

Dizajniram bazu da određeni djelovi na bazi moraju imati mogučnost unošenja prijevoda.

Najednostavniji primjer vijesti.
Za sad neka bude jedna tablica novosti.
Treba nam još jedna tablica za prijevode tekstova.
Jedna tablica za popis jezika.
Ovo se fino može povezati bez nekih problema.

E sad tu dolazi problem. Kome pripada vijest. Recimo imamo popis tvrtki sa prijevodima. Ok dodamo jednu columnu u vijesti da znamo da vijest pripada tvrtki.
E sad, dođe sutra novi dan i netko se sjeti da se vijesti mogu objavljivati i po županijama.
Pa ajmo dodati još jedanu columnu da znamo u koju županiji vijest pripada.
I tu je nastao problem dodavanjem novih foregin key gubi se mogučnost lake nadogradnje.
Znači rupa u dizajnu. Inače ne koristim više od jednog foregin key osim naravno u tablicama koje nemaju nikakvih podataka, ali ovdje mi se čini da je i taj jedan previše.
Prekosutra će možda još jedna tablica željeti objavljivati vijesti, recimo privatne osobe.
I što sad opet novi foregin key.
Pa tko bi to ulovio.
Select * from vijest where zupanija is null, tvrtka is null and privatni_osobe not null:)

Na kraju sam došao do toga da bi tablica vijesti, trebali biti lišena bilo kakvih keya osim primary key.
A svaka tablica koja ima mogučnost vijesti bi morala imati i jednu tablicu u kojoj bi se držali podaci vijest.
Znači to bi izgledalo ovako

županija->županija_vijesti->vijest->prijevod_vijesti.

E sad bi mogle i postojati kombinacije tipa da tvrtka i županija ima istu vijest.
Jer bi se u županija_vijesti i tvrtka_vijesti mogao staviti isti foregin key iz vijest_id.

No da je samo jedan foregin key na tablici vijesti, recimo od županije već bi bili moguči problemi. Što ako županija želi izbrisati vijest a tvrtka dalje želi imati pristup vijesti.
Onda staviti županiju na null i promjeniti logiku na serveru da županija ne selektira null.

Uglavnom ništa što se kvalitetnim dizajnom ne može rješiti no mislim barem iz toga konkretnog primjera da ako tablicu koristi više drugih tablica ili u budućnosti postoji mogučnost da bi mogle biti novih tablica povezanih s tom tablicom. Ta tablica nebi trebala imati foregin key već isključivo povezivanje s drugim tablicama preko drugih tablica, ako je naravno to moguče.

Trebaš tagirati vijesti.

Vlasništvo je jedinstveno ali vijest može biti u više tagova.

Npr.

tablica VIJEST
*VIJEST
TEKST

tablica TAG
*TAG
NAZIV

tablica VIJEST_TAG
*VIJEST
*TAG

Ja uvijek radim da mi svaka tablica ima PK i ako treba FK na mama tablicu.

Što se tiče prijevoda, to bi složio ovako.
tablica JEZIK
*JEZIK
NAZIV

tablica VIJEST_JEZIK
*VIJEST
*JEZIK
TEKST

Dopuna, “VIJEST” je vrlo specifična, možda je bolje CLANAK.

ja sam bio u zaboravio staviti PK na tablicu i onda mi Zend javi error da mi fali PK.
Koristio sam Zend model za spajanje na bazu. Došlo mi je da ga pitam, a šta to njega briga:)
Ali opet dobro da je javio.

Vidio sa da neki stavljao username i mail za PK. Ja sam im rekao da to ne radim i kad su me pitali zašto nisam imao pravi odgovor.
Bio sam negdje pročitao mišljenje od jednog stručnjaka koji je rekao da podaci su podaci a PK treba biti pointer i ništa više, pa sam to tako prihvatio.

PK po meni može biti bilo što unique, znači username, mail, JMBG ili sada OIB, nije greška ako imaš autonumber, ali pitam se više put čemu to…

Primarni ključ svakako nije “pointer”. Niti ne znam što bi to značilo u kontekstu baza podataka.

Tablica u bazi podataka je entitet. Svaki redak tablice predstavlja jednu stvarnu pojavnost tog entiteta koja onda ima i svoj identitet - nešto po čemu se razlikuje od svakog drugog pripadnika iste vrste.

Kao primarni ključ se izabire najmanji skup atributa nekog entiteta koji ga u potpunosti i jednoznačno identificira. Često puta ima više takvih kombinacija atributa, koje se nazivaju alternativni ključevi.

Kolokvijalno govoreći, ako imamo entitet “osoba”, onda će primarni ključ biti par (ime, prezime). Ovdje sam rekao “kolokvijalno govoreći”, jer u stvarnosti ime i prezime nisu jedinstveni identifikator osobe. Zapravo, kod ljudi, koliko god atributa uparili (ime, prezime, datum rođenja, mjesto rođenja, spol, visinu, težinu), nikada nećemo dobiti pouzdano jednoznačan način identifikacije, ali čemo dobiti stvarno ogroman primarni ključ. Zato se u takvim situacijama često koriste umjetni, dodijeljeni jednostavni atributi za koje je unikatnost garantirana unutar neke domene i uz neke prihvatljive ograde (npr. OIB ili JMBG ili e-mail ili korisnička oznaka ili sl.).

Neki drugi entiteti poput gradova se lako mogu identificirati poštanskim brojem (ili parom “kod države”, “poštanski broj” i sl.).

U konačnici, u stvarnom, modelu ćeš izabrati takav “prirodni” primarni ključ jer to odražava smisao i svrhu baze podataka kao jednog matematičkog modela stvarnosti. Tek bi na koncu, zbog potreba optimalizacije vremena izvođenja ili spremničkog prostora, tamo gdje vidiš da je to potrebno, kao PK izabrao nekakav posve besmisleni, umjetni, ali “mali” ili “brzi” ključ poput izmišljenog “autonumber” polja ili slično. Ali za to trebaš imati razlog.

No, ako ti nemaš koristi od primarnog ključa (tj. ne znaš što će ti ili ne vidiš da ti nečemu služi), onda nigdje ne stoji da ga moraš imati. I to ti je pravi razlog zašto ga nemaš: ne znaš što će ti.

Ići ubacivati primarne ključeve (ili bilo kakve druge značajke) bez nekog jasnog razloga se svodi na dodavanje “featurea” samo zbog “featurea” - i nvj. su takve značajke ionako onda pogrešno upotrebljene.

Razgovarao sam davno s osobom kojoj je glavni smjer baze zadnje dvije godine i ona mi je bila ispričalo apsolutno isto što je tsereg rekao.
Kad sam vidio kako dizajnira baze prati tu logiku i njemu je apsolutno nerazumljivo zašto stavljam PK a imam neki podatak koji je unique.

No meni je malo teško prihvatiti utvrđivanje činjeničnog stanja podaka koje se ipak može promjeniti i ne postoji nikakva garancija da će taj podatak u nekim drugim uvjetima biti isti.

Nisam našao niti jedan pravi primjer gdje bi korištenje internal primary key pod uvijetom da je unique primary key dobar bila neka prednost.
Osim kod self joina i odnosa parent child. Što je opet moguče da nisam dobro istestirao jer kad sam vidio da kod internal ključa sam dobio što sam htio nisam se više time zabavljao.

Malo sam potražio po webu i našao sam na ne baš referentnoj stranici što se baze tiče, no primjer je i više nego dobar. Vaša aplikacija koja za gradove uzima poštanski broj neće raditi u New Orleansu jer čak četri grada imaju isti poštanski broj:)

[quote=“gorrc”]No meni je malo teško prihvatiti utvrđivanje činjeničnog stanja podaka koje se ipak može promjeniti i ne postoji nikakva garancija da će taj podatak u nekim drugim uvjetima biti isti.[/quote]???

Daj pokušaj to reći zdravo-seljački.

[quote=“gorrc”]Nisam našao niti jedan pravi primjer gdje bi korištenje internal primary key pod uvijetom da je unique primary key dobar bila neka prednost.
Osim kod self joina i odnosa parent child. Što je opet moguče da nisam dobro istestirao jer kad sam vidio da kod internal ključa sam dobio što sam htio nisam se više time zabavljao.[/quote]Što ti je to “internal primary key”? Što znači “unique primary key”? Pa svaki je primarni ključ jedinstven, nema primarnog ključa koji nije “unique”?

[quote=“gorrc”]Malo sam potražio po webu i našao sam na ne baš referentnoj stranici što se baze tiče, no primjer je i više nego dobar. Vaša aplikacija koja za gradove uzima poštanski broj neće raditi u New Orleansu jer čak četri grada imaju isti poštanski broj:)[/quote]Vidi, svrha školskih primjera je da ti objasne logiku. A logiku si sasvim dobro razumio. U Hrvatskoj hrpa baza koristi poštanski broj grada jer zadovoljava potrebe. A što se pripetavanja tiče, da se citiram:[quote=""]Zato se u takvim situacijama često koriste umjetni, dodijeljeni jednostavni atributi za koje je unikatnost garantirana unutar neke domene i uz neke prihvatljive ograde[/quote]Šifrarnik koji pošte imaju je zapravo šifrarnik poštanskih ureda, a ne gradova i svatko tko dizajnira bazu podataka bi to morao shvaćati. To je posve proizvoljno izmišljen podatak i nije nikakav “prirodni atribut”, ali je stabilan, dobro poznat i prilično dobro korelira sa stvarnim gradom, stoga se čini kao dobar kandidat za šifriranje gradova, ukoliko se razumije stvarna domena i prihvate stanovite ograde. Ok?

Znači, DA - bez uključivanja mozga se ne mogu raditi niti baze podataka.


Na koncu, ne kužim baš u kojem smeru želiš ići? Hoćeš li reći što? Da ne vidiš zašto ne bi kao primarni ključ koristio uvijek auto-number? Pa nema razloga zašto ne bi.

Naravno, ako ne želiš koristiti već ugrađene i efikasne mehanizme baze kojima osiguravaš integritet podataka (da nemaš nemaš dva korisnika s istim korisničkim imenom, da nemaš zabunom dva puta upisanu istu stavku računa i sl.) - ti si posve slobodan o integritetu podataka se brinuti algoritamski, uključivši i situacije gdje imaš paralelni, istodobni pristup klijenata, te tretirati bazu podataka kao običnu vreću u koju metaš podatke. Mislim - što god je tebi, kao programeru - praktičaru jednostavnije, efikasnije, fleksibilnije, bolje dokumentirano, lakše za održavanje i nadogradnju, itd.

Ono što ti možda nedostaje je saznanje da prije izgradnje fizičkog modela dolazi faza logičkog dizajna. To je razina E-R dijagrama u kojoj uopće otkrivaš izgled svoje baze mapiranjem stvarnih stvari (materijalnih i apstraktnih) u rječnik relacija i entiteta. Ovdje otrkivanje entiteta, istraživanje njihovih atributa i identiteta čini ključan dio procesa stvaranja - procesa analize i dizajna. U tom procesu tražiš ne samo dobar model stvarnog sustava, već najjednostavniji model stvarnog sustava. Utvrđivanje identiteta, relacija, proces normalizacije baze i sl. su naprosti alati kojima nastojiš nered dovesti u red.

Hoćeš li ti poslije u svim tablicama koristiti izmišljene neke brojeve, to je tvoj problem, a ponajviše stvar tvog iskustva u sve kompleksnijim i kompleksnijim bazama.

[quote=“tsereg”]???

Daj pokušaj to reći zdravo-seljački.
[/quote]

Mislim čemu trošiti energiju na utvrđivanje jeli podatak podoban ili ne.
Mislim ako je JMBG broj, čime ga čini podobnijm od broja 1.
Ako taj JMBG ima neku vrijednost iz stvarnog života onda mi moramo imati i podatak da je taj JMBG valjan.
Dobro recimo da jest.
Uzmimo onda da isti bazu instaliramo za nekog bugara.
Mi smo kroz cijelu aplikaciju gdje god je zatrebalo povezati se s korisikom koristili JMBG ili još bolje kad je trebao osobni matični broj od korisnika uzeli smo JMBG.
Jel će to funkcionirati i za bugarsku, neznam.
Recimo da hoće.

Admin unese krivi JMBG i želi ga ispraviti, dobro nema problema, radi update svugdje gdje je koristio taj JMGB i sazna strašnu istinu zamjenio je dva korisnika i njihove JMBG.
Nema problema, dolazi održavanje isključuje primary.
Jel admin ima kakve veze s primary dok se key kreira unutar baze.
Nema, svi podaci se mogu mjenjati.
Onog treba kad je neki podatak iz “stvarnog života” uzet kao primary key unutar baze mi smo tom adminu zavezali ruke.
Jel to poželjno. Ponekad da, ponekad ne.
Ali dok postoji slučaj da je ponekad ne, čemu uopće razmatrati opciju da.

Siguran sam da ne dizajnirate aplikacije tako da korisnik može prčkati po primary keyu. Ali uz toga što je baza nekakav model stvarnog svijeta, baza je i backbone aplikacije. A aplikacija je ono što klijentu isporučujemo.
I mislim da je jednostavnije i kvalitetnije kad klijent za operacije na bazi šalje virtualni ID a ne poštanski broj, JMBG, kombinacije dva keya itd.

E da bugar ne mora zvati održavnje može uzeti, neki dva bezvena broja, upisati ih i onda opet iznova unjeti:)

Uzmimo recimo, da je email uzet kao primary.
Korisnik može mjenjati mail. Ima 500 postova.
Njegova izmjena je napravila 500 update u bazi.
Znači onaj ko dizajnira bazu nebi trebao imati uvid u to što su ti podaci u stvarnom svijetu već kako će oni utjecati i na samu aplikaciju i sustav.
Ako se odluči za taj famozi auto increment. Niti onaj ko radi na aplikaciji niti onaj ko dizajnira bazu ne moraju razmišljati o tome.
A kad radiš oboje, zašto ne spojiti ugodno s korisnim i rješiti se razmišljanja za dva čovjeka:)

JMBG nije baš tako lako fulati jer JMBG kao i svi takvi osobni brojevi važni (OIB, broj bankovnih računa…) imaju kontrolni broj te tu nema greške, ti sad tu nabrajaš neke iznimne situacije u kojima bi to trebalo, izmijenio si našu domenu događaja i naravno da su se izmijenila i pravila koja su prije važila, Mjenjanje E-maila, čak i da dozvoliš je takva rijetkost da je to zanemarivo…
kada imaš neku tablicu u kojoj nemaš ništa što je UNIQUE onda se upotrebljava autonumber, ali isto tako imamo i situaciju di su dva stupca unique, tu onda isto možeš staviti da 2 stupca čine primarni ključ recimo ovaj primjer imaš zgrade i sobe, sad svaka zgrada je označena nekim brojem, i svaka soba u zgradi, ti upisuješ sobe, znači imaš više soba sa istim brojem, i imaš više zgrada koje imaju tu sobu, ali ZGRADA->SOBA je svakako unique te je sasvim uredno ako ti je ZGRADA I SBA primarni ključ…

Imam jedan PK koji se sastoji od 10-ak polja.
Jesam li mogao dodati jedno novo polje da bude PK?
Naravno da jesam ali sam isto tako vidio da kombinacija tih polja MORA biti unique i stvar je bila riješena.

@Trnac u postpunosti se slažem, jedini problem koji se zna pojaviti kod toga je kada radiš SELECT ako želiš jedan specifičan red moraš navesti svih 10 entiteta,makar nije ni to neki problem, ali pitam se i kod performansi, dali će prije odabrati SELECT sa 1 uvjetom ili sa 10uvjeta …

To je izolirani slučaj i obično mi tablice imaju 1-4 polja u PK.
Naveo sam samo kao primjer da se ne treba nečega držati kao pijan plota jer dizajn baze nije matematika nego više umjetnost.

[quote=“trnac”]To je izolirani slučaj i obično mi tablice imaju 1-4 polja u PK.
Naveo sam samo kao primjer da se ne treba nečega držati kao pijan plota jer dizajn baze nije matematika nego više umjetnost.[/quote]

onda moram stavit X :smiley:

Da može ako znaš kakav je podatak zgrada i kakav podatak može biti soba.
Ali ako radiš web aplikaciju koju mogu koristiti ljudi iz cijelog svijeta.
Onda ne možeš unaprijed odrediti niti veličinu niti tip podatka.

Gdje piše da se soba mora biti broj, može biti 2B.
A gdje piše da se soba ne mora zvati “Predsjednički apartman sunce”.

Mislim baza se mora prilagodit web 2.0. a ja ne vidim drugi način osim kreiranja surogat PK.

koji web2.0? to je onaj izmišljeni pojam za stranice koje koriste javascript? lol
pa kad znaš domenu baze onda ju ideš i kreirat pa nećeš kreirat bazu za sajt koji će posječivat cjeli svijet da sadrži stvari koje važe samo za Hr…
i kakve veze “web2.0” sa dizajniranjem baze podataka? nema to veze jedno s drugim :wink:

[quote=“Kečko”]
pa kad znaš domenu baze onda ju ideš i kreirat pa nećeš kreirat bazu za sajt koji će posječivat cjeli svijet da sadrži stvari koje važe samo za Hr…
i kakve veze “web2.0” sa dizajniranjem baze podataka? nema to veze jedno s drugim ;)[/quote]

A dobro a kad idem kreirat sajt za cjeli svijet onda ću na Wiki (web 2.0) tražiti što vrijedi za i za Hrvatsku i za cijeli svijet.
Uostalom kakvo je to dizajniranje aplikacija koje mogu samo raditi u Hrvatskoj.
Jel zbog takvog razmišljanja imamo problema sa izvozom?

Web 2.0 stvarno nema nikakve veze sa bazom, vjerovatno zato jer su temelji relacijskih baza udareni dok je web bio “web alpha 0.001”.

A sad dali web 2.0 aplikacije nemaju nikakve veze s bazom, mislim da imaju i iskreno neznam na temelju kojeg korisnikovog unosa bi facebook, youtube itd itd, odlučili da nešto što korisnik unese u sajt da bude PK.

Tu je još termin SaaS koji kad se poveže sa Web 2.0 (RIA aplikacije) onda dobivamo zanimljivu kombinaciju u kojoj se svi slažemo baza igra ključnu ulogu.
A dali je takvu bazu kvalitetnije dizajnirati sa int auto_increment PK ili varchar 32 to je naravno na iskustvu.
A zašto sam napisao varchar 32 zato je u primjeru sa sobama ako bi stavio varchar 20 i imaš dvije sobe u istoj zgradi naziva
"Predsjednički apartman sunce".
“Predsjednički apartman kiša”.
Srezan ti bio na “Predsjednički apart” ako bi koristio varchchar 20.
Pa bi najelegatnije bilo haširati cijeli string i tako ga spremati i tako bi stvarno mogao biti 100% siguran da tvoj key će raditi u svakoj zgradi i hotelu na kugli zemljaskoj.

[quote=“gorrc”]A dobro a kad idem kreirat sajt za cjeli svijet onda ću na Wiki (web 2.0) tražiti što vrijedi za i za Hrvatsku i za cijeli svijet.
Uostalom kakvo je to dizajniranje aplikacija koje mogu samo raditi u Hrvatskoj.
Jel zbog takvog razmišljanja imamo problema sa izvozom?

Web 2.0 stvarno nema nikakve veze sa bazom, vjerovatno zato jer su temelji relacijskih baza udareni dok je web bio “web alpha 0.001”.

A sad dali web 2.0 aplikacije nemaju nikakve veze s bazom, mislim da imaju i iskreno neznam na temelju kojeg korisnikovog unosa bi facebook, youtube itd itd, odlučili da nešto što korisnik unese u sajt da bude PK.[/quote]

Logika je univerzalna i nema veze s geografskim položajem.

Prvi put čujem za te termine.

Ovo se kosi sa zdravom logikom i takvo što može napraviti samo diletant-amater crni pojas deseti dan.