[Alg] id opzoeken voor gebruik als foreign key

Pagina: 1
Acties:

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 23-05 14:53
Ik heb weer een vaag topicje bedacht naar aanleiding van een eenvoudig probleempje wat ik tegenkwam vandaag. Een voorbeeldje voor de duidelijkheid:
We hebben een tabelletje met orders. Daarin een kolom statusid, waarin aan wordt gegeven wat de status is (in behandeling/nieuw/afgekeurd/enz.) Deze statussen staan natuurlijk ook allemaal netjes in een tabelletje met een id als primary key.
code:
1
2
3
4
5
6
7
8
9
tabel orders
-id
-klantid
-statusid

tabel statussen
-id
-naam          (standaard naamgeving: NEW/BOUNCED/enz)
-leesbare naam (nieuwe offerte/enz)

Er komt en nieuwe order binnen, de status moet dus op nieuw komen te staan.
De tabel statussen kan met een update veranderd worden maar normalerwijze niet door de gebruikers. Wel moet het in de db staan vanwege vertalingen van de leesbare naam.

de vraag: hoe ga je hier mee om?
a. eerst de id opzoeken: SELECT id FROM statussen WHERE naam='NEW'
b. je hebt al de id's standaard gecached in één of andere include en hoopt dat deze nog in de database staat
c. een select into query gebruiken
d. je hebt je applicatie beter ontworpen/uitgedacht en komt dit probleem nooit tegen.

//titel 8)7

[ Voor 2% gewijzigd door djluc op 18-08-2004 00:40 . Reden: ja ik ben de topictitel vergeten, zelf mijn marker staat er nog ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

Ik zou persoonlijk zoiets als statussen geen eigen tabel geven. Wat betreft normaliseren zou het wel de ideale situatie zijn, maar in dit geval levert het geen tot weinig winst op.
In MySQL zou ik die hele tabel voor statussen weglaten, en een enum maken van alle statussen die mogelijk zijn, en die in het statusveld van de ordertabel stoppen. Op die manier moet je weliswaar het datatype van die kolom veranderen zodra er een nieuwe status wordt geïntroduceert, maar als je daarover gaat nadenken: hoe vaak komt dat nou voor? Waarschijnlijk nooit...
Iig, als je een enum hebt, dan heb je die hele 2e tabel niet, en hoef je dus ook niks te joinen bij je update. Erg praktische situatie dus, zij het met een verminderd genormaliseerd datamodel.

Edit: * NMe aait Delphi32. :)

[ Voor 4% gewijzigd door NMe op 18-08-2004 00:55 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 23-05 19:25

Delphi32

Heading for the gates of Eden

Yep, bekend probleem.
Ergens vind ik dat dit soort status-tabellen niet in de database thuis horen als tabel. Dat je een leesbare vertaling van je status nodig hebt snap ik, maar dat zou je ook op applicatieniveau kunnen afhandelen (de vertaling niet in de db dus).
Dus als je nou eens (puur brainstorm hoor, ik heb dit nog niet gebruikt) een eigen fieldtype definieert in je db waarin je als geldige waarden alleen de mogelijke orderstatussen opneemt, en het veld Order.Status van dat type maakt?
- de daadwerkelijke implementatie van dat veld maakt me niet zoveel uit (mag integer, of varchar of whatever you like zijn)
- statussen zijn niet meer te bewerken door de gebruiker (of door een stoute ontwikkelaar :))
- je hoeft geen ID meer op te zoeken, slechts de juiste veldwaarde op te geven bij bewerkingen

Mogelijk probleem is de onderhoudbaarheid van dit soort fieldtypes. Maar goed, het is maar een idee. Kan je er wat mee?
edit:
NMe84 was me net voor :'(

[ Voor 3% gewijzigd door Delphi32 op 18-08-2004 00:54 ]


Verwijderd

NMe84:
En wat nu als je toch een 'leesbare' naam aan een status wilt geven, of uitleg? Of een linkje naar uitleg?

Als de database structuur vaststaat, is het de vraag of het zinvol is om een status intern bij zijn naam te behandelen. Je zult dan in je applicatie die naam moeten hardcoden. Dat kun je op 1 centrale plaats doen, met bijvoorbeeld gedefinieerde waarden. Maar dan kun je beter nog met integers werken, de id's van die statustabel.

