[ Tyler Durden @ 14.07.2016. 09:53 ] @
Prije svega, izvinjavam se na ovom clickbaity naslovu :-)

Zanima best practice, ili prosto kako vi rijesavate situacije gdje recimo imate neke artikle, i oni sad imaju neke standardne kolone, koje sve uvijek imaju neke vrijednosti, ali tu i tamo neki artikal recimo ima potrebe da ima jednu dodatnu kolonu, koja bi kod vecine ostalih artikala ili bila NULL ili imala neku default vrijednost. Lupam, neki artikal ima jos dodatno uputstvo za rukovanje ili upotrebu, koje je potrebno da se dodatno naglasi i napomene.
Varijanta 1: postoji ta kolona u tabeli artikal i da stavi NULL za sve one artikle koji nemaju vrijednost
Varijanta 2: postoji ta kolona u tabeli artikal i tamo gdje nema potrebe za specificnom vrijednoscu tog polja, stoji neki default koji vazi za sve te artikle
Varijanta 3: odvojena tabela koja ima FK iz tabele artikal, zatim ima kolonu CUSTOM_VALUE u kojoj se nalazi konstanta koja opisuje tu vrijednost (jer u ovu kolonu mogu da idu i druge custom vrijednosti, recimo napomena o isteku roka trajanja) i naravno kolona value u kojoj je taj sami specificni opis
Varijanta 4: ?

Imate li neke sugestije?
[ bogdan.kecman @ 14.07.2016. 10:07 ] @
ja licno ili v3 ili mnogo cesce v4, v4 je - nemam uopste jednu tabelu sa
kolonama vezanim za taj artikl vec imam sistem tabela, znas i sam tu
foru, imas objekat, imas object properties, svaki property ima type, u
odnosu na type ima vrednost u odgovarajucoj tabeli .. ako pogledam ove
vece shopove kojima imam uvid u strukturu date.. svi su v4 ..
[ Tyler Durden @ 14.07.2016. 10:11 ] @
Nažalost ne znam za tu foru :D
Možeš li samo malo još da je opišeš detaljnije ili da daš neki link gdje to opisano ili gdje ima neki primjer?
[ bogdan.kecman @ 14.07.2016. 10:39 ] @
stao mi mozak kako se zove taj model, mnogo je popularan spominjali smo
ovde na forumu bar 20 puta ... ako niko ne ucuka pre mene seticu se ja
cim se razbudim pa cu ti ucukam :D
[ jablan @ 14.07.2016. 11:00 ] @
https://en.wikipedia.org/wiki/...3attribute%E2%80%93value_model (EAV) i koliko vidim vodi se kao antipattern, tj. nešto što bi u većini slučajeva trebalo izbegavati. Kao alternativa predlaže se neko od nasleđivanja, ili (b)lob polje (koje u poslednje vreme baze jako dobro hendluju). Preporučujem knjigu SQL antipatterns.

Pogledaj i ovde: http://dba.stackexchange.com/q...me-for-this-database-structure
[ Tyler Durden @ 14.07.2016. 11:33 ] @
A imaš li da preporučiš neku od varijanti, ili glasaš za neku od predloženih?

