Office Forum
www.Office-Loesung.de
Access :: Excel :: Outlook :: PowerPoint :: Word :: Office :: Wieder Online ---> provisorisches Office Forum <-
Hierarchie und Referentielle Integrität
Gehe zu Seite 1, 2, 3  Weiter
zurück: DB Upsizing mittels Skript automatisieren weiter: Daten vergleichen Unbeantwortete Beiträge anzeigen
Neues Thema eröffnen   Neue Antwort erstellen     Status: Offen Facebook-Likes Diese Seite Freunden empfehlen
Zu Browser-Favoriten hinzufügen
Autor Nachricht
sk42
Im Profil kannst Du frei den Rang ändern


Verfasst am:
14. März 2012, 14:36
Rufname:

Hierarchie und Referentielle Integrität - Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,

Für eine hierarchische Struktur (Projekte und Teilprojekte) habe ich bishger in der Projekttabelle ein Fremdschlüselfeld, in welches ich den Primärschlüssel des jeweils übergeordneten Projektes eintrage.
Nur wie behandle ich Projekte, die kein übergeordnetes Projekt haben? Ich habe da bisher immer "0" eingetragen. Das schließt aber eine referentielle Integrität aus, weil "0" im Primärschlüsselfeld ja nicht vorkommt.
Ich würde aber gerne auch hier die referentielle Inegrität nutzen. Wie aber identifiziere ich dann ein Projekt als Hauptprojekt (also ein Projekt, was keinem übergeordneten Projekt zugeordnet ist)? Ein Dummy-Eintrag dafür in der Projektliste zu machen finde ich unschön. Einen Verweis "auf sich selbst" ist nicht machbar, weil man das im Formular dann nicht über ein Kombinationsfeld auswählen kann (da der DS zu dem Zeitpunkt des Eintragens ja dort noch gar nicht existiert).

Wie macht man das am sinnvollsten?
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
14. März 2012, 18:22
Rufname:


AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,

Es ist eigentlich bei einer Selbstreferenzierung üblich, daß das/die Topelement(e) im Feld ParentID auf 0 gesetzt werden.

Die RI soll ja in erster Linie erzwingen, daß es in der Nachschlagetabelle bereits eine passende ID gibt, Du kannst also die gleiche Tabelle zweimal im Beziehungsfenster hinzufügen und dann die ParentID auf die ID verweisen lassen, mit RI, das funktioniert.

Auch das Eingeben ist kein Problem, sobald Du das erste Zeichen im Datensatz tippst, wird die ID (Autowert) schon erstellt und steht zur Verfügung, Du kannst eben nur keine 0 eintragen. Alternativ kannst Du aber einen Toplevel auch so markieren, daß die ID auf sich selbst zeigt, dann geht es auch mit der Eingabe wieder. Wobei ich persönlich eher eine ID 1 für das Toplevel-Element reservieren würde, da man das ja im Formular einfach mit WHERE ausblenden kann, denn ansonsten müßtest Du bei jeder Rekursion immer prüfen, ob ParentID = ID ist, um das/ein Toplevelelement zu bestimmen. Wenn das Toplevelelement 1 aber bereits in der Tabelle ist und selbst nicht Bestandteil einer Abfrage durch WHERE-Ausschluß, kann eine Rekursion einfach durchlaufen, ohne etwas zu prüfen.

@Kyron: Das Datenmodell ist völlig in Ordnung, eine Hierarchietabelle baut man i.d.R. immer mit einer Selbstreferenzierung auf, prominentes Beispiel ist die Employee-Tabelle der AdventureWorks- (Northwind-) Demodatenbank.
Es gibt sicher auch andere Lösungen für das Problem, aber das ist die einfachste Methode und vermutlich auch die wartungsfreundlichste im Vergleich zu anderen.

Da das Feld ParentID nur ein einfaches Zahlenfeld ist, kann man natürlich auch eine 0 eintragen. Aber wenn man ein Toplevel-Element 1 reserviert, dann kann man die Eingabe von <=0 per Gültigkeitsregel unterbinden.

Was nicht funktioniert, ist eine Löschweitergabe, da Access dazu ja rekursiv arbeiten müßte. Man kann die Löschweitergabe in der Beziehung sogar definieren, aber wenn man dann versucht, ein übergeordnetes Element zu löschen, bekommt man die Meldung, daß das nicht geht, weil die Tabelle gesperrt sei - das ist ja kein Wunder, denn der betreffende Tabellenbereich wird zum Löschen gesperrt, die gleiche Tabelle dann wieder angesprochen, um den untergeordneten Datensatz zu löschen, wenn der aber in der gleichen Page liegt, wird er u.U. mit gesperrt und das löst dann ja außerdem wieder die nächste Löschweitergabe aus usw.

Es funktioniert, wenn die Löschweitergabe eingeschaltet ist, wenn man den Baum von unten her löscht, aber das macht den Zweck der Löschweitergabe zunichte, daher sollte man darauf verzichten (das gleiche gilt wohl auch für die Aktualisierungsweitergabe).

Für hierarchische Darstellung ist ohnehin ein SQL Server besser geeignet, der kann auch rekursives SQL, damit kann man speziell so eine Struktur perfekt in einer einzigen Abfrage abklappern. Mit dem relativ primitiven Access SQL ist das leider nicht möglich.

Gruß

Christian
sk42
Im Profil kannst Du frei den Rang ändern


Verfasst am:
14. März 2012, 22:44
Rufname:

Re: AW: Hierarchie und Referentielle Integrität - Re: AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,
Bitsqueezer - 14. März 2012, 17:22 hat folgendes geschrieben:
Es ist eigentlich bei einer Selbstreferenzierung üblich, daß das/die Topelement(e) im Feld ParentID auf 0 gesetzt werden.

