Ontstaan van dubbele waarde

Status
Niet open voor verdere reacties.
Als de database dit weekend doorkomt zal ik eens naar de structuur kijken. Ik ben wel geen FE dev, dus alleen de database structuren.
 
Net terug van vakantie wacht ook ik met spanning op de database.
 
Goedenavond heren uit het hoge Noorden Noorwegen.
Ik heb mijn database ingekort tot 5 records.
Voor de goede orde is mijn doel om een werkende database te krijgen waarin ik mijn treinencollectie in wil beheren. Niets meer. Daarvoor heb ik Access genomen omdat ik in het verleden ook hier iets heb gedaan. De cursussen hen ik doorgenomen eb daar haal ik wel wat uit maar het meeste gebruik ik niet in mijn database. Het enige wat ik van jullie wil help mij om dit werkbaar te maken. Daarna zal ik waarschijnlijk niet meer met Access gaan werken. Dus probeer van mij geen access-programmeur te maken. In het begin vertelde ik jullie dat ik drie hoofd tabellen alle drie zijn het 1 op 1 relaties. Ik heb geprobeerd om ze samen te voegen tot 1 tabel d.m.v. een query maar daar kwam een foutmelding uit over velden met meerdere waarden zijn niet toegestaan. Dit probleem opgezocht maar kan deze velden niet vinden.
De velden met een keuzemenu: Maatschappij en Fabrikant en de bij behorende logo's werken niet. Wel heeft dit eens gedaan maar nu ik aan het rotzooien ben, ben ik de draad kwijt. Kunnen jullie mij alsjeblieft zeggen waar de fouten in zitten of verbeter mijn model.
Groet Auke
 
Zonder de database te zien blijft het koffiedik kijken.
 
Ik heb even vlug naar de structuur gekeken en heb alvast de volgende vragen/opmerkingen:
  • waarom de outer joins in de relaties? Outer joins zou ik in de queries leggen, niet in de relaties tussen de tabellen
  • ik zou de sub datasheets uitschakelen in de tabellen. Dat is alleen storende overlast
  • in de tabel T_Assen lijkt het veld Assen, omschreven als: 'Het aantal assen volgens standarisering' niet de aangewezen kandidaat om als PK te gebruiken
  • tabellen T_Treinsamenstelling/T_Decoder/... zijn nergens aan gerelateerd WIP (Work In Progress)?
  • In tabel T_Verzekering/financieel zou ik geen / teken in de naam gebruiken en velden Totaal_aantal_in_serie;Nummer in serie en Serienummer lijken niet in deze tabel thuis te horen
  • T_kleur heeft geen PK. Als je niet op kleur gaat zoeken, lijkt dit me een overbodige tabel en kan je de kleur beter rechtstreeks in de tabel noteren als tekst.
Aangezien het jaren geleden is dat front-end applicaties maakte laat ik forms en rapporten aan de collega's over om na te kijken. Succes

PS: wat het vriendelijke "Goedenavond heren" betreft: er zijn ook dames bij ;)
 
Het probleem zit denk ik in de relatie tussen materieel en verzekering. Je hebt Id_verzekering (sleutel van verzekering) gekoppeld aan Id_Materieel, terwijl in verzekering ook een veld Id_materieel voorkomt.
De tabel verzekering/financieel lijkt me in deze vorm sowieso (deels) overbodig. Een stuk materieel heeft bijvoorbeeld maar één aanschafprijs- en datum, dus die velden kan je net zo goed in de tabel materieel opnemen. Merk op dat serienummer en nummer in serie (wat is het verschil) in beide tabellen voorkomen.
Een verzekering kan je meer dan één keer afsluiten, maar ik weet niet of je dat wilt vast leggen. Ik vraag me sowieso af of je allemaal aparte verzekeringen per stuk materieel afsluit.

Ook van echt bedrijf vraag ik me af af dat een één-op-veel is. Als het al een aparte tabel is, dan zou de relatie misschien zelfs andersom moeten lopen! Als je twee exemplaren van bijvoorbeeld een zelfde loc hebt, horen daar dezelfde echt gebruik gegevens bij.