Wat vind je zelf zinniger? Strings gebruiken in je applicatie en extra en overbodige code schrijven, of constante integers en DIE een zinnige naam geven.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

Verwijderd schreef op 18 augustus 2004 @ 00:54:
NMe84:
En wat nu als je toch een 'leesbare' naam aan een status wilt geven, of uitleg? Of een linkje naar uitleg?
Taalafhankelijke tekst hou ik het liefst sowieso uit mijn databases. Beschrijvingen van een status zijn in het Nederlands natuurlijk anders dan in het Engels. Ik weet niet of multilanguage een vereiste is, maar als dat zo is, zou ik die beschrijvingen sowieso uit de database laten. En als het geen vereiste is, dan moet je gewoon doen wat je zelf het handigste vindt werken. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • JaQ
  • Registratie: Juni 2001
  • Laatst online: 23-05 21:02

JaQ

wat je wilt is functionaliteit hangen aan een vrij textveld (als ik het goed begrijp). Dat is dus vragen om problemen. De "naam" van de status is betekenisvol, dus kan niet geupdate worden zonder dat je software "breekt". De labels van je statussen zijn uiteraard wel updateble.

misschien wordt deze reactie wat bot, maar heb vandaag een erg matig humeur en net een discussie over dit met een junior hier gehad.

NMe84 --> nofi, maar waarom zou je geen tabel opnemen met vertalingen? Dat is net zoiets roepen als dat een applicatie altijd maar voor 1 bedrijf geschreven kan worden (hoezo multi-organisatie?, een ASP neemt natuurlijk voor iedere nieuwe klant een nieuwe database... we heten niet allemaal world online) En performance verlies? Moet je of een echte database gebruiken, of beter leren programmeren / ontwerpen (nofi nogmaals).

Niets mis met labels in je database dus. Zeker in een multi-language omgeving. De keuze om teksten in een bestand of template vast te leggen is een keuze, maar hoeft zeker niet de juiste te zijn. (ik leg zelfs templates vast in databases)

De gekozen database structuur is echter niet geschikt voor multi language, denk dan aan iets als dit:

code:
1
2
3
4
5
6
7
8
status
  - id
  - code

status_labels
  - status_id
  - language_id
  - translation


(in multi organisatie omgeving aangevuld met een organisatie_id in status_labels )

Egoist: A person of low taste, more interested in themselves than in me


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 23-05 14:53
De gekozen database structuur is echter niet geschikt voor multi language, denk dan aan iets als dit:
Dat heb ik niet meegenomen in de startpost omdat het niet noodzakelijk is voor de aard van het probleem. Uiteraard wordt dit wel op een correcte manier in de database opgeslagen.

Verwijderd

Ergens was er iemand die problemen heeft met die ID's in de applicatie bekend te maken. Mag daar wat meer redenering bij?
Ik zie enkel voordelen. Snellere queries (geen joins), je kan de description mooi ophalen uit een cache adhv die ID die je als constante ergens hebt gedefinieerd. (hands up, hoeveel security engines werken met unieke integers ofzo om actions, rollen, ...te definieren).

Onder normale omstandigheden wijzigen die getalletjes toch niet denk ik zo...

En talen opnemen in de database daar mag dan ook een mooie cache bovenop, want alle vertalingen uit de DB halen (héél grote tabel) adhv language-code en 'label ID' lijkt me ook iets wat niet leuk is voor een pagina met veel labels en gebruikers.... maar voor application specific vertalingen (statussen) vind ik de database zeker niet ongeschikt.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:06

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 18 augustus 2004 @ 12:47:
Ergens was er iemand die problemen heeft met die ID's in de applicatie bekend te maken. Mag daar wat meer redenering bij?
Ik zie enkel voordelen. Snellere queries (geen joins), je kan de description mooi ophalen uit een cache adhv die ID die je als constante ergens hebt gedefinieerd. (hands up, hoeveel security engines werken met unieke integers ofzo om actions, rollen, ...te definieren).
ID's cachen is heel iets anders dan ID's hard definieren. ID's cachen, ok. Maar hard definieren, zou ik zeker niet doen.
Onder normale omstandigheden wijzigen die getalletjes toch niet denk ik zo...
Dus jij kan van te voren aangeven wat er precies aan opties in de database moet ook al weet je klant/opdrachtgever dat niet precies?
Jou klanten/opdrachtgevers komen nooit achter nog met "maar doe optie wil ik daar ook nog bij hebben"?

