Ik ben een database aan het ontwerpen voor een project. Er is één tabel waar ik niet uitkom, welk ontwerp ik ook maak. Het gaat om de opslag van plaatsen, en de ligging er van.
Voorbeeld: De Nederlandse plaats Akkrum ligt in de Nederlandse gemeente Boarnsterhim. Deze gemeente ligt in de Nederlandse provincie Friesland. Friesland ligt in het land Nederland. Nederland ligt in Europa.
Laat ik er maar meteen bij zeggen dat het internationaal moet werken. Elk land heeft een eigen indeling, zo werkt Duitsland met deelstaten, Kreise en gemeentes. De database hoeft geen informatie over loop van de hierarchie (Nederland heeft provincies, Duitsland deelstaten, Nederlandse gemeente ligt in provincie, Europa bestaat uit landen dus een gemeente kan nooit rechtstreeks onder Europa vallen, enz..) te bevatten. Dat ondersteunt de software. Per land wordt ondersteuning geprogrammeerd.
Mogelijke toepassing:
Soort is een belangrijke variabele. Deze geeft het type plaats aan. Om praktische redenen heb ik elk land zijn eigen soort gegeven. Een plaats met soort "Land Nederland" komt natuurlijk slechts 1 keer voor want er is slechts 1 land Nederland.
Voorbeeld:
Voor elke taal heb ik een contante. Aan soort in de tabel plaatsnaam is er exoniem (officiële naam in de lokale taal), endoniem (officiële naam gebruikt in andere talen), niet-officiële naam en oude niet meer gebruikte naam (bijvoorbeeld Karl-Marx Stadt, het huidige Chemnitz in Duitsland).
Tot nu toe niet moeilijk. Hiermee kun je elke plaats invoeren.
Plaatsen moeten echter ook gekoppeld worden. Geregistreerd moet worden bijvoorbeeld dat Akkrum in gem. Boarnsterhim ligt, deze gemeente ligt in provincie Friesland, etc..
Daarbij speelt een aantal problemen:
- Er hierarchie ligt niet overal zo mooi vast als in Nederland. In Duitsland bijvoorbeeld bestaan Kreisfreie steden, die liggen dus niet in een Kreis. Je hebt zelfs steden die op zich zelf een deelstaat vormen.
- Niet elke plaats ligt mooi binnen één andere (grotere) plaats. Voorbeeld: In Frankrijk zijn er gemeentes die verdeeld liggen over twee kantons. Dus sommige gemeentes bestaan uit twee delen.
- Het verleden: Ik wil ook de historie en toekomst er in hebben van plaatsen en hun verhoudingen. En daar begint de ellende pas echt. Verder dan 150 jaar terug is gelukkig niet nodig. Maar dat maakt het fenomeen gemeentelijke herindelingen niet minder rampzalig.
Voorbeeld: Boarnsterhim is in 1984 ontstaan uit drie gemeenten. Twee daarvan zijn in zijn geheel in het nieuwe Boarnsterhim opgegaan. Eén daarvan is deels opgegaan in Boarnsterhim en deels in een andere gemeente.
Aanvankelijk dacht ik aan de volgende oplossing: Tabel met plaatselen, met een jaar_van en een jaar_tot, en de parent. Maar dat betekent dat je bij de eerstvolgende gemeentelijke herindeling alle plaatsen afzonderlijk moet wijzigen. Daarnaast worden gegevens dubbel opgeslagen, veel plaatsen hebben een identieke geschiedenis.
Dit is mijn huidige oplossing:
Elke plaats kan meerdere delen hebben. Parent geeft aan waar het deel ligt. Bij alle Nederlandse plaatsen hebben de delen dezelfde parent, maar in het eerder genoemde voorbeeld Frankrijk hoeft dit niet altijd zo te zijn. Ander voorbeeld is Turkije, dat deels in Azië, deels in Europa ligt. Alle andere tabellen in de database verwijzen dan ook naar een plaatsdeel, nooit naar de plaatstabel zelf.
Tot slot de variabelen "tot" en "opgegaan_in": Deze regelen veranderingen zoals herindelingen.
tot en opgegaan_in beide 0? -> Plaats bestaat nog
tot>0 en opgegaan_in 0? -> Plaats is opgeheven (komt zelden voor)
tot>0 en opgegaan>0 -> Plaats is opgegaan in andere plaats, recentelijk bijvoorbeeld gemeentes Moordrecht, Nieuwerkerk aan den IJssel en Zevenhuizen-Moerkapelle die per 1 januari 2010 opgaan in gemeente Zuidplas.
Tot nu toe nog steeds niet al te moeilijk. Als concreet voorbeeld gebruik ik de gemeente Boarnsterhim, omdat deze is ontstaan uit 3 gemeentes en naar verwachting in de toekomst weer wordt opgedeeld, bijvoorbeeld tussen Leeuwarden en Heerenveen.
Deze praktijksituatie levert op:
Boarnsterhim, 1 deel, nog bestaand.
Idaarderadeel 1 deel, opgegaan in Boarnsterhim sinds 1984
Rauwerderhem 1 deel, opgegaan in Boarnsterhim sinds 1984
Utingeradeel 2 delen, deel 1 opgegaan in Boarnsterhim sinds 1984, de andere in Skarsterlân.
Voorbeeld: De plaats Akkrum heeft als parent Idaarderadeel. Met een query is de achterhalen dat Akkrum momenteel in Boarnsterhim ligt.
Akkrum kan ook gekoppeld worden aan Boarnsterhim, maar dan is niet de achterhalen dat Akkrum oorspronkelijk in Idaarderadeel lag. Het eerste nadeel aan dit ontwerp: Potentiele fouten in de database. Software moet goed in de gaten worden dat plaatsen echt aan de oudste oorspronkelijke gemeentes worden gekoppeld, anders is de geschiedenis niet te achterhalen.
Met dit nadeel valt nog te leven.
Het wordt pas echt lastig als Boarnsterhim gaat splitsen. Twee delen, een deel Heerenveen en een deel Leeuwarden. In de database moeten minimaal 6 (!) delen Boarnsterhim komen.
Want:
Idaarderadeel -> Boarnsterhim -> Heerenveen
Idaarderadeel -> Boarnsterhim -> Leeuwarden
Rauwerderhem -> Boarnsterhim -> Heerenveen
Rauwerderhem -> Boarnsterhim -> Leeuwarden
Utingeradeel -> Boarnsterhim -> Heerenveen
Utingeradeel -> Boarnsterhim -> Leeuwarden
Utingeradeel -> Skarsterlân
Het wordt alleen eenvoudiger als deze mogelijke herindeling plaatsvindt over de oude gemeentegrenzen van 1984, maar die kans is niet zo groot. Ik zeg overigens niet dat die herindeling plaats gaat vinden, maar ik gebruik het als voorbeeld voor mijn ontwerp en de belemmeringen.
Het wordt dus behoorlijk complex. Stel dat over een x aantal jaren ineens bijvoorbeeld de provincies worden vervangen door gewesten met compleet nieuwe grenzen, dan wordt het helemaal een chaos.
Ik ben dan ook op zoek naar suggesties voor iets beters, met de volgende eisen:
- Internationaal, elk mogelijke land moet ondersteund kunnen worden
- Goed werkend met het verleden (ca. 150 jaar), heden en de toekomst (ook extreme situaties).
- Zo min mogelijk mogelijkheden om foute links te leggen waardoor informatie niet meer volledig uit de query's naar voren komt.
- Werkbaar. Er moet een userinterface omheen gebouwd kunnen worden zonder al te idioot veel programmeerwerk. Het huidige ontwerp voldoet niet aan deze eis, het wordt knap ingewikkeld als een gemeente als Boarnsterhim al in 6 delen wordt geknipt voor een niet ondenkbaar toekomstscenario.
Voorbeeld: De Nederlandse plaats Akkrum ligt in de Nederlandse gemeente Boarnsterhim. Deze gemeente ligt in de Nederlandse provincie Friesland. Friesland ligt in het land Nederland. Nederland ligt in Europa.
Laat ik er maar meteen bij zeggen dat het internationaal moet werken. Elk land heeft een eigen indeling, zo werkt Duitsland met deelstaten, Kreise en gemeentes. De database hoeft geen informatie over loop van de hierarchie (Nederland heeft provincies, Duitsland deelstaten, Nederlandse gemeente ligt in provincie, Europa bestaat uit landen dus een gemeente kan nooit rechtstreeks onder Europa vallen, enz..) te bevatten. Dat ondersteunt de software. Per land wordt ondersteuning geprogrammeerd.
Mogelijke toepassing:
code:
1
2
3
| ; TABLE plaats id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, soort INTEGER UNSIGNED NOT NULL, |
Soort is een belangrijke variabele. Deze geeft het type plaats aan. Om praktische redenen heb ik elk land zijn eigen soort gegeven. Een plaats met soort "Land Nederland" komt natuurlijk slechts 1 keer voor want er is slechts 1 land Nederland.
Voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| 100 Land Nederland 120 Nederlandse provincie 180 Nederlandse gemeente 195 Nederlandse plaats 400 Land Duitsland 410 Duitse deelstaat 440 Duitse kreis/district 480 Duitse gemeente 495 Duitse plaats 500 Land Frankrijk 520 Franse Regio 530 Departement (departement) 560 Arrondissement (arrondissement) 570 Kanton (canton) 580 Gemeente (commune) 595 Plaats |
code:
1
2
3
4
5
6
| ; TABLE plaatsnaam id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, plaats INTEGER UNSIGNED NOT NULL REFERENCES plaats(id), taal INTEGER UNSIGNED NOT NULL, naam VARCHAR(255) NOT NULL, status SMALLINT UNSIGNED NOT NULL, |
Voor elke taal heb ik een contante. Aan soort in de tabel plaatsnaam is er exoniem (officiële naam in de lokale taal), endoniem (officiële naam gebruikt in andere talen), niet-officiële naam en oude niet meer gebruikte naam (bijvoorbeeld Karl-Marx Stadt, het huidige Chemnitz in Duitsland).
Tot nu toe niet moeilijk. Hiermee kun je elke plaats invoeren.
Plaatsen moeten echter ook gekoppeld worden. Geregistreerd moet worden bijvoorbeeld dat Akkrum in gem. Boarnsterhim ligt, deze gemeente ligt in provincie Friesland, etc..
Daarbij speelt een aantal problemen:
- Er hierarchie ligt niet overal zo mooi vast als in Nederland. In Duitsland bijvoorbeeld bestaan Kreisfreie steden, die liggen dus niet in een Kreis. Je hebt zelfs steden die op zich zelf een deelstaat vormen.
- Niet elke plaats ligt mooi binnen één andere (grotere) plaats. Voorbeeld: In Frankrijk zijn er gemeentes die verdeeld liggen over twee kantons. Dus sommige gemeentes bestaan uit twee delen.
- Het verleden: Ik wil ook de historie en toekomst er in hebben van plaatsen en hun verhoudingen. En daar begint de ellende pas echt. Verder dan 150 jaar terug is gelukkig niet nodig. Maar dat maakt het fenomeen gemeentelijke herindelingen niet minder rampzalig.
Voorbeeld: Boarnsterhim is in 1984 ontstaan uit drie gemeenten. Twee daarvan zijn in zijn geheel in het nieuwe Boarnsterhim opgegaan. Eén daarvan is deels opgegaan in Boarnsterhim en deels in een andere gemeente.
Aanvankelijk dacht ik aan de volgende oplossing: Tabel met plaatselen, met een jaar_van en een jaar_tot, en de parent. Maar dat betekent dat je bij de eerstvolgende gemeentelijke herindeling alle plaatsen afzonderlijk moet wijzigen. Daarnaast worden gegevens dubbel opgeslagen, veel plaatsen hebben een identieke geschiedenis.
Dit is mijn huidige oplossing:
code:
1
2
3
4
5
6
| ; TABLE plaatsdeel id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, plaats INTEGER UNSIGNED NOT NULL REFERENCES plaats(id), parent INTEGER UNSIGNED NOT NULL REFERENCES plaatsdeel(id), tot INTEGER UNSIGNED NOT NULL, opgegaan_in INTEGER UNSIGNED NOT NULL REFERENCES plaatsdeel(id), |
Elke plaats kan meerdere delen hebben. Parent geeft aan waar het deel ligt. Bij alle Nederlandse plaatsen hebben de delen dezelfde parent, maar in het eerder genoemde voorbeeld Frankrijk hoeft dit niet altijd zo te zijn. Ander voorbeeld is Turkije, dat deels in Azië, deels in Europa ligt. Alle andere tabellen in de database verwijzen dan ook naar een plaatsdeel, nooit naar de plaatstabel zelf.
Tot slot de variabelen "tot" en "opgegaan_in": Deze regelen veranderingen zoals herindelingen.
tot en opgegaan_in beide 0? -> Plaats bestaat nog
tot>0 en opgegaan_in 0? -> Plaats is opgeheven (komt zelden voor)
tot>0 en opgegaan>0 -> Plaats is opgegaan in andere plaats, recentelijk bijvoorbeeld gemeentes Moordrecht, Nieuwerkerk aan den IJssel en Zevenhuizen-Moerkapelle die per 1 januari 2010 opgaan in gemeente Zuidplas.
Tot nu toe nog steeds niet al te moeilijk. Als concreet voorbeeld gebruik ik de gemeente Boarnsterhim, omdat deze is ontstaan uit 3 gemeentes en naar verwachting in de toekomst weer wordt opgedeeld, bijvoorbeeld tussen Leeuwarden en Heerenveen.
Deze praktijksituatie levert op:
Boarnsterhim, 1 deel, nog bestaand.
Idaarderadeel 1 deel, opgegaan in Boarnsterhim sinds 1984
Rauwerderhem 1 deel, opgegaan in Boarnsterhim sinds 1984
Utingeradeel 2 delen, deel 1 opgegaan in Boarnsterhim sinds 1984, de andere in Skarsterlân.
Voorbeeld: De plaats Akkrum heeft als parent Idaarderadeel. Met een query is de achterhalen dat Akkrum momenteel in Boarnsterhim ligt.
Akkrum kan ook gekoppeld worden aan Boarnsterhim, maar dan is niet de achterhalen dat Akkrum oorspronkelijk in Idaarderadeel lag. Het eerste nadeel aan dit ontwerp: Potentiele fouten in de database. Software moet goed in de gaten worden dat plaatsen echt aan de oudste oorspronkelijke gemeentes worden gekoppeld, anders is de geschiedenis niet te achterhalen.
Met dit nadeel valt nog te leven.
Het wordt pas echt lastig als Boarnsterhim gaat splitsen. Twee delen, een deel Heerenveen en een deel Leeuwarden. In de database moeten minimaal 6 (!) delen Boarnsterhim komen.
Want:
Idaarderadeel -> Boarnsterhim -> Heerenveen
Idaarderadeel -> Boarnsterhim -> Leeuwarden
Rauwerderhem -> Boarnsterhim -> Heerenveen
Rauwerderhem -> Boarnsterhim -> Leeuwarden
Utingeradeel -> Boarnsterhim -> Heerenveen
Utingeradeel -> Boarnsterhim -> Leeuwarden
Utingeradeel -> Skarsterlân
Het wordt alleen eenvoudiger als deze mogelijke herindeling plaatsvindt over de oude gemeentegrenzen van 1984, maar die kans is niet zo groot. Ik zeg overigens niet dat die herindeling plaats gaat vinden, maar ik gebruik het als voorbeeld voor mijn ontwerp en de belemmeringen.
Het wordt dus behoorlijk complex. Stel dat over een x aantal jaren ineens bijvoorbeeld de provincies worden vervangen door gewesten met compleet nieuwe grenzen, dan wordt het helemaal een chaos.
Ik ben dan ook op zoek naar suggesties voor iets beters, met de volgende eisen:
- Internationaal, elk mogelijke land moet ondersteund kunnen worden
- Goed werkend met het verleden (ca. 150 jaar), heden en de toekomst (ook extreme situaties).
- Zo min mogelijk mogelijkheden om foute links te leggen waardoor informatie niet meer volledig uit de query's naar voren komt.
- Werkbaar. Er moet een userinterface omheen gebouwd kunnen worden zonder al te idioot veel programmeerwerk. Het huidige ontwerp voldoet niet aan deze eis, het wordt knap ingewikkeld als een gemeente als Boarnsterhim al in 6 delen wordt geknipt voor een niet ondenkbaar toekomstscenario.