edit: ok, sad gledam predloge na ovom linku...
[ bogdan.kecman @ 14.07.2016. 11:43 ] @
da da eav .. vidis kako ima ko ne zaboravlja te stvari :D ... ja mogu
pricam satima o njemu al kad treba se setim kako se zove stane mi mozak :(

obzirom da pricamo o okvirima mysql-a
- blob nije resenje
- json/xml i ostala bratija nisu resenje

a to da ih "dobro hendluju", hendluju ih uzasno, nego su developeri
poceli da sisaju "sve" a filtriranje rade na klijentu :(
[ bogdan.kecman @ 14.07.2016. 11:51 ] @
btw ovo sto ja koristim ( i sto uglavnim svi veliki koriste) je nesto
modifikovan eav, dakle nemas klasican key-value vec imas uz key i type a
onda imas po jednu tabelu za svaki type za value te onda iz ove ili one
tabele vadis value zavisno od toga koji je type .. malo komplicira
stvari ali ...

takodje svaka ozbiljnija implementacija ovde koristi SP za upisivanje
vrednosti te kroz sp radis kontrolu validnosti podataka (druga varijanta
je da je baza skroz glupa i da verujes dati koja dolazi sa klijenta, sto
nije bas moderan pristup)

e sad, kaze jablan "izbegavati" ... moras da izvagas dal ti treba ili ne
.. evo ti npr ooyyo.com ti je odlican primer, probali su eav varijantu
probali su klasicnu tabelu sa viskom kolona tj sve moguce kolone koje im
trebaju su stavili pa neki auto koristi ove a neki one .. varijanta sa
"viskom kolona" uzima oko 3x vise mesta (disk/ram) od eav varijante ali
varijanta sa viskom kolona radi za vise od red velicine brze od
varijante bez viska kolona .. tako da .. jbg .. sta ti je bitnije, da
sacuvas storage (ni ssd ni ram nisu bas jeftini) ili performanse :D ...
mobile.de na primer, ista prica .. sa druge strane bookings je eav (opet
budzen, ne klasican al eav) .. bitno ti je kako koristis podatke, sta
vadis, kad vadis, kako vadis .. ako te zanima 2-3 atributa samo za
pretragu bas te briga, sto kaze jablan turi to u blob a ta 2-3 atributa
izvuci u kolone i to je to ... web-u posaljes taj blob pa nek se smara
da ga raspakuje i prikaze kako mu volja :D ... ako radis pretragu po tim
atributima onda jbg .. zaboravi blob
[ Tyler Durden @ 14.07.2016. 12:19 ] @
Polja za koja mi ovo treba su manje bitna polja, nikakva pretraga se ne radi po njima i potrebna su samo da se prikazu uz taj proizvod kad se ode na detalje tog proizvoda.

Evo kako sam ja to trenutno zamislio, mockup skracena stripovana verzija.
tabela proizvod, ima id, i naziv prozivoda i datum unosa.
tabela sve_custom_vrijednosti ima id i naziv_custom_vrijednosti u kojoj ima nekoliko vrijednosti, npr. SPECIFICNO_UPUTSTVO_ZA_RUKOVANJE, pa onda NAPOMENA_O_ZAPALJIVOSTI itd....
tabela dodatni_info_o_prozivodu ima id, ima FK iz tabele proizvod, ima FK iz tabele sve_custom_vrijednosti i ima value u koje npr. stoji "za rukovanje ovim ultra zapaljivim lakom, nemojte da prinosite otvoreni plamen" i onda bih joinovima tih tabela izvlacio ako neki prozivod ima dodatne informacije.
[ bogdan.kecman @ 14.07.2016. 12:28 ] @
a vidi tu ti jablanova ideja sa blob-om radi posao 1/1 zato sto ti mysql
ne trosi neko mesto u tabeli za blob polje ako je prazno psoebno ako
nemas kljuc nad blobom .. dodas blob i u njega upucas sve to sto mora
negde da imas a ne treba ti
[ dusans @ 14.07.2016. 12:33 ] @
Pravo je pitanje da li su ovi SPECIFICNO_UPUTSTVO_ZA_RUKOVANJE, NAPOMENA_O_ZAPALJIVOSTI, itd...
dinamički ili ne i koliko ih ima?
[ Tyler Durden @ 14.07.2016. 12:39 ] @
^kako mislis da li su dinamicki ili ne?
oko njihovog broja... recimo da ima 1000 artikala, a ukupno ovih ili onih specificnih polja/opisa za sve te artikle zajedno ima mozda pedesetak
[ jablan @ 14.07.2016. 12:43 ] @
Citat:
Tyler Durden:
A imaš li da preporučiš neku od varijanti, ili glasaš za neku od predloženih?

Zavisi od slučaja. Svakako ne bih koristio mysql, za početak. :)
[ Tyler Durden @ 14.07.2016. 12:55 ] @
nadam se da kapiras koliko si konstruktivan :-)
[ jablan @ 14.07.2016. 13:09 ] @
Dobro de. Ali pazi, u zavisnosti od zahteva, možda ima logike i da dodaš poseban key-value store za ove podatke. Inače, ne znam zašto blob ne bi bio rešenje čak i pod mysql-om. Npr. Rails od verzije 4 ima prilično dobru podršku za serijalizaciju heševa u jedno polje, na Postgresu može da koristi hstore/json, a drugde koristi standardno text polje. Znači, može i ovako i onako.
[ Tyler Durden @ 14.07.2016. 13:22 ] @
kad kazete blob na sta konkretno mislite?
da dodam jos jednu kolonu u proizvod tabelu (i tako je denormalizujem) koja ce biti blob i u nju spucam sve sto sto je tako neko siroce od podatka, u nekom json ili xml formatu?
[ bogdan.kecman @ 14.07.2016. 13:25 ] @
sta moze da uradi u drugom rdbms-u ili key-value store-u je potpuno
nebitno za ovu temu, moze i da pise po papiricima i da koristi m$sql ili
oracle db potpuno mu isto pomaze ... mysql ne moze da radi nikakav
koristan search kroz strukturu u blobu a rails i njegova podrska za
blobove je vracanje na papirice i olovku .. dakle ako mu treba bilo
kakva pretraga po tim podacima blob je beskoristan za to u mysql-u ...
ako mu ne treba pretraga po tome onda moze da ih sacuva kako god .. u
blobu (koji sluzi bas za to) na primer..
[ jablan @ 14.07.2016. 13:32 ] @
@Tyler: baš to.
[ bogdan.kecman @ 14.07.2016. 13:40 ] @
blob, text, zavisi sta ce guras, koji format - koji je tebi zgodan ..
mysql tek od 5.7 ima neku pateticnu podrsku za json .. ako si na 5.7
mozda ti je zgodno da se igras sa tim, ako ne, uguraj sta god ti znaci
da lako zapakujes i otpakujes na klijentu ... ako je klijent neki php
serialize rulez :D
[ nkrgovic @ 14.07.2016. 14:37 ] @
Cisto iz licnog iskustva: Ako je u pitanju neka tabela koja se koristi za mnogo toga ima smisla podeliti je na dve. Posto ovde deluje da ce to da se koristi ja bi, ako ne ides na EAV, isao na dve tabele:

- Artikal (ID, Sifra, Ime, Cena, Lager). Ono sto ti UVEK treba, kad radis SELECT *, jer ces cesto da radis SELECT *. Vodi racuna, kad radis SELECT ID,Sifra,Ime,Cena, a nema covering index - to je isto SELECT *. DB Engine kad cita red uvek cita CEO red iz storage engine-a. Covering index ti resava taj problem, ali prouci sta je u MySQL-u covering index, moras da poklopis i redosled.

- ArticalDetails (ID, ID_Artikla, Polje1, Polje2....). Ovo dovlacis samo kad ti treba, implicitnim ili explicitnim join-om. Ovde mozes da imas i NULL-ove, ovo nije EAV, vec samo parcanje jedne tabele na dva dela. Ako ti svi ti dodatni podaci trebaju 5% vremena, onda 95% vremena ti trosis IOPS-e diska da ih citas u prazno.... Sto je, sto moja cerka kaze, blesavo. :D Na listanju, pregledu, kupovini i proveri lagera... na svemu tome ti ne treba podatak o roku trajanja, o garanciji, o cemu vec imas te dodatne atribute....

Ako guras u serijalizovani JSON, onda samo zguras taj json u drugu tabelu. Cilj je samo da ustedis resurse i da ne citas sve to svaki put kad gledas koliko ih ima na lageru, a da ne moras da imas planinu index-a da bi ti radilo stranicenje.
[ jablan @ 14.07.2016. 15:20 ] @
Jel može malo više info o "Vodi racuna, kad radis SELECT ID,Sifra,Ime,Cena, a nema covering index - to je isto SELECT *. " pošto mi zvuči prilično čudno? Mislim, jasno je da neće moći da izvuče i vrati podatke iz samog indeksa, ali da li zaista mora da čita SVA POLJA sa diska, da bi ti vratio samo neka?
[ bogdan.kecman @ 14.07.2016. 15:41 ] @
> ali da li zaista mora da čita SVA POLJA sa diska,

da, zavisno od storage engine-a cita ili ceo slog ili ceo page (u kome
je vise slogova), nije mysql izmisljotina, sve osim blobova se nalazi u
slogu i sa diska se cita ceo slog, blobovi se citaju u "drugoj turi" sa
"drugog mesta"..

za pg pogledaj npr
https://www.postgresql.org/doc...tatic/storage-page-layout.html i on
cita uvek ceo slog bez obzira sto vuces samo 1 kolonu (ignorisem
specijalne slucajeve za TOAST)

za mysql, dosta losija dokumentacija:
https://dev.mysql.com/doc/refm...nnodb-row-format-overview.html

ne znam kako radi mssql ali sybase od koga je nastao je citao ceo page
za svaki slog

...

tako da ne znam odakle cudjenje? ako mora da pipne tabelu (nema svu
potrebnu datu u indexu) mora uzme ceo row, teoretski ne mora ali je brze
da uzme ceo