Decoder? Zit er denk ik ook hooguit één van in een loc.

Noella signaleerde al opmerkelijke zaken in je relaties. Maar er is meer. Bij geen van de relaties wordt referentiële integriteit afgedwongen. Bij een aantal relaties heb ik geprobeerd dat aan te zetten en telkens lukte het niet omdat dan de regels voor referentiële integriteit zouden worden overtreden. Er zit dus iets grondig mis in de database. Bij de relatie tussen materieel en maatschappij is de fout bijvoorbeeld dat er in materieel een maatschappij Deutsche Bundesbahn genoemd wordt die niet in de tabel maatschappij voorkomt (opvallend genoeg wel DB en DB AG.

Werk aan de winkel dus.
 
Als je twee exemplaren van bijvoorbeeld een zelfde loc hebt, horen daar dezelfde echt gebruik gegevens bij.
Als je meerdere exemplaren van hetzelfde materiaal hebt zou ik dit in twee tabellen noteren. Eén T_Materiaal met alle gegevens die voor alle exemplaren hetzelfde zijn zoals type, ect. en één voor de exemplaren met de exemplaar specifieke informatie zoals prijs, ect.

Wat referentiële integriteit betreft, dit is typisch iets voor Access tabellen . Ik weet ook niet als dit wel echt overal nodig is. In databases gebruiken we constraints om de data-integriteit te beschermen, maar zijn daar spaarzaam mee en proberen die alleen aan te maken waar het werkelijk nodig is .
 
Bedankt voor jullie reacties.
Ik ga ze proberen stuk voor stuk te bestuderen en kijken of ik dit kan herstellen.
Groet Auke
 
@noella: TS groette alleen de Hoge Heren Uit Het Hoge Noorden. Daar val ik ook niet onder, dus ik voel mij óók niet aangesproken ;).

Ik ben het om te beginnen eens met de meeste opmerkingen van noella, dus die hoef ik niet te herhalen. Wel een kleine aanvulling op haar eerste opmerking over de Outer Joins (inderdaad: vervang ze allemaal door een Inner Join (optie 1), want hier nergens voor nodig). En wel deze: een Outer join op tabelniveau kan best handig zijn in sommige gevallen. Bijvoorbeeld: je zit op een plek waar je bestellingen aanneemt, en er belt een nieuwe klant. Dan wil je zo snel mogelijk de bestelling opnemen, bij voorkeur uiteraard ook met de juiste klantgegevens. Alleen: die klant bestaat nog niet. In dat geval zou je, als je een Outer Join hebt tussen Bestellingen en Klanten, tóch eerst de bestelling in kunnen geven, en dan achteraf de klantgegevens aanvullen. Of dat een handige werkwijze is, is een heel andere vraag :). Maar goed, daar zou je dus een Outer Join in kunnen zetten.
Normaal gesproken wil je juist geen gegevens kunnen invoeren die je niet hebt. Dus wat er ook gebeurt: nooit een outer join :).

