Pouziti autoincrementu - ukrok stranou

Honza Pazdziora adelton na informatics.muni.cz
Čtvrtek Červen 19 13:25:48 CEST 2003


On Thu, Jun 19, 2003 at 12:37:56PM +0200, "Zíka Aleš, Ing." wrote:
> 
> 	Jak takovouhle situaci nejlepe resit, kdyz se zmeni nejake udaje v
> adresari zakazniku (ICO, adresa, kontaktni osoba)?
> 	Kdyz to rovnou opravim v adresari, asi to neni to prave orechove,
> protoze kdyz si budu chtit z nejakeho duvodu chcti vytisknou kopii starsi
> faktury, natahne mi novejsi data a nebude shodna s originalem.
> 
> 	Napadaji me takovato reseni:
> 	1. Kopirovat vsechny udaje k fakture a adresrar pak uz dal
> nepouzivat. Ale tohle je asi prave to, co je podle relacni teorie spatne,
> ne?
> 	2. Zalozit ho jako noveho zakaznika. Ovsem pak budu mit problemy
> zjisit, ze se jedna o stejnou firmu pri statistikach typu "kdo toho od nas
> nejvic nakoupil za poslednich pet let", takze bych si tam musel vytvorit
> jeste nejaky mechanismus, ktery mi sdeli, ze tyhle tri zazanmy jsou valset
> jedna a tatáz firma.
> 	3. Zavest si nejake datumove atributy "plati od - do" a vybirat
> prislusny zaznam podle data vydani faktury. To mi ale prijde jeste
> komplikovanejsi nez v predchozim bode.
> 
> 	Jak zni teorie a co rika praxe, jak v takovemhle pripade nejlepe
> postupovat?

Ja bych prihodil jeste par prikladu: pracoviste v organizaci, tedy
cleneni na nadrizene a podrizene a ustavy a pobocky a fakulty a katedry
a tak; predmety vypisovane univerzitou, ktere se opakuji a jsou jakoby
porad stejne (student ma absolvovat Algebru III, tedy cokoli, co je
vypsano jako Algebra III), ale jsou pokazde jine, uci je nekdo jiny,
atp; databaze zbozi, ktere prodavame a chceme o nich mit evidovane
technicke udaje -- jenze napriklad v zavislosti na verzi firmwaru
mobilniho telefonu se zmeni funkce, ktere ten telefon ma, i kdyz
oznaceni toho mobilu se nezmeni.

V zasade i u tech zakazniku je problem, protoze oni se zakaznici mohou
slucovat a rozdelovat a byt nastupniky nebo nebyt nastupniky ... Na
prvni pohled ten clovek, co do databaze podle nove dosle faktury
zadava, ze se neco zmenilo, nemusi poznat, jestli je to jeste ta sama
entita, nebo uz neco noveho. A pro ucely interni statistiky (slev
a historie vztahu) muze byt potreba povazovat dve firmy za jednu, ale
pro ucely nejakeho oficialniho vykaznictvi vuci statu uz treba ne.

Po tom, co jsem si vyzral reseni par problemu s tim, kdy puvodni navrh
byl nemistne skromny a spolehal na vysledky analyzy, ktera rikala, ze
nektery udaj se nikdy nezmeni a pokud uz ano, tak nikdy nebude potreba
divat se na neho v minulosti, bych se v budoucnu nikdy nezdrahal
pouzit maximalne barokni konstrukci:

	cosi:
	id				integer		PK
	nejake_to_bezne_pojmenovani	varchar	not null

	cosi_historie:
	id				integer		FK(cosi.id)
	udaj1				nejaky_typ
	udaj2				nejaky_jiny_typ
	udaj3				nejaky_jiny_typ
	-- nebo dokonce udaje jako atribut hodnota
	platnost_od			date
	zmenil				integer		FK(tabulka_lidi.id)
	platnost_do			date

Kde ten atribut platnost_do je triggerem automaticky nastaven na
platnost_od blizsiho novejsiho zaznamu a cosi.nejake_to_bezne_pojmenovani
je triggerem nastaveno na nejakou vhodnou hodnotu z cosi_historie,
nejlepe nejake textove spojeni tech udaju. Pro bezne pouziti v aplikaci
(mam vypsat, o jakeho zakaznika jde) se vezme to
cosi.nejake_to_bezne_pojmenovani, a pro jakekoli vaznejsi pouziti
(vypsat udaj na fakture, a to i na fakture stare) musim vedet, 
k jakemu casovemu okamziku ten udaj chci. Takze defaultne jedu podle
sysdate (now, nebo jak to vase oblibena databaze pojmenovava)
a jinak podle casoveho udaje nedrazeneho objektu (cili zakaznikovy
udaje vezmu podle casu vytvoreni faktury).

Ta hodnota platnost_do mi zajisti, ze v te historii najdu co potrebuji
jednim neslozenym selectem.

V zavislosti na tom, co aplikacne uzivatelum povolim, jsou mozne dalsi
komplikace a rozsireni:

- Pokud uzivatel ma moznost zadat i platnost zmeny, tedy firma se
  pred mesicem prestehovala nebo slecna se vdala, i kdyz jsme to
  zjistili az ted, je potreba evidovat nejen tu platnost_(od|do) jako
  databazovou platnost toho, kdy byla provedena zmena, ale vedle toho
  i tu zadanou platnost. A podle situace brat udaj podle jedne nebo
  druhe platnosti. Pokud se budu ptat, jak se jmenovala pred tydnem
  slecna, o ktere jsem se dnes dozvedel, ze se pred mesicem vdala
  a takhle jsem to zadal do systemu, tak se chci dozvedet, ze se pred
  tydnem jmenovala uz svym "vdanym" jmenem. Pokud se ale budu ptat, na
  jake jmeno jsem teto slecne vystavil pred tydnem fakturu, budu
  samozrejme chtit videt jeji divci jmeno.

  Problem s race condition paralelne bezicich transakci nechavam na
  doladeni laskavemu ctenari. :-)

- Pokud uzivatel ma moznost zadat udaj i do budoucnosti (toto auto se
  od 1. cervence nebude jmenovat Superb, ale Superc, ale bude to furt
  to same auto), tak mi nemusi fungovat to vytahovani toho
  cosi.nejake_to_bezne_pojmenovani. Da se resit nejakou opakovane
  spoustenou davkou, ktera to po pulnoci prepocita -- ono se az tak
  moc nedeje, pokud tam bude stary udaj, protoze to je pouze informativni
  textovy udaj, nikoli neco podstatneho.

- Pokud je pro mne uzitecne vedet i kontinuitu ci souvislosti
  jednotlivych entit, musim si to drzet zvlast, a to nikoli atributem
  u te entity, ale zasadne tabulkami bokem

	cosi_ekvivalence:
	id1			integer
	id2			integer

  nebo

	cosi_podrizene:
	nadrizene		integer
	podrizene		integer

  protoze jen tak mam sanci uchovat m x n vztahy (nejen firma se
  zmenila z takove na makovou, ale i firma se rozdelila na tri, tato
  tri pracoviste byla zrusena a nahrazena jednim ...).

Abych odpovedel na Vami nabizene moznosti: to 1. je asi hodne drsne,
nicmene dokazu si predstavit, ze v okamziku, kdy je faktura vystavena,
si ji vykopirujete se vsemi udaji do tabulky bokem, treba jako XML
nebo nejak, protoze to je koneckoncu archiv a nove vytisteni stare
faktury by nemelo jet podle aktualni databaze. Podobne treba vystaveni
zapoctoveho listu. Nebo tak. Nedelal bych to pausalne u vseho, ale
zase bych to uplne apriori nezavrhoval, muze se hodit.

To 2: noveho databazoveho zakaznika bych zakladal v situaci, kdy
i v realnem svete je to nova firma. Podobne u jinych objektu. Tedka
treba ale nedokazu rict, jestli zmena s.r.o. na a.s. je jenom zmena
formy nebo stara konci a nova zacina. Co mi muze v me evidenci
napovedet je potreba mit striktne odlisene nejake dalsi navazane udaje
pro tu jednu entitu. Ono to vyplyne z primarnich klicu na jinych
tabulkach. Nicmene ano, tu souvislost je potreba tam pak mit bokem.
Ale nepovazoval bych to za nic spatneho.

Ad 3: ve skutecnosti je to snadne a pokud zacnete i k evidovanemu
pohlavi svych zamestnancu ci zakazniku pristupovat jako k casove
omezenemu udaji, nebude Vam cinit problemy se takhle chovat uplne ke
vsem udajum. Pozor na to, ze muze stacit jedna dvojice plati_do --
plati_do u udaje, ale mohou byt potreba dve, a neni to zamenne.

Jejda, to jsem se rozepsal ...

-- 
------------------------------------------------------------------------
 Honza Pazdziora | adelton na fi.muni.cz | http://www.fi.muni.cz/~adelton/
 .project: Perl, mod_perl, DBI, Oracle, auth. WWW servers, XML/XSL, ...
		Only self-confident people can be simple.


Další informace o konferenci Databases