inace mysql ne cida (po defaultu) manje od 1MB nikad sa diska, uglavnom cita ceo page, kesira (innodb_buffer_pool) etc etc .. ima cela prica objasnjena u manualu ali od kad su ga reformatirali nista ne umem tamo vise da nadjem pa me mrzi da trazim link gde sve to pise
[ jablan @ 14.07.2016. 15:46 ] @
Jasno. Pitanje je samo da li dodatne kolone tu unose vidljivu razliku po pitanju performansi. I u kom momentu ta razlika opravdava deljenje tabele po vertikali sa svime što to donosi, tj. novi indeksi, novi upiti, JOINovi itd.

http://stackoverflow.com/quest...lumns-affect-query-performance
https://www.percona.com/blog/2...f-columns-affects-performance/
[ bogdan.kecman @ 14.07.2016. 15:57 ] @
nemoj se preterano vezujes za SO tamo ima puno netacnih stvari posebno oko performansi ... (nisam citao taj link tako da mozda sve sto pisu 100% tacno) ali generalno za "dal bolje tante ili kukuriku" ne postoji univerzalni odgovor ... zavisi od slucaja do slucaja... bitno je da nekom bude jasno kako to radi da bi doneo pravu odluku ..

za mysql (da ne ulazim u ostale posto svi rade drugacije) mozes da racunas da on uvek cita ceo page, i taj page kesira, da li ti zelis da kesiras u ramu npr 50% nekih slogova koji ti nikad ne trebaju? podelis tabelu na dve i ono sto ti treba u 1% slucajeva bude kesirano samo 1% puta .. sa druge strane ako ti je valjan index i 90% citanja ti je samo index onda te bas briga i sve strpas u tu jednu tabelu .. ili ako imas 1000 artikala (neko spomenuo tu cifru?) 128G ram masina je danas dzaba ta baza nije cela velika 4-5G cela staje u ram, sto bi delio tabelu na 2 dela i komplikovao sebi zivot ... opet ako pricamo o petabajtnoj tabeli svaki bit koji moze da se ucari znaci ..

tako da ne bih ulazio u to sta je bolje, ja rekoh "najcesce", "veliki broj klijenata" i "ja" modifikovani v4 .. dal je najbolji, znam brdo primera gde bi to bilo samoubistvo, znam primere gde je do jaja resenje ..

jedino sto mogu da kazem "univerzalno", "silver bullet" je DOKUMENTACIJA ... sta god uradis do jaja dobro dokumentuj kako radi, zasto tako radi i zasto si doneo odluku da tako radi i koja si sve druga resenja uzeo u obzir i svako od njih zasto si odbacio, jer ta resenja, svake godine kada se radi review neko ce da predloze "ajmo da promenimo da bude ovako drugacije" .. ako nemas tu dokumentaciju - puno ce te kostati
[ nkrgovic @ 14.07.2016. 16:04 ] @
Nije ovo samo do MySQL-a, to definitivno rade sve row-based baze koje znam. Mislim da negde ima dokumentacija da i Oracle baza to radi (velika "oracle database"), to su pricali kad su uvodili columnar support....

Ovaj tekst sa Percona sajta je dobar, mada mator - ali neko moje iskustvo je da, kad imas 200 kolona, prelazak na tabelu od 10 plus drugu od 190 i te kako znaci. E sad, sa 10 ili 15 verovatno ne znaci puno, ali ako projektujes sad, onda bolje da projektujes za dve tabele, pa ce ova druga vremenom narasti do mnogo... opet to je iz nekog mog iskustva. Te stvari se stalno dodaju, kako projekat odmice, a 95% vremena se ne koriste.

Sto se performansi tice, po meni, ako ti 95% vremena ne trebaju sve te kolone, i mala usteda ce ti znaciti, jer stedis na 19 od 20 izvrsavanja - da bi jedno bilo nesto sporije. Po meni to nije los tradeoff.... Ja samo napominjem sad, jer je neke stvari, tipa ovoga, uvek lakse resiti na pocetku, nego posle raditi refactor. :D

Naravno, BLOB u MySQL-u to resava drugacije, sad za 5.7 izlazi i X api (ili kako se zove vec taj javascript fazon api), pa on ima neku json podrsku, sve to ima nesto svoje i neko dodatno resenje za json... Ja pricam samo ako hoces da imas row-based bazu da ima smisla ovo resiti u startu. Pazi, na toj dodatnoj tabeli ti, verovatno, i ne trebaju indexi sem po id-u iz druge tabele, tu ces ulaziti samo kad ti treba, verovatno, ceo slog i to za tacno odredjen artikal. Ono po cemu pretrazujes (cena, ima na lageru i sl). ces verovano drzati u osnovnoj artikal tabeli.
[ jablan @ 14.07.2016. 16:05 ] @
Hvala Bogi, odlični saveti. Inače, nisam linkovao SO kao argument za ili protiv, već kao zanimljivo štivo. Evo ovaj lik (170k+ karma) je benčmarkovao, mada nešto drugačiji slučaj, COUNT(*) nad tabelom bez indexa:

http://stackoverflow.com/quest...query-on?noredirect=1&lq=1
[ bogdan.kecman @ 14.07.2016. 16:30 ] @
ma da imamo malo vise ovakvih diskusja ovde, ucmao se forum, a i meni se malo vezba komunikacija na srpskom :D ..

elem innodb je uzasan kada je count(*) u pitanju ... uzasi promiskuiteta :( .. a inace razni testovi koliko brzo ce radi "full table scan" su uzasno beskorisni ... prvo tog sto napravi sistem koji radi fts treba neko rokne, drugo, taj sto napravi fts, taj fts nece radi "sam na masini" ka kad to krene da se gomila svi testovi koje si radio mozes bacis u kantu :( .. tako da dal ce neko ustedi 10% brzina za fts ako uradi ovo ili ono, nebitno ...

ne pricam o olapima i postanalizi deep date .. to je sad neka druga prica (i ne vidi zasto bi bilo ko sa 2 grama mozga za to koristio mysql) .. pricam o realnom real time poslu.. kakav upit od 90 sekundi u real time svetu radi posao? koji klijent ce ti saceka 90sec da mu se ucita strana, otvori rezultat na telefonu, aplikaciji .. to jos ove knjihovodje trpe jer ne znaju za bolje, vec ovi mladji zovu i prete tuzbom kad im tako nesto probas uvaliti ..

tako da - fts - ima tu mnogo sta sto moze ali beskorisno

a za normalan pristup .. kada je mysql u pitanju bitno je shvatiti razliku izmedju formata innodb tabela (ako pricamo o innodb-u), i razliku izmedju staticnog i dinamickog sloga i kako se sta gde pise i kada se cita ..
[ Tyler Durden @ 14.07.2016. 16:30 ] @
Citat:
Pazi, na toj dodatnoj tabeli ti, verovatno, i ne trebaju indexi sem po id-u iz druge tabele, tu ces ulaziti samo kad ti treba, verovatno, ceo slog i to za tacno odredjen artikal. Ono po cemu pretrazujes (cena, ima na lageru i sl). ces verovano drzati u osnovnoj artikal tabeli.


Ma da, bas tako.
A svidja mi se i ovaj inheritance koncept, vec vidim da bih to mogao da primjenim na jednom drugom mjestu, tj. u 2.0 verziji :)
[ bogdan.kecman @ 14.07.2016. 16:47 ] @
obrati samo paznju, ako to ne pretrazujes, onda moze da bude i u blobu,
koji ne zauzima mesto u tabeli a mozes da ga povuces jednostavno, bez
join-a, kad ti treba a u njega mozes upucas u formatu koji ti je zgodan
za klijent
[ Tyler Durden @ 14.07.2016. 18:46 ] @
razmislicu jos, ali nesto ne volim da imam denormalizovanu bazu ako bas nemam neki dobar razlog
[ bogdan.kecman @ 14.07.2016. 18:55 ] @
a vidi razlog je uvek TCO .. iliti cena ..
denormalizacija ti smanjuje operativne troskove jer ti povecava
performanse pa za manje pare dobijes vise, ali ti povecava troskove
razvoja jer moras da imas dobru dokumentaciju i kada radis promene moras
da konsultujes istu (klasicno dobro normalizovan model je
self-docummented dok kod denormalizacije moras da objasnis sta je sta i
zasto je to tako) ..
[ farmaceut @ 14.07.2016. 21:52 ] @
EAV model ili neka varijanta, iako se cesto ne preporucuje, u tvom slucaju bi mogao biti rjesnje.
Np, ja za medicinskie eviencije koristim neku hibridnu varijantu Bogdanove "v4", gdje neke uobicajene podatke stavljam u "klasicnu" tabelu, a ostatak informacija ide u EAV. Imam oko 500 "entiteta" (razliciti tipovi medicinskih dokumenata) i skoro 20k razlicitih atributa.

I to sljaka odlicno, naravno moras biti svjestan sta radis, i sta su ti ogranicenja....