[ Voor 3% gewijzigd door Creepy op 18-08-2004 14:10 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

en adhv wat haal je ze dan uit cache? nog een andere key?
businesslogicKey > DBPrimaryKey? Ergens moet je BL toch van die statussen afweten, dus daar gebruiken wij dan constanten voor. (er zijn zelfs ranges gedefinieerd voor elke module om keys in onder te brengen). Ik praat dan over status descriptions, action descriptions, object descriptions, ...

Als er een status bijkomt heb je wel héél wat meer werk in de business logic dan een constante wijzigen/toevoegen. (ik toch)

Of zie ik iets over het hoofd?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Creepy schreef op 18 augustus 2004 @ 14:09:
Dus jij kan van te voren aangeven wat er precies aan opties in de database moet ook al weet je klant/opdrachtgever dat niet precies?
Jou klanten/opdrachtgevers komen nooit achter nog met "maar doe optie wil ik daar ook nog bij hebben"?
offtopic:
:w Creepy


100% mee eensch:
A note about customers:

They often use the term "always" when they mean "usually"
They often use the term "never" when they mean "seldom"
M.a.w. Ik zou ze niet hardcoden in je app. Doe je dit wel, dat zul je regelmatig je software moeten aanpassen. Doe je dit met de DB dan kun je zelfs een schermpje knutselen waar ze zélf statussen bij kunnen maken.

Een extra join op zo'n tabelletje met maar (relatief) een paar statussen lijkt me niet zo'n ramp.

[ Voor 30% gewijzigd door RobIII op 18-08-2004 16:10 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:06

Creepy

Tactical Espionage Splatterer

RobIII schreef op 18 augustus 2004 @ 16:07:
[...]

offtopic:
:w Creepy


100% mee eensch:

[...]
offtopic:
RobIII O+
BBQ Fanaat ;)
Verwijderd schreef op 18 augustus 2004 @ 15:55:
en adhv wat haal je ze dan uit cache? nog een andere key?
businesslogicKey > DBPrimaryKey? Ergens moet je BL toch van die statussen afweten, dus daar gebruiken wij dan constanten voor. (er zijn zelfs ranges gedefinieerd voor elke module om keys in onder te brengen). Ik praat dan over status descriptions, action descriptions, object descriptions, ...

Als er een status bijkomt heb je wel héél wat meer werk in de business logic dan een constante wijzigen/toevoegen. (ik toch)

Of zie ik iets over het hoofd?
Als je database entries een 1 op 1 relatie hebben met je code, waarom zou je ze dan nog opnemen in de database? Voor een vertaling o.i.d.? ;)
Altijd leuk als je een ID in de code verandert (het is een constante, dus dat moet kunnen) en dat dan ook ineens je DB op de schop moet...

[ Voor 7% gewijzigd door Creepy op 18-08-2004 16:22 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 23-05 14:53
De discussie over performance is inderdaad interessant. Ik ben nu bezig met een app voor max zo'n 10 gebruikers. Maar toch wil ik leren hoe eht anders beter kan. Verder is het cachen inderdaad ook een optie, zie mijn startpost.
Doe je dit met de DB dan kun je zelfs een schermpje knutselen waar ze zélf statussen bij kunnen maken.
Dat doe ik uiteraard niet. ik log even in op phpmyadmin, voeg er één toe en reken een stukje maatwerk }) Serieus: een edit maken die een eenvoudig ini/include bestand bewerkt is natuurlijk ook geen probleem maar daar gaat het ook niet echt om.

Het meest intensieve gebruik is het ophalen van de gegevens. Verder is het toch weer wat extra code om een id op te zoeken. Een globale array met daarin de statussen en hun id's is ook nog een mogelijkheid. Dan heb je caching gedurende deze ene aanvraag.

Dit mag gerust nog een keer gequote worden: ;)
A note about customers:
They often use the term "always" when they mean "usually"
They often use the term "never" when they mean "seldom"
Pagina: 1