Die RI soll ja in erster Linie erzwingen, daß es in der Nachschlagetabelle bereits eine passende ID gibt,
Aber die gibt es ja nicht, wenn ich da "0" eintrage! Und somit geht dann auch referentielle Integrität nicht.
Die IDs des Primärschlüssels fängt ja mit "1" an (als Primärschlüssel verwende ich ausschließlich "AutoWert".
Zu "0" gibt es keinen Toplevel-Eintrag.

Zitat:
Auch das Eingeben ist kein Problem, sobald Du das erste Zeichen im Datensatz tippst, wird die ID (Autowert) schon erstellt und steht zur Verfügung,
Alternativ kannst Du aber einen Toplevel auch so markieren, daß die ID auf sich selbst zeigt, dann geht es auch mit der Eingabe wieder.
Ich gebe aber nicht direkt in der Tabelle ein, sondern über ein Formular. Um Inkonsistenzen durch Tippfehler zu verhindern und weil man mit der ID nix anfangen kann, gebe ich über ein Kombinationsfeld an, welches mir nicht die ProjektID, sondern das Projekt anzeigt (aber natürlich dann die ID einträgt) und das Kombifeld ist so eingestellt, daß ich nur Einträge aus der Liste wählen kann (und das soll auch so bleiben). Und damit funktioniert es dann nicht, da der neue Eintrag zu dem Zeitpunkt eben noch nicht vorhanden ist.

Zitat:
Wobei ich persönlich eher eine ID 1 für das Toplevel-Element reservieren würde,
Also komme ich um einen Dummy-Eintrag nicht drum herum? Das wäre ziemlich unschön, da ich in der Prrojekttabelle eine ganze Reihe von Pflichtfeldern habe, die ich bei einem Dummy-Eintrag ja nicht füllen könnte.

Zitat:
da man das ja im Formular einfach mit WHERE ausblenden kann, denn ansonsten müßtest Du bei jeder Rekursion immer prüfen, ob ParentID = ID ist, um das/ein Toplevelelement zu bestimmen.
Da die Hierarchie nur einstufig ist (d.h. ein Toplevel-Projekt kann Teilprojekte haben, aber ein Teilprojekt hat keine weiteren Unterprojekte), benötige ich zum Glück keine Rekursion. Die Abfragen sind also einfach.

Zitat:
@Kyron: Das Datenmodell ist völlig in Ordnung, eine Hierarchietabelle baut man i.d.R. immer mit einer Selbstreferenzierung auf,
Worauf beziehst du dich hier? Ich sehe hier nur deine Anwort.

Zitat:
Was nicht funktioniert, ist eine Löschweitergabe,
Die benötige ich auch nicht.
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
14. März 2012, 23:21
Rufname:

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,

richtig, wenn RI verwendet wird, geht DANN natürlich nicht mehr 0. Du kannst Dich nur für eins entscheiden.

Mit einem Kombinationsfeld habe ich es jetzt nicht probiert, aber auch dafür ließe sich sicher eine entsprechende Lösung finden.

Der Dummy-Eintrag wird nie sichtbar, entsprechend spielt es auch keine Rolle, was da drinsteht.

ABER: Wenn Du ohnehin nur eine einstufige Hierarchie hast, dann hatte Kyron (der seinen Artikel in der Zwischenzeit, während ich schrieb, wohl gelöschthat) wohl doch recht: In dem Fall ist das Datenmodell ganz einfach falsch. Denn wenn es keine Hierarchie gibt, ist eine Selbstreferenz nicht notwendig, dann kannst Du das alles mit einer ganz normalen 1:n-Beziehung erledigen, eine Tabelle Masterprojekt und eine Tabelle Unterprojekte - fertig. Das wird dann auch in den Formularen um einiges einfacher.

Gruß

Christian
sk42
Im Profil kannst Du frei den Rang ändern


Verfasst am:
15. März 2012, 00:25
Rufname:


Re: AW: Hierarchie und Referentielle Integrität - Re: AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,
Bitsqueezer - 14. März 2012, 22:21 hat folgendes geschrieben:
Mit einem Kombinationsfeld habe ich es jetzt nicht probiert, aber auch dafür ließe sich sicher eine entsprechende Lösung finden.
Dann werde ich mal eine entsprechende Frage im Formular-Unterforum stellen.

Zitat:
Der Dummy-Eintrag wird nie sichtbar, entsprechend spielt es auch keine Rolle, was da drinsteht.
Und wenn man bei den Abfragen mal vergißt, diesen Dummy auszublenden...
Zum einen werden Abfragen dadurch ja komplizierter und zum anderen kann ich dann nie die Tabelle als Datenherkunft nehmen, sondern muß immer eine Abfrage machen. Geht da nicht die Geschwindigkeit in die Knie, insb. beim Kriterium "<>"?

Zitat:
In dem Fall ist das Datenmodell ganz einfach falsch. Denn wenn es keine Hierarchie gibt, ist eine Selbstreferenz nicht notwendig, dann kannst Du das alles mit einer ganz normalen 1:n-Beziehung erledigen, eine Tabelle Masterprojekt und eine Tabelle Unterprojekte - fertig. Das wird dann auch in den Formularen um einiges einfacher.
Das wird für alle Auswertungen deutlich komplizierter, denn ich müßte dann ja aus den beiden Tabellen (die dann ja identische Felder hätten) zuvor immer eine UNION-Abfrage machen, denn bei weitem nicht jedes Toplevel-Projekt hat Teilprojekte. Der gravierenste Nachteil ist aber, daß UNION-Abfragen nicht editierbar sind.
Diese Probleme wollte ich eigentlich mit meinem Datenmodell (also eine 1:n-Beziehung zu sich selbst) vermeiden.
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
15. März 2012, 09:03
Rufname:

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,
Zitat:
kann ich dann nie die Tabelle als Datenherkunft nehmen
Der Ansatz ist schon falsch. Man nimmt GRUNDSÄTZLICH NIE eine Tabelle als Datenherkunft. Eine Abfrage (insbesondere eine gespeicherte Abfrage) optimiert das Tempo und kann auf exakt das begrenzt werden, was man benötigt - und genau so soll man es auch handhaben.

Das Ausklammern vergessen - auch das ist kein Problem, wenn man einfach eine Basisabfrage macht, die eben genau das macht und alles Weitere darauf basieren läßt. Aber auch ohne ist das kein Problem, denn wenn man es vergißt, dann muß man es halt nachtragen. Programmfehler muß man immer bereinigen.

Da die Teilprojekte ja immer auf einen Masterprojektdatensatz zeigen, ist die Lösung ganz einfach: Jedes Masterprojekt bekommt immer mindestens genau ein Teilprojekt. So kann die Masterprojekttabelle inhaltlich "dünn" gehalten werden, während alle Daten zu allen Projekten in der Teilprojekttabelle stehen. Der Basisdatensatz könnte beispielsweise durch ein Ja/Nein-Feld als solcher gekennzeichnet werden. Eine UNION-Abfrage ist dabei nicht notwendig.

Gruß

Christian
sk42
Im Profil kannst Du frei den Rang ändern


Verfasst am:
15. März 2012, 10:25
Rufname:

Re: AW: Hierarchie und Referentielle Integrität - Re: AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,
Bitsqueezer - 15. März 2012, 08:03 hat folgendes geschrieben:
Der Ansatz ist schon falsch. Man nimmt GRUNDSÄTZLICH NIE eine Tabelle als Datenherkunft.
Wieso das denn? Shock Auch nicht für die ganzen Hilfstabellen, die ja immer nur wenige Datensätze enthalten und man da immer alle Datensätze in den Kombinationsfeldern benötigt?
Ich habe immer nur dann Abgragen als Datenherkunft genommen, wenn es gar nicht anders ging, d.h. ich unbedingt nur einen ganz bestimmten Teil der Datensätze benötigte.

Zitat:
Eine Abfrage (insbesondere eine gespeicherte Abfrage) optimiert das Tempo und kann auf exakt das begrenzt werden, was man benötigt
Performanter, wenn man eine Abfrage zwischenschaltet? Die muß doch abgearbeitet werden, benötigt also zusätzliche Zeit?
Begrenzen der DS ist hier nur in wenigen Fällen nötig bzw. sinnvoll, und dafür nehme ich dann auch eine Abfrage. Aber meistens benötige ich die komplette Liste (die Anzahl der DS bewegt sich noch im dreistelligen Bereich) oder muß schnell zwischen verschiedenen Auswahlen und Gesamtliste umschalten können. Das mache ich dann über SuchKombifelder bzw. SuchListenfelder im Formular, denn ich kann ja nicht während das Formular geöffnet ist, die Datenherkunft des Formulars ändern (z.B. von Auswahlabfrage auf Gesamttabelle).

Und wie ist es mit der Performance, wenn ich von dieser Grundabfrage weitere Abfragen machen muß? Ich habe immer versucht, die Schachtelungstiefe (also Abfrage von einer Abfrage) so gering wie möglich zu halten, weil ansonsten ja nicht nur eine, sondern mehrere Abfragen abgearbeitet werden müßten, und sowas kostet ja Zeit. Confused

Zitat:
Programmfehler muß man immer bereinigen.
Stimmt, und das nicht zu knapp. Wenn da diese elende fehleranfällige Tipperei nicht wäre. Rolling Eyes Die Abfragen mache ich daher grundsätzlich mit dem Assistenten.

Zitat:
Jedes Masterprojekt bekommt immer mindestens genau ein Teilprojekt.
Question Aber dann habe ich doch jede Menge überflüssiger Dummy-Datensätze? Question

Zitat:
So kann die Masterprojekttabelle inhaltlich "dünn" gehalten werden, während alle Daten zu allen Projekten in der Teilprojekttabelle stehen. Der Basisdatensatz könnte beispielsweise durch ein Ja/Nein-Feld als solcher gekennzeichnet werden.
Und was mache ich dann mit den Detaildatensätzen derjenigen Masterprojekte, die echte Teilprojekte enthalten? Wo sollen deren Detaildaten dann stehen?
Was daran einfacher sein soll verstehe ich noch nicht oder ich verstehe nicht genau, was du damit meinst. Question Ich hatte mir damals als ich das Datenmodell gemacht hatte, ja auch überlegt gehabt, ob ich da zwei Tabellen machen kann, aber die Datenmischung gibt das nicht her. Es gibt da zu viele Fallunterscheidungen und Überschneidungen, so daß es mir einzig sinnvoll erschien, daraus eine einzige Tabelle zu machen (dazu mit etlichen 1:n verknüpften Detailtabellen) mit dem Feld ParentID in Beziehung zu sich selbst (also zu dem Primärschlüssel der gleichen Tabelle).
sk42 am 15. März 2012 um 09:40 hat folgendes geschrieben:
Hallo,

Bei einer Hierarchie (Hauptprojekt und Teilprojekt) habe ich ja den PK (Primärschlüssel) und den FK (Fremdschlüssel) in der gleichen Tabelle mit Beziehung zu sich selbst.
Es soll referentielle Integrität eingestellt sein, d.h. im FK kann nur ein Wert drin stehen, der als PK bereits existiert.

Wenn ich nun aber einen neuen Datensatz anlege, dann existiert dieser neue Wert aber im Kombifeld noch nicht. Gibt es eine Möglichkeit, den PK dieses neuen, noch im Bearbeitungsmodus befindlichen Datensatzes schon zu diesem Zeitpunkt im Kombifeld verfügbar zu haben, so daß dieser ausgewählt werden kann?

PS: Hintergrund meiner Frage ist dieser Thread

Themen zusammengeführt. KlausMz
KlausMz
Moderator Access


Verfasst am:
15. März 2012, 11:06
Rufname:
Wohnort: Irgendwo in der Pfalz

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,
ich habe diesen Beitrag gelöscht, der nachfolgende Beitrag von Bitsqueezer trifft es deutlich besser. Laughing

_________________
Gruß
Klaus . . . . . Feedback wäre wünschenswert.
Ich möchte bitte keine unaufgeforderten PN. Fragen bitte im Forum.


Zuletzt bearbeitet von KlausMz am 15. März 2012, 11:28, insgesamt 2-mal bearbeitet
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
15. März 2012, 11:08
Rufname:

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,

also zu den Performance-Tips liest Du am besten mal hier, sonst muß ich das alles wiederholen:

Verbessern der Leistung einer Access-Datenbank

Insbesondere bei den "kleinen Nachschlagetabellen" nimmt man immer eine Abfrage, alleine schon deswegen, weil diese oft nur aus einer ID und einem Textfeld bestehen. Da man hier i.d.R. bei der Anzeige in der Kombobox auch eine Sortierung benötigt, kommst Du um eine Abfrage mit ORDER BY nicht drumherum. Darüber hinaus enthalten Hilfstabellen auch oft zusätzliche Spalten, die an anderer Stelle im Programm benötigt werden, aber nicht in einer Kombobox, so daß diese Spalten schon wieder ausgeklammert werden können.

Dazu kommt, daß der Gedanke "ich nehme eine Tabelle als Datenherkunft" schon falsch ist, denn man KANN in einer Datenbank gar keine Tabelle als Datenherkunft nehmen. Die einzige Möglichkeit, an die Daten einer Tabelle heranzukommen, besteht in einer SELECT-Abfrage. Und nur, weil Du keine eigene erstellst, bedeutet das Einstellen eines Tabellennamens nicht, daß keine Abfrage erstellt wird - das macht Access im Hintergrund. Die Abfrage sieht dann so aus: "SELECT * FROM Tabelle". Nur daß es sich dabei dann um eine unsortierte (oder PK-sortierte) dynamische SQL-Abfrage handelt, die nicht vorkompiliert ist und entsprechend auch nicht optimiert. Man erstellt also eine Abfrage UND speichert diese immer, also nicht etwa ein SELECT-Befehl direkt in der Datenherkunft - das ist dann genauso schlecht.
Nebenbei hat eine gespeicherte Abfrage bei geschickter Namensgebung den Vorteil, daß man sie immer wieder verwenden kann, in allen Formularen. Ich speichere Komboboxabfragen z.B. immer mit dem Prefix "qryCTL", so kann ich beim Erstellen einer gleichen Kombobox in einem neuen Formular einfach die Abfrage wieder auswählen und habe überall das gleiche Format - noch besser, wenn ich daran mal was ändern muß (zum Beispiel die Sortierung), dann brauche ich nur diese eine Abfrage zu ändern und weiß, daß es in allen Formularen nun so aussieht. Bei Tabellenherkunft oder SELECT-Befehl in der Herkunft muß ich die Änderung in jedem Formular machen (bzw. bei Tabellenherkunft kann ich nicht einmal etwas ändern).
Aus dem gleichen Grund gehört in ein SELECT grundsätzlich kein "*" für die Spaltenauswahl, immer eine genaue Feldliste.

Wenn die Grundabfrage eine gespeicherte Abfrage ist, wird die Abfrage ja bereits optimiert, aber der Weg war auch nur der Vorschlag, wenn Du das Ausklammern von DS 1 auf sichere Weise nicht vergessen möchtest. Ich würde es auch in jeder Abfrage einzeln machen. Der Performance-Verlust ist allerdings in diesem Fall nicht sehr groß, würde ich mal sagen.

Die Abfragen baue ich auch meistens zunächst mit dem Abfrageeditor, weil man da die Spalten schneller zusammenklicken kann und die JOINs manuell in dem bekloppten Geklammere von Access SQL zu schreiben, ist beinahe unmöglich. Zu manuellem SQL greife ich nur, wenn es schneller geht, es zu schreiben als mit der Maus zu schubsen oder wenn Spezialitäten wie Unterabfragen hinzukommen, die man mit dem Editor nur schwierig eingeben kann.

Datenstruktur: Nein, keine Dummy-Datensätze, denn jedes Projekt, egal ob Teil- oder Masterprojekt, ist ja ein Projekt, es enthält also z.B. eine Projektnummer, einen Namen, Startdatum usw. Diese Daten können, egal ob Teil- oder Masterprojekt, alle in die Teilprojekttabelle. Die Mastertabelle braucht dann nur noch wenige zusätzliche Basisdaten zu enthalten, die für alle Teilprojekte gelten, beispielsweise ein m:n-Link zu den projektbeteiligten Usern. Aber man kann ja auch ganz andere Modelle entwerfen, das war nur ein Beispiel. Genau kann man das ohnehin nur sagen, wenn man die genauen Umstände kennt und das, was man letzten Endes dabei herausholen will. Ich würde mir jedenfalls eine Selbstreferenz gut überlegen, denn außer bei komplexen Bäumen lohnt sich diese Form nicht, weil sie viel schwieriger zu handhaben ist als eine einfache Relation, die ruhig auch ein wenig denormalisiert sein darf.

Gruß

Christian
KlausMz
Moderator Access


Verfasst am:
15. März 2012, 11:14
Rufname:
Wohnort: Irgendwo in der Pfalz

AW: Hierarchie und KombiFeld: neuer DS schon auswählbar mach - AW: Hierarchie und KombiFeld: neuer DS schon auswählbar mach

Nach oben
       Version: Office 2003

Hallo,
ich würde vorschlagen, Du bleibst auch mal in diesem Thread, zumal Deine neuer Beitrag ja mit diesem im Zusammenhang steht und Du selbst darauf verweist.

Ich habe daher beide Themen zusammengeführt. Die Beiträge sind chronologisch eingefügt.

Siehe neuer Beitrag von sk42 vom 15. März 2012, 09:40

_________________
Gruß
Klaus . . . . . Feedback wäre wünschenswert.
Ich möchte bitte keine unaufgeforderten PN. Fragen bitte im Forum.
sk42
Im Profil kannst Du frei den Rang ändern


Verfasst am:
16. März 2012, 12:04
Rufname:

Re: AW: Hierarchie und Referentielle Integrität - Re: AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,

Erstmal danke für den Link! Das ist ja eine Menge interessanter Lesestoff (ganz durch bin ich damit aber noch nicht), wenn auch teilweise äußerst schwer zu lesen (hellgraue Schrift auf weißem Hintergrund, grrrr).

Bitsqueezer - 15. März 2012, 10:08 hat folgendes geschrieben:
Insbesondere bei den "kleinen Nachschlagetabellen" nimmt man immer eine Abfrage, alleine schon deswegen, weil diese oft nur aus einer ID und einem Textfeld bestehen. Da man hier i.d.R. bei der Anzeige in der Kombobox auch eine Sortierung benötigt, kommst Du um eine Abfrage mit ORDER BY nicht drumherum.
Aber diese "Abfrage" ist doch innerhalb der Kombobox gespeichert, d.h. dies zähle ich nicht als "Abfrage", da diese ja nicht im Datenbankfenster erscheint. Dies ist Bestandteil der Kombobox.

Zitat:
Dazu kommt, daß der Gedanke "ich nehme eine Tabelle als Datenherkunft" schon falsch ist, denn man KANN in einer Datenbank gar keine Tabelle als Datenherkunft nehmen. Die einzige Möglichkeit, an die Daten einer Tabelle heranzukommen, besteht in einer SELECT-Abfrage. Und nur, weil Du keine eigene erstellst, bedeutet das Einstellen eines Tabellennamens nicht, daß keine Abfrage erstellt wird - das macht Access im Hintergrund.
Mit "Abfrage" meine ich natürlich nur das, was im Datenbankfenster als Abfrageobjekt erscheint. Und bei den Formularen wählt man bei der Eigenschaft "Record Source" ja die Tabelle aus. Wie Access das nun im Hintergrund umsetzt ist für den Anwender doch irrelevant. Wink

Zitat:
Nebenbei hat eine gespeicherte Abfrage bei geschickter Namensgebung den Vorteil, daß man sie immer wieder verwenden kann, in allen Formularen.
Hat aber auch den gravierenden Nachteil, daß zu einen die Anzahl der Abfragen im Datenbankfenster expoldiert (man hat ja sowieso schon jede Menge Abfragen dort drin stehen, die sich teilweise nur in Details unterscheiden) und zum anderen man dann gar nicht mehr weiß, welche Abfrage man für welche Kombobox in welchem Formular verwendet hat. Da verliere ich ja dann vollends die Übersicht. Rolling Eyes

Zitat:
Bei Tabellenherkunft oder SELECT-Befehl in der Herkunft muß ich die Änderung in jedem Formular machen
Und gerade das empfinde ich als großen Vorteil bzgl. der Übersichtlichkeit. Da weiß man genau was wozu gehört. Und daß man Abfragen mit exakt gleichen Kriterien in mehreren Formularen verwendet, kommt bei mir nicht gar so häufig vor, irgendwo muß dann doch ein Detail anders sein.

Zitat:
Aus dem gleichen Grund gehört in ein SELECT grundsätzlich kein "*" für die Spaltenauswahl, immer eine genaue Feldliste.
Ja, das mache ich auch so. Das Sternchen verwende ich nie.

Zitat:
Wenn die Grundabfrage eine gespeicherte Abfrage ist, wird die Abfrage ja bereits optimiert,
Auch bei den direkt in den Kombinationsfeldern gespeicherten Abfragen?

Zitat:
Datenstruktur: Genau kann man das ohnehin nur sagen, wenn man die genauen Umstände kennt und das, was man letzten Endes dabei herausholen will. Ich würde mir jedenfalls eine Selbstreferenz gut überlegen, denn außer bei komplexen Bäumen lohnt sich diese Form nicht, weil sie viel schwieriger zu handhaben ist als eine einfache Relation, die ruhig auch ein wenig denormalisiert sein darf.
Ich werde die Projektdaten noch mal genauer unter die Lupe nehmen und mir anhand dessen dann unter Berücksichtigung eurer Infos nochmal genau das Datenmodell überlegen und testen, ob das dann mit den Formularen benutzerfreundlich klappt bzw. ob die Auslagerung der Masterprojekte überhaupt möglich ist aufgrund der zu erfassenden Daten und eventueller Überschneidungen.

Danke!
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
16. März 2012, 14:02
Rufname:

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo,
Zitat:
Aber diese "Abfrage" ist doch innerhalb der Kombobox gespeichert, d.h. dies zähle ich nicht als "Abfrage", da diese ja nicht im Datenbankfenster erscheint. Dies ist Bestandteil der Kombobox.
So ist es, sowohl bei Einstellung eines Tabellennamens als auch bei Eingabe eines kompletten SELECT-Befehls wird KEINE gespeicherte Abfrage erstellt, sondern zum Zeitpunkt, wenn das Formular geöffnet wird, ein dynamischer SQL-Befehl ausgeführt, das kostet Zeit. Denn im Fall eines SELECT-Befehls muß dieser erst geparst werden, Ablaufpläne erstellt werden usw., im Fall eines Tabellennamens wird ein simpler SELECT * FROM Tabelle-Befehl erstellt und danach erfolgt das gleiche Prozedere.
Im Fall einer gespeicherten Abfrage dagegen wird der SQL-Befehl bereits beim Speichern geparst, es werden Ablaufpläne erstellt und das Ergebnis ist, daß diese Vorgänge beim Ausführen der gespeicherten Abfrage gespart werden. Beim SQL Server werden die Ablaufpläne sogar regelmäßig anhand der Daten weiter optimiert, Access geht da nicht ganz so weit, aber auch hier findet bis zu einer bestimmten Grenze eine Optimierung der Abfrage statt. Das ist der Grund, warum MS in der oben gelinkten Seite auch selbst empfiehlt, immer eine gespeicherte Abfrage zu erstellen und zu verwenden, und natürlich nicht nur bei Komboboxen, sondern bei ALLEM, was man mit SQL macht. Das heißt: Formulare, Listboxen, Komboboxen, aber auch QueryDefs statt dynamisch zusammengesetzten SQL-Strings, wo immer es geht. Und, was man auch oft sieht, auch nicht eine QueryDef speichern und dann diese später im Code aus der Liste zu holen, den SQL-Parameter (also den SQL-Text) in VBA anzupassen und dann auszuführen, das ist genau der gleiche Unsinn, denn damit gehen die Optimierungsvorteile zum Teufel. Wenn man aus irgendeinem Grund unbedingt einen dynamischen SQL-Befehl benötigt, dann erstellt man eine temporäre QueryDef (die erscheint nicht in der Liste der Abfragen) und stellt dann den SQL-Parameter auf den Befehl, aber diese Vorgehensweise macht nur Sinn, wenn man Parameter im SQL-Befehl verwenden möchte, denn mit der QueryDef kann man dann die Parameter mit der Parameters-Collection typgenau setzen, das verhindert z.B. SQL Injection (wenn Dir das kein Begriff ist, einfach mal nach googlen, der Begriff und der Vermeidung dessen, was dahintersteht, sollte jeder Datenbankprogrammierer kennen).

Zitat:
Mit "Abfrage" meine ich natürlich nur das, was im Datenbankfenster als Abfrageobjekt erscheint
Naja...was Du MEINST, spielt dabei eigentlich keine Rolle. Das, was Du im Datenbankfenster siehst, sind nur die gespeicherten Abfragen, aber damit ist nicht alles Andere keine Abfrage.

Zitat:
Und bei den Formularen wählt man bei der Eigenschaft "Record Source" ja die Tabelle aus. Wie Access das nun im Hintergrund umsetzt ist für den Anwender doch irrelevant.
Definitiv falsch. Insbesondere bei Formularen verwendet man IMMER eine gespeicherte Abfrage, NIEMALS den Tabellennamen. Die Gründe sind die gleichen wie bei der "kleinen" Kombobox (/Listbox...). Nur daß es bei Formularen noch viel wichtiger ist, exakt zu definieren, was man benötigt, da die Datenmenge hier i.d.R. viel größer ist als bei Komboboxen etc. (mal von Endlosformularen gesprochen).

Für den Anwender ist es ebensowenig irrelevant, auch wenn er die Einstellung nie zu sehen bekommt. Dafür spürt er den Unterschied in der Performance.

Zitat:
Hat aber auch den gravierenden Nachteil, daß zu einen die Anzahl der Abfragen im Datenbankfenster expoldiert
Yep, das ist wohl so. Ab A2007 kannst Du im Navigationsfenster eigene Gruppen definieren und die Abfragen so entsprechend zu den Objekten hinzufügen, wo sie benötigt werden (was ich persönlich "unordentlicher" empfinde und nie verwende). Aber die Übersicht geht nicht verloren, wenn die Benennung ordentlich ist. Wenn man natürlich nur "Abfrage1" und "Abfrage2" usw. in der Liste stehen hat, dann ist die Übersicht schnell weg.
Eine Benennung sollte entsprechend sortiert erfolgen, dann gibt es Null Probleme mit der Übersicht. Da Access alles alphabetisch sortiert, ist die Reihenfolge der Namensgebung schon klar. Beispiel:

Alle Controls (Komboboxen, Listboxen usw.), die eine RowSource verwenden können, bekommen als Prefix "qryCTL". Als nächstes folgt der Name der Tabelle, die diese Kombobox anzeigen soll und ggf. danach der Zweck. Wenn also ein Projekt aus einer Projektliste ausgewählt werden soll, dann heißt die Query "qryCTLProjekte". I.d.R. wird man ein Projekt, da Nachschlagetabelle, dem User immer auf die gleiche Weise anbieten, also kann jede Kombobox nun diese Datenquelle immer verwenden. Wenn man es sich besonders einfach machen will, erstellt man ein Dummyformular, in das man die Kombobox mit allen Spalteneinstellungen (Breite, Anzahl usw.) einmal genau definiert, in jedem Formular, in dem dann ein Projekt ausgewählt werden soll, öffnet man dann einfach das Dummyformular und kopiert sich die Kombobox da raus und in das neue Formular rein. Man erspart sich die Arbeit, die richtige Query herauszusuchen, aber auch, alle Spalteneinstellungen wieder erneut vornehmen zu müssen. Gibt es eine Abweichung im Formular, erstellt man aus der Abfrage einfach eine neue. Wenn also die Abfrage "qryCTLProjekte" alle Projekte listet (damit sollte man immer anfangen), dann braucht man in dem neuen Formular nun nur noch auf "[...]" neben dem Abfragenamen zu klicken, landet im Queryeditor von "qryCTLProjekte" und klickt "Speichern Unter" und speichert die Query nun unter "qryCTLProjekte_Abgeschlossen". Dann kann man den Filter für nur abgeschlossene Projekte definieren, hat sich aber die Arbeit gespart, auch alles Andere wieder neu einstellen zu müssen (welche Felder, welche Reihenfolge, welche Sortierung, Ausschluß des Dummy-Projektes usw.). Nun habe ich zwei Queries in der Liste, aber durch die Sortierung stehen diese genau untereinander, so daß später alle Queries (qry), die z.B. in einer Kombobox stehen (CTL), eine Projektliste anzeigen sollen (Projekte) mit ihren jeweiligen Zwecken untereinander stehen, leicht wiederzufinden, leicht zu warten.
Das gleiche mit Formularen: "qryFRMProjekte_Liste" für das Endlosfenster mit allen Projekten. "qryFRMProjekte_NachID" für eine Parameterquery, die eine ID entgegennimmt und dann nur dieses Projekt anzeigt. "qryFRMProjekte_SF_Teilprojekte" für ein Unterformular (SF) Teilprojekte, das im Hauptformular Projekte liegt und die passenden Teilprojekte für das jeweils angezeigte Hauptprojekt anzeigt.
Hält man sich strikt an so eine strukturierte Namensgebung, ist es ein Kinderspiel, auch durch kilometerlange Querylisten durchzublicken. Und ja: Das ist normale Arbeit für einen Datenbankentwickler, wenn Du irgendwann mal an einen Datenbankserver gerätst, wirst Du sehen, daß Du dort mit noch viel längeren Listen zurechtkommen mußt - auch hier gilt: Ordentliche Namensgebung nach einem einheitlichen Standard (den man sich selbst setzen, aber auch daran halten sollte) vermeidet Chaos beim Überblick.
Durch die Namensgebung wie im Beispiel braucht man in der Dropdownliste der RowSource in der Kombobox noch nicht einmal stundenlang zu scrollen, denn die Namensgebung hilft, den Namen nicht erinnern zu müssen, sondern einfach einzutippen. Es ist eine Abfrage, also "qry". Es ist eine Kombobox, also "CTL", es ist eine Projektliste, also "Proj" - und schon erscheinen im Dropdown schön untereinander alle Queries, die damit zu tun haben und ich kann mir die richtige heraussuchen. Das ist doch wirklich nicht schwer.

Wenn man wissen will, wo man etwas verwendet hat, verwendet man Tools, da empfehle ich zum Beispiel die V-Tools

Die haben einen Punkt "Total deep search", damit kannst Du jedes Objekt überall wiederfinden.

Du siehst, es gibt keinen Grund, eine Tabelle oder gar dynamisches SQL als Record- oder RowSource einzustellen, wo immer eine gespeicherte Abfrage möglich ist, sollte sie auch unbedingt verwendet werden. Der Grund, eine Tabelle auszuwählen, ist meist Faulheit, mehr nicht. Das rächt sich dann, wenn man z.B. eine Tabelle/Abfrage öffnet, die keine Sortierung verwendet und die Datensätze plötzlich bei jedem Aktualisieren in einer zufälligen Reihenfolge erscheinen, oder die Performance grottenschlecht ist, weil man von den 50 Feldern im Formular nur 3 anzeigt, aber alle 50 im Hintergrund mitgeladen werden...usw.

Gruß

Christian
JMalberg
Es wird so langsam sinnig ...


Verfasst am:
16. März 2012, 14:07
Rufname:
Wohnort: Saarbrücken

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Rick Fishers "Find & Replace" kann ich auch empfehlen. Zwar sperrig aber umfassend.
_________________
Gruß
Jürgen

Der Unterschied zwischen Theorie und Praxis ist in der Praxis größer als in der Theorie!
Gast



Verfasst am:
16. März 2012, 14:51
Rufname:

AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Zitat:
zum Zeitpunkt, wenn das Formular geöffnet wird, ein dynamischer SQL-Befehl ausgeführt, das kostet Zeit ...
Da würde ich widersprechen. Michael Zimmermann spricht in seinem Script Performance in Abfragen (Seite 31) davon, dass für Datenherkünfte von Formularen, Kombi- und Listenfeldern intern Systemabfragen erstellt werden, die der Compilation einer gespeicherten Abfrage vergleichbar und somit zeitlich unkritisch sind.
Zitat:
Im Fall einer gespeicherten Abfrage dagegen wird der SQL-Befehl bereits beim Speichern geparst, es werden Ablaufpläne erstellt und das Ergebnis ist, daß diese Vorgänge beim Ausführen der gespeicherten Abfrage gespart werden.
Erstellung Ablaufplan und Compilation erfolgen erst mit der ersten Ausführung der Abfrage, nicht bei Speicherung. Daher hat eine dynamisch geänderte gespeicherte Abfrage auch keinen Effekt gegenüber einer puren SQL-Anweisung.

Den Effekt der höheren Ausführungsgeschwindigkeit einer gespeicherten Abfrage gegenüber einer puren SQL-Anweisung sollte man aber auch nicht überbewerten. Michael Zimmermann spricht zwar von bis zu 400 % (annähernde Zahlen habe ich selber auch schon ermittelt), allerdings erfolgt das unter Laborbedingungen bezogen auf diesen Ansatzpunkt.
Dass sich allein durch die Speicherung einer Abfrage als Objekt die Ausführungsgeschwindigkeit verdoppelt oder gar vervierfacht, wird wohl kaum jemand in seiner Praxis festgestellt haben bzw. feststellen können. Immerhin muss bei einer Abfrage nach der Compilation die eigentliche Arbeit ausgeführt werden, und während für die Compilation einer (hier im Forum üblichen) Abfrage eine Zeit im untersten Millisekundenbereich benötigt wird, spielen bei der eigentlichen Abfrage andere Faktoren eine erheblich größere Rolle: Abfragedesign, Indexnutzung, Datenmengen, Netzwerktraffic. Hier geht es dann nicht um Millisekunden bis Sekunden, sondern schnell einmal um Sekunden oder Stunden.
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
16. März 2012, 16:23
Rufname:


AW: Hierarchie und Referentielle Integrität - AW: Hierarchie und Referentielle Integrität

Nach oben
       Version: Office 2003

Hallo Gast,

es ist sicher richtig, daß Access die Abfragen, die man in Komboboxen etc. hinterlegt, irgendwo in den Systemtabellen speichert (speichern muß, irgendwie muß es sich die Einstellung ja "merken"). Allerdings gehe ich davon aus, daß der Hersteller Microsoft sein Produkt am besten kennt und in dem oben aufgeführten Link (der auf alle Fälle bis A2003 gültig ist) steht unter dem Punkt "Verbesserung der Leistung von Abfragen":

Zitat:
Speichern Sie die SQL-Anweisung als Abfrage, wenn für die Datenherkunft-Eigenschaft eines Formulars oder eines Berichts eine SQL-Anweisung festgelegt wurde, und legen Sie dann die Datenherkunft-Eigenschaft auf den Namen der Abfrage fest.
Wozu sollte man die Empfehlung geben, wenn es dazu keinen Grund gäbe? Auch wenn der hier leider nicht genannt wird. Ich halte es also durchaus für möglich, daß es einen Unterschied gibt zwischen regulär und "heimlich" gespeicherten Abfragen.

Der Ausführungsplan wird allerdings bereits beim Kompilieren der Abfrage erstellt und gespeichert - darin besteht ja gerade ein wesentlicher Vorteil der gespeicherten Abfrage gegenüber dynamischem SQL. Es gibt auch einen "ShowPlan"-Registrykey, den man einstellen kann, damit kann man sich diesen sogar anzeigen lassen (sollte man aber nachher wieder deaktivieren, kostet erheblich Performance).
Da ein Ausführungsplan jedoch bei unterschiedlicher Anzahl Datensätze unterschiedlich effizient sein kann, wird nach bestimmten Algorithmen der Ausführungsplan auch neu erstellt, die Abfrage also recompiliert. Wenn eine Tabelle nicht gerade jeden Tag um xtausend Datensätze in der Menge schwankt, passiert das aber wohl eher selten.

Ich bin aber Deiner Meinung, wenn es um den tatsächlichen Performance-Gewinn geht, sowohl das Parsen des SQL-Befehls als auch die Erstellung eines Ablaufplans benötigen nicht gerade sehr lange, der Performance-Gewinn ist also nicht riesig. Dennoch bin ich der Meinung, daß man jede Möglichkeit, die Performance zu verbessern, nutzen sollte - und eine gespeicherte Abfrage (bei sinnvoller Benennung) erhöht die Übersichtlichkeit für meine Begriffe und gewöhnt frühzeitig an die richtige Verwendung, wenn man irgendwann mal mit einem Datenbankserver zu tun bekommt. Da hier Tabellen mit Statistiken angelegt werden, die die Ausführungspläne verwenden (was aus Platzgründen und der Tatsache, daß eine Access-Backenddatei nur passiv ist, in Access so nicht möglich/begrenzt ist), ist eine gespeicherte Abfrage im Regelfall erheblich schneller als ein dynamischer SQL Befehl.

In jedem Fall ist natürlich klar, daß die von Dir genannten Punkte wie Indexnutzung usw. den bedeutendsten Teil der Performance ausmachen. Genau deswegen sollte man Ausführungspläne auch mal genau studieren, weil sie einem viele Hinweise geben, wo die Abfrage verbesserungswürdig ist. Bei SQL Server ist das einfach, übersichtlich und informativ, bei Access hindert alleine die Notwendigkeit eines Registry-Eintrags und der effektive Informationsgehalt der Logs, die dabei herauskommen, daran, den Ablaufplan hier effektiv zu nutzen. Access ist halt für den "einfachen User" konzipiert und der soll sowas wie Ablaufpläne gar nicht erst kennen/zu sehen bekommen....

Man müßte wohl mal (realistische) Messungen vornehmen, inwieweit die Aussage von Microsoft heute noch Gültigkeit hat oder ob der Text nur ein Relikt aus einer alten Access-Version ist. So oder so - gleich richtig angewöhnt, ist immer besser.

Gruß

Christian
Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind
GMT + 1 Stunde

Gehe zu Seite 1, 2, 3  Weiter
Diese Seite Freunden empfehlen

Seite 1 von 3
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen

Verwandte Themen
Forum / Themen   Antworten   Autor   Aufrufe   Letzter Beitrag 
Keine neuen Beiträge Access Tabellen & Abfragen: Richtig zählen ohne referentielle Integrität 18 Musicfreak666 326 21. März 2014, 12:21
Musicfreak666 Richtig zählen ohne referentielle Integrität
Keine neuen Beiträge Access Tabellen & Abfragen: Beziehungen ohne referentielle Integrität 5 takayser 399 16. März 2012, 20:32
Gast Beziehungen ohne referentielle Integrität
Keine neuen Beiträge Access Tabellen & Abfragen: Referentielle Integrität - Grundsätzliches 1 JMalberg 512 20. Dez 2011, 18:39
Gast Referentielle Integrität - Grundsätzliches
Keine neuen Beiträge Access Tabellen & Abfragen: Daten in Access auf Referentielle Integrität prüfen 5 Maddin26 622 27. Nov 2011, 14:10
Sonneschein Daten in Access auf Referentielle Integrität prüfen
Keine neuen Beiträge Access Tabellen & Abfragen: referentielle Integrität wiederherstellen 1 froggie 272 30. Nov 2010, 14:51
Gast referentielle Integrität wiederherstellen
Keine neuen Beiträge Access Tabellen & Abfragen: Beziehungen mit referentieller Integrität nicht anwendbar 1 GM-2010 1003 15. Jul 2010, 13:35
AS55 Beziehungen mit referentieller Integrität nicht anwendbar
Keine neuen Beiträge Access Hilfe: Referentielle Integrität 3 krefi 1098 21. Mai 2010, 14:19
krefi Referentielle Integrität
Keine neuen Beiträge Access Tabellen & Abfragen: Hierarchie Struktur in Access 8 ronster 3369 13. Jul 2009, 07:58
DBKlempner Hierarchie Struktur in Access
Keine neuen Beiträge Access Tabellen & Abfragen: Mehrfachverknüpfung unter Beibehaltung referenz. Integrität 6 Marco74 1182 31. Okt 2008, 14:37
Marco74 Mehrfachverknüpfung unter Beibehaltung referenz. Integrität
Keine neuen Beiträge Access Tabellen & Abfragen: problem referentielle integritaet 6 AbsoluterBeginner 484 24. Dez 2007, 13:49
Zed2k problem referentielle integritaet
Keine neuen Beiträge Access Programmierung / VBA: Erstellen von Beziehungen mit referentieller Integrität VBA 5 bb2k 5806 24. Okt 2007, 18:06
rita2008 Erstellen von Beziehungen mit referentieller Integrität VBA
Keine neuen Beiträge Access Tabellen & Abfragen: Verstoß gegen referenzielle Integrität 1 Gast 904 09. Okt 2007, 22:17
john795 Verstoß gegen referenzielle Integrität
 

----> Diese Seite Freunden empfehlen <------ Impressum - Besuchen Sie auch: Microsoft-Excel Diagramme