Wat echter véél erger is: je hebt bij de meeste tabellen geen <Referentiële Integriteit afdwingen> aangevinkt. Dat maakt alle gelegde 'relaties' volkomen waardeloos. Maar dan ook écht in de zin van nutteloos. De relatie Conditie -> Conditie (ook weer zo'n outer join) doet echt helemaal niets: je kunt net zo goed de velden [Conditie] uit t_Conditie koppelen aan [Serienummer] uit t_Verzekering. Of het veld [Datum]. Mag allemaal, Access haalt zijn schouders op en denkt: la-mar-gaan. Zet ik <Referentiële Integriteit afdwingen> wél aan, dan kan ik de relaties meestal al niet meer leggen. Reden? De gegevens kloppen niet in de tabellen. Kortom: werk (een boel zelfs) aan de winkel!

Wat mij ook opviel: te pas en te onpas gebruik je bijlage velden. Niet doen, zou ik zeggen. Sla bijlagen niet op in de database, maar in aparte map(pen) onder de database. En gebruik tekstvelden om naar de bijlagen te verwijzen om ze op formulieren te tonen.
Tweede opmerking: de tabel [Logo_maatschappij] is niet genormaliseerd, met drie (ook nog eens bijlage)velden voor [Logo_maatschappij]. Ook niet doen dus: desnoods een extra gekoppelde tabel voor andere logo's. Of zaken die veelvuldig kunnen veranderen.
Nog een voorbeeldje van een slecht genormaliseerde tabel: de tabel t_DecoderGegevens met daarin de velden CV-01 t/m CV-123. Daar staat weliswaar een optionele beschrijving bij, maar dat zou ik toch echt anders doen. Bijvoorbeeld door een codetabel te maken met die codes als sleutelveld, en een naamveld met daarin de beschrijving die je nu hebt en eventueel een memo veld om het veld verder te omschrijven. In een koppeltabel leg je dan voor elke combinatie een record vast.

Kortom: knap eerst de basis op, dan gaan we naar de formulieren kijken :).
 
Nog een voorbeeldje van een slecht genormaliseerde tabel: de tabel t_DecoderGegevens met daarin de velden CV-01 t/m CV-123. Daar staat weliswaar een optionele beschrijving bij, maar dat zou ik toch echt anders doen. Bijvoorbeeld door een codetabel te maken met die codes als sleutelveld, en een naamveld met daarin de beschrijving die je nu hebt en eventueel een memo veld om het veld verder te omschrijven. In een koppeltabel leg je dan voor elke combinatie een record vast.
De naam van de velden is misschien niet zo duidelijk voor mensen die geen treincollectie hebben, maar elk veld heeft wel een andere betekenis, dus als elke decoder maar 1 lokadres, minimale snelheid ect. kan hebben zie ik geen reden om dit nog verder uit te splitsen. Dan zijn dit duidelijk eigenschappen van de decoder.
 
Mits je (grotendeels) alle velden moet vullen, dan zijn die velden op zijn plek in die tabel. Zelfs met onlogische namen (al zie ik de logica daar niet van in; het maakt een tabel bepaald niet overzichtelijker als je codes gebruikt als veldnamen). Is dat níet het geval (pak ‘m beet zo’n 30-40%) dan zou ik toch voor een koppeltabel gaan, zoals aangegeven.
 
Gegroet dames en heren ;) , hier weer een berichtje uit het hoge Noorden.

Sorry voor de vorige aanhef, ik dacht dat ik met manspersonen te maken had maar dat is natuurlijk niet vanzelfsprekend. NoellaG nu begrijp ik dat jij een vrouw bent, OctaFish? Peter kan ik begrijpen.

Eerst de opmerkingen van NoellaG;
  • waarom de outer joins in de relaties? Outer joins zou ik in de queries leggen, niet in de relaties tussen de tabellen Als ik de relaties verwijderd en opnieuw aanbrengt dan krijg je bij de knop <Jointype> de mogelijkheid om een Outer Joins te maken. Daar doe ik dus niets mee?
  • ik zou de sub datasheets uitschakelen in de tabellen. Dat is alleen storende overlast Wat zijn dat?
  • in de tabel T_Assen lijkt het veld Assen, omschreven als: 'Het aantal assen volgens standarisering' niet de aangewezen kandidaat om als PK te gebruiken Heb ik weggehaald dit is een tabel voor een Keuzevak
  • tabellen T_Treinsamenstelling/T_Decoder/... zijn nergens aan gerelateerd WIP (Work In Progress)? Klopt.
  • In tabel T_Verzekering/financieel zou ik geen / teken in de naam gebruiken en velden Totaal_aantal_in_serie;Nummer in serie en Serienummer lijken niet in deze tabel thuis te horen Klopt, heb ik uit de tabel verwijderd.
  • T_kleur heeft geen PK. Als je niet op kleur gaat zoeken, lijkt dit me een overbodige tabel en kan je de kleur beter rechtstreeks in de tabel noteren als tekst. Deze tabel is bedoeld voor een Keuzelijst met invulvak in het formulier. Voor dit soort tabellen heb je toch geen PK nodig?
Een belangrijke reactie van OctaFish:
Wat mij ook opviel: te pas en te onpas gebruik je bijlage velden. Niet doen, zou ik zeggen. Sla bijlagen niet op in de database, maar in aparte map(pen) onder de database. En gebruik tekstvelden om naar de bijlagen te verwijzen om ze op formulieren te tonen. Krijg ik ze dan wel meteen te zien op mijn formulier bij het doorbladeren? De tekstvelden, hoe gaat dat in zijn werk? Ik heb op internet gekeken en dat gaat dan met veel VBA. Hoe richt ik mijn tabellen hiervoor in?

Voor het afdwingen van de <Referentiële Integriteit afdwingen> kloppen er gegevens in de tabel niet. Welke dan niet waar moet ik op letten?

Misschien een gekke vraag; maar zou één van jullie mijn Database in orde willen maken zodat ik verder kan gaan? Ik weet het niet zeker maar dat kost misschien minder tijd. Ik zou die persoon daar eeuwig dankbaar voor zijn.

Groet Auke
 

Bijlagen

  • Referentie tabellen.jpg
    Referentie tabellen.jpg
    129,2 KB · Weergaven: 4
Punt 1: ja, daar doe je normaal gesproken niets mee. Om de redenen die ik heb uitgelegd: je brengt jezelf in de situatie waarin je niet-gerelateerde records kan toevoegen in andere tabellen. En dat is het laatste dat je zou moeten willen. Wat je dus wel moet willen: Referentiële Integriteit afdwingen tussen tabellen. Daarmee garandeer je valide informatie in je tabellen.

Punt 2: dat punt kun je vergeten. In Access kun je gekoppelde tabellen zien in een hoofdtabel; dat heet dan ‘sub datasets weergeven’ of zoiets. Heb je daar geen last van: niets aan doen.

Punt 6: Toch wel. In ieder geval een sleutelveld om te voorkomen dat je een kleur twee keer toevoegt. Stel je keuzelijst zó in dat je altijd ontbrekende kleuren kunt toevoegen (gebeurtenis NotInList).

Wat de bijlagen (en het vermijden ervan) betreft: daar is weinig VBA voor nodig; je hebt dus een tekstveld waarin je de verwijzing naar de bijlage/afbeelding als tekst wegschrijft (D:\Databases\Jouw database\Afbeeldingen\Plaatje 1.jpg etc). Op het formulier staat dan een niet-afhankelijk Image object dat als bron het tekstveld krijgt. Dat is één regel VBA :). Eventueel 2, als je er een Repaint aan toevoegt.

Sowieso kom je er gauw genoeg achter dat je eigenlijk geen nette database kunt maken zonder íets van programmeren af te weten. Je database wordt er namelijk een heel stuk beter van als je hem kunt automatiseren met handige procedures. Zo heb ik bijvoorbeeld nog wel ergens een functie liggen die een bijlage naar een submap kan verplaatsen, de verwijzing ernaar in een (nieuw) tekstveld en de bijlage dan verwijdert. Je bent niet de eerste die het bijlageveld gebruikt :).

Ik weet niet of wij de aangewezen persoon zijn om jouw data op te schonen, want hoe moeten wijnsteen wat goede data is en wat niet? Dat zou ik toch echt zelf doen. Wat ik wél voor je kan doen is een paar queries “Niet-gerelateerde Records” in je systeem zetten zodat je makkelijk kan zien om welke records het gaat. (Die maak je overigens simpel met een wizard) Dan kun je zelf bepalen of je de ontbrekende records wilt toevoegen, of de niet-gerelateerde wilt weggooien.

Ik kijk morgen wel even naar die functie en query. En zal op een formulier laten zien hoe zo’n tekstveld dan werkt.
 
Ik heb in mijn tabel T_materieel een veld aangemaakt voor Afbeeldingen maar als ik meerdere foto's wil toevoegen aan een item? Moet daar dan niet een aparte tabel voor zijn bv T_Afbeeldingen met de velden Id_Afbeelding, Id_Materieel, Pad (deel van de plaats op de schijf tot de afbeeldingen) , Pad_fabrikant (de map per fabrikant, Pad_foto (plaats van de *.jpg) en eventueel een omschrijving. Hieruit volgt de vraag: kun je velden samen voegen zodat ze één string vormen waarmee je dan het zoekpad creëert? Het zijn honderden foto's in verschillende mappen onder gebracht om een beetje ordening te krijgen, onder merknaam en type loc etc.. Het zou te gek zijn als ik in het formulier een merknaam selecteer dan deze dan ook gebruikt kan worden. Maar misschien lig ik de lat wel heeel hoog.

Over het wel of niet door jou of een ander persoon mijn data zou moeten opschonen; de data die in tabellen staan zijn voor mij vaste gegevens, het is juist om het e.e.a. te koppelen om een werkzaam geheel van te maken d.m.v. de formulieren. De formulieren had ik al een vorm gegeven. Het kost jou nu ook heel veel tijd en tikwerk om mij door de materie heen te loodsen. (als er kosten aan verbonden zijn ben ik bereid deze te vergoeden)
Zo niet dan stap voor stap op deze manier verder gaan.

Groet Auke
 
Meerdere foto's aan één tupel hangen houdt inderdaad in dat je een koppeling moet maken met de brontabel en de tabel met Afbeeldingen. An sich niet zo moeilijk. Je zou bijvoorbeeld op het formulier van je materieel een subformulier kunnen maken waarin je die afbeeldingen invoert. Een keuzelijst kan ook goed werken. Vaak wil je de afbeeldingen ook gelijk kunnen zien, en dan is een doorlopend formulier minder handig omdat de hoogte van één record dan ook de hoogte van de afbeelding bepaalt. Hoe hoger de afbeelding, hoe minder records je dan kunt zien. Of je gebruikt een relatief lage hoogte (zeg 1 cm) en je opent de foto dan in een apart scherm door op de thumbnail in het record te klikken.

Zelf zou ik niet beginnen aan het splitsen van het pad waar de foto's staan; je hebt immers het volledige pad nodig om de foto te bekijken. Dus sla dan ook het volledige pad op in één veld. Wél kun je de map met afbeeldingen (en die talloze submappen) in de map zetten waar je ook de database hebt staan. Dan kun je met een simpel commando (CurrentProject.Path & "\Afbeeldingen\") het hoofdpad gebruiken om afbeeldingen op te zoeken. Ik gebruik sowieso altijd een DialogFileOpen om te bladeren naar een afbeelding om die toe te voegen aan de tabel. Dan heb je dus het volledige pad al te pakken. Eventueel trek je het pad los van de naam van de foto, maar zelfs dat hoeft niet.

En je kunt natuurlijk alle reeds ingelezen foto's met een VBA procedure uit de Bijlage velden halen en verplaatsen naar de juiste submappen. Dan heb je alles automatisch geregeld: de verwijzing opgeslagen, de afbeelding opgeslagen en de bijlage verwijderd.

Wat betreft het opschonen: de data zijn dus niet correct t.o.v. de verschillende tabellen, want de tabellen zijn niet correct te koppelen. Ergo: er staan niet de juiste records in de tabellen. Dus ofwel in de hoofdtabel de ontbrekende records toevoegen (die data hebben wij niet) ofwel in de gerelateerde tabel de records verwijderen. En of een record weg mag, dat weet alleen jij :). Dus beide zaken ga ik niet voor je doen. Moet je echt zelf naar kijken. Heb je al geprobeerd om met de wizard Niet-gerelateerde Records te kijken om welke gegevens het gaat? Een voorbeeldje:

Code:
SELECT T_Materieel.Id_Materieel, T_Materieel.Omschrijving, 
T_Materieel.Materieel_type, T_Materieel.Materieel_codering
FROM T_Materieel LEFT JOIN T_Materieel_type
ON T_Materieel.[Materieel_type] = T_Materieel_type.[Materieel_type]
WHERE (((T_Materieel_type.Materieel_type) Is Null));
Laat één record zien, materieel type "BR 212". Die zit dus in je tabel t_Materieel, maar niet in je tabel t_Materieel_type. Daardoor kun je de twee tabellen dus niet correct koppelen. Ofwel BR212 bestaat niet, en die waarde mag je dus niet gebruiken, ofwel BR212 bestaat wél, en moet dus worden toegevoegd aan de tabel t_Materieel_type. Dat ga/kan ik echt niet voor jou bepalen.
 
T_kleur heeft geen PK. Als je niet op kleur gaat zoeken, lijkt dit me een overbodige tabel en kan je de kleur beter rechtstreeks in de tabel noteren als tekst. Deze tabel is bedoeld voor een Keuzelijst met invulvak in het formulier. Voor dit soort tabellen heb je toch geen PK nodig?
Als je niet op kleur gaat zoeken kan je nog altijd een keuzelijst maken met de waarden die reeds gebruikt zijn in dat veld met : select distinct [Kleur] from [T_materieel], daar hoef je nietperse een nieuwe tabel voor aan te maken

Voor de relaties kies je gewoon een Inner join (toon alleen deze gegevens waarvan het koppelveld in beide tabellen overeenkomt). Als je deze tabellen in een query gebruikt wordt deze relatie standaard overgenomen, maar in de query kan je deze nog aanpassen tot een outer join.

Denk ook goed na welke relaties wil afdwingen via referentiële integriteit. Alleen voor degene die je echt wil beschermen: bv je wil geen onderdelen noteren voor treinen die niet in de database zitten. Voor de tabel Fabrikanten is dat waarschijnlijk niet nodig. Het fabrikantenveld is een tekstveld waarin de naam van de fabrikant staat. In de tabel fabrikanten kan je verdere gegevens zoals het logo opzoeken als die gegevens bestaan. Als je de naam van de fabrikant vrij wil ingeven en alleen deze namen in de aparte tabel noteren als er daadwerkelijk verdere gegevens zijn, kan je dat met een gewone relatie doen zonder verdere controles, omdat het ook niet uitmaakt of die fabrikant wel degelijk bestaat in de tabel T_fabrikanten. In queries gebruik je dan een outer join naar fabrikanten om alle materieel te zien. Hetzelfde geldt voor materieel type.
 
Over het afdwingen via referentiële integriteit denk ik alleen aan de drie hoofdtabellen. Echter de tabel T_Echt_bedrijf zal niet voor alle records gelden, ik heb deze nu wel 1 op 1 gemaakt maar dat zou niet hoeven daar staan dan veel ongebruikte records in of zou ik dit zo laten?
Als je referentiële integriteit wilt afdwingen tussen 2 tabellen, T_Materieel en T_Verzekering_financieel moeten identiek zijn voor de overeenkomende velden in dit geval geld dit alleen het veld Id_Materieel. Het veld Condities heb ik ook een Keuzenlijst van gemaakt. Toch wil referentiële integriteit niet lukken.
De enige andere tabel die nog aan T_Verzekering_Financieel gekoppeld is T_Verkoper. Daar zijn en worden niet alle velden ingevuld. Dat is dan het zelfde wat NoellaG zei over Fabrikanten.

Het kwartje is gevallen voor Niet-gerelateerde Records. Ik ben daar mee bezig om dit te corrigeren.

Ik heb een keuzelijst gemaakt met daarin de kleuren in gekopieerd. Alleen weet ik niet waar ik <select distinct [Kleur] from [T_materieel]> in moet zetten.

Als ik iets heb veranderd dan komt er bij de Relaties een nieuwe tabel T_Materieel_1 bij of/en _2, _3, _4 ?
Wat ga ik hier meed doen?
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan