Bekijk Volledige Versie : Database normalisatie
Martin Schapendonk
15/08/03, 15:15
Hoi,
Ik zit met een klein probleem waar ik zo 1 2 3 even niet uitkom. Ik denk
dat het triviaal is, ik zal er wel grandioos overheen zitten kijken.
Scenario: ik ben een trefwoordenlijst aan het maken. Die lijst is
opgedeeld in balies, een balie heeft 0 of meer items, en een item heeft
1 of meer trefwoorden.
Echter, de trefwoorden moeten uniek zijn *per balie*.
Na wat schrijfwerk komt daar dit uitrollen:
create table items (
id primary key,
...
);
create table trefwoorden (
id primary key,
...
);
create table balies (
id primary key, ...
);
create table items_trefwoorden (
id primary key,
item_id,
trefwoord_id,
...,
foreign key (item_id),
foreign key (trefwoord_id)
);
create table items_desks (
id primary key,
item_id,
desk_id,
...,
foreign key (item_id),
foreign key (desk_id)
);
Mijn gevoel zegt dat dit niet helemaal klopt, omdat desk_id bepaald
wordt door item_id, en je feitelijk dus uit die relatie af zou moeten
kunnen leiden of een keyword al in gebruik is op die desk.
Maar ik zie het even niet...
Wie wel?
Bedankt,
Martin
--
Martin Schapendonk, usenet@schapendonk.org
"The website you seek can not be located, but countless more exist."
Martin Schapendonk wrote:
> Hoi,
>
> Ik zit met een klein probleem waar ik zo 1 2 3 even niet uitkom. Ik denk
> dat het triviaal is, ik zal er wel grandioos overheen zitten kijken.
>
> Scenario: ik ben een trefwoordenlijst aan het maken. Die lijst is
> opgedeeld in balies, een balie heeft 0 of meer items, en een item heeft
> 1 of meer trefwoorden.
>
> Echter, de trefwoorden moeten uniek zijn *per balie*.
>
> Na wat schrijfwerk komt daar dit uitrollen:
>
> create table items (
> id primary key,
> ...
> );
>
> create table trefwoorden (
> id primary key,
> ...
> );
>
> create table balies (
> id primary key, ...
> );
>
> create table items_trefwoorden (
> id primary key,
> item_id,
> trefwoord_id,
> ...,
> foreign key (item_id),
> foreign key (trefwoord_id)
> );
>
> create table items_desks (
> id primary key,
> item_id,
> desk_id,
> ...,
> foreign key (item_id),
> foreign key (desk_id)
> );
>
> Mijn gevoel zegt dat dit niet helemaal klopt, omdat desk_id bepaald
> wordt door item_id, en je feitelijk dus uit die relatie af zou moeten
> kunnen leiden of een keyword al in gebruik is op die desk.
>
> Maar ik zie het even niet...
>
> Wie wel?
>
> Bedankt,
>
> Martin
>
does een beetje voorbeeld data....
Rene Pijlman
16/08/03, 00:15
Martin Schapendonk:
>Scenario: ik ben een trefwoordenlijst aan het maken. Die lijst is
>opgedeeld in balies, een balie heeft 0 of meer items, en een item heeft
>1 of meer trefwoorden.
>
>Echter, de trefwoorden moeten uniek zijn *per balie*.
>
>Na wat schrijfwerk komt daar dit uitrollen:
[...]
>create table items_trefwoorden (
> id primary key,
> item_id,
> trefwoord_id,
> ...,
> foreign key (item_id),
> foreign key (trefwoord_id)
>);
Ik zie de noodzaak voor een koppeltabel niet bij een 1-op-n relatie. Je
kunt toch in trefwoorden een verplichte foreign key item_id opnemen?
>create table items_desks (
desk == balie, neem ik aan.
Hiervoor geldt hetzelfde: je kunt in item een optionele foreign key naar
desk opnemen.
> foreign key (item_id),
> foreign key (desk_id)
>
>Mijn gevoel zegt dat dit niet helemaal klopt, omdat desk_id bepaald
>wordt door item_id, en je feitelijk dus uit die relatie af zou moeten
>kunnen leiden of een keyword al in gebruik is op die desk.
Als ik het goed begrijp probeer je hier een primary key te gebruiken om
een bepaalde constraint af te dwingen, terwijl die constraint naar zijn
aard geen primary key is. Dat kan wel, maar dan moet je de combinatie van
tref_id en desk_id in een PK/FK opnemen. Alleen vraag ik me af wat het
voor zin heeft. Want het veronderstelt dat elke transactie die een
trefwoord of balie manipuleert ook een record in deze extra tabel
toevoegt/verwijdert.
Is het niet beter om een constraint te definiëren? Of is er een reden
waarom je het anders wilt doen?
--
René Pijlman
Wat wil jij leren? http://www.leren.nl
Martin Schapendonk
17/08/03, 11:15
Rene Pijlman <reply.in.the.newsgroup@my.address.is.invalid> wrote in message news:<34mqjvsu22heft91l80743cdf5nh37no7p@4ax.com>...
> >create table items_trefwoorden (
>
> Ik zie de noodzaak voor een koppeltabel niet bij een 1-op-n relatie. Je
> kunt toch in trefwoorden een verplichte foreign key item_id opnemen?
Klopt, dat had ik eerst ook, maar toen kwam ik in de knoei met de
uniqueness tussen desk en trefwoord. Daarom heb ik trefwoorden in een
aparte relatie gezet en met twee koppeltabellen de relatie met items
en desks vastgelegd.
> >create table items_desks (
>
> desk == balie, neem ik aan.
Klopt.
> Hiervoor geldt hetzelfde: je kunt in item een optionele foreign key naar
> desk opnemen.
Ai, en hier ben ik vergeten te vermelden dat een item op meerdere
balies kan staan. Die koppeling is dus wel nodig. En in deze tabel
ligt een unique constraint op item_id en desk_id samen.
> >Mijn gevoel zegt dat dit niet helemaal klopt, omdat desk_id bepaald
> >wordt door item_id, en je feitelijk dus uit die relatie af zou moeten
> >kunnen leiden of een keyword al in gebruik is op die desk.
>
> Als ik het goed begrijp probeer je hier een primary key te gebruiken om
> een bepaalde constraint af te dwingen, terwijl die constraint naar zijn
> aard geen primary key is. Dat kan wel, maar dan moet je de combinatie van
> tref_id en desk_id in een PK/FK opnemen. Alleen vraag ik me af wat het
> voor zin heeft. Want het veronderstelt dat elke transactie die een
> trefwoord of balie manipuleert ook een record in deze extra tabel
> toevoegt/verwijdert.
Precies, en dan creeer je een update anomaly in je data. Daar liep ik
dus tegenaan. Dat probeer ik te voorkomen, maar zag niet echt hoe.
> Is het niet beter om een constraint te definiëren? Of is er een reden
> waarom je het anders wilt doen?
Het kan wmb wel met een constraint, daar heb ik ook naar gekeken. De
tabel ziet er dan zo uit:
create table items_trefwoorden (
trefwoord_id,
trefwoord,
item_id,
foreign key (item_id)
);
Je moet dan een constraint hebben die bij een insert/update adhv het
item_id het desk_id bepaald, en daarna de uniqueness van desk_id en
trefwoord controleert. Het gaat in dit geval om een Oracle database,
en een CHECK constraint is helaas beperkt tot checks binnen dezelfde
tabel. Dan zou ik het met triggers op moeten gaan lossen en dat leek
me nodeloos ingewikkeld. Maar als het moet... :-)
Heb je nog andere ideeen?
Groeten,
Martin
Rene Pijlman
21/08/03, 15:45
Martin Schapendonk:
>Je moet dan een constraint hebben die bij een insert/update adhv het
>item_id het desk_id bepaald, en daarna de uniqueness van desk_id en
>trefwoord controleert. Het gaat in dit geval om een Oracle database,
>en een CHECK constraint is helaas beperkt tot checks binnen dezelfde
>tabel. Dan zou ik het met triggers op moeten gaan lossen en dat leek
>me nodeloos ingewikkeld. Maar als het moet... :-)
>
>Heb je nog andere ideeen?
Mijn Oracle-kennis dateert nog van versie 7 en begint een beetje weg te
zakken, maar ook na enig bladeren in de 9i documentatie kom ik niet verder
dan de suggestie om triggers te gebruiken.
--
René Pijlman
Wat wil jij leren? http://www.leren.nl