Laden...

Daten- / Tabellenorganisation

Erstellt von Darokh vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.941 Views
D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren
Daten- / Tabellenorganisation

verwendetes Datenbanksystem: Access DB

Ich arbeite derzeitig an einem Programm für eine psychologische Praxis in der ich arbeite und versuche gerade auf den Schirm zu bekommen, wie ich die Tabellen anlegen soll. Die wichtigesten Tabellen wollte ich gerne mal hier posten und eure Meinung dazu hören, da ich mich dort an einigen Stellen im Kreis drehe und mir nicht sicher bin, ob ich das richtig organisiere...
Der Übersicht halber habe ich nun auch nicht alle Infos, die in die Tabellen sollen, reingepackt, sondern nur die wichtigsten.

Gutachten1.GutachtenID 1.GutacherID 1.StatusID 1.PatientenID 1.verschiedene Testergebnisse

Der Status kann mehrer, hierarchisch aufsteigende Werte annehmen -- von z.B.
"Termin vergeben" --> "Testdaten erhoben" --> "Gutachten erstellt" ---> "Rechnung bezahlt"

Nun stellt sich für mich hier die Frage, ob dieser Status in das Gutachten gehört, oder jedes Gutachten in eine Art "Abwicklungstabelle" gehört, in dem steht, welches Gutachten (oder später auch Sprechstunde, Testung oder ähnliches) welchen Status derzeitig besitzt. Schließlich entspricht es einem Vorgang, der nach und nach abgewickelt wird. Zudem könnten Meetings, Sprechstunden mit Patienten oder ähnliches auch einen Status besitzen. An diesem Punkt explodiert nun leider mein Kopf. Da es natürlich jeweils abhängig davon verschiedene Status gibt.

Exemplarisch noch für die Sprechstunde:1.SprechstundeID 1.GutachterID 1.Notiz 1.(StatusID)

Von diesen Kategorien, (Gutachten, Sprechstunde oder z.B. Meeting) wird es noch mehr geben, aber ist derzeitig noch nicht ganz absehbar.

Zudem soll ein Terminkalender integriert werden, den hatte ich mir wie folgt überlegt:

Terminkalender1.TerminID 1.KategorieID (ist es ein Gutachten? eine Sprechstunde? Meeting?) 1.....ID (hier sollen GutachtenID, SprechstundenID, etc rein--wie auch immer man das nennen soll) 1.Datum 1.Zeit

Hier hätte ich natürlich das Problem, dass ich bei einer Suche im Terminkalender eine GutachtenID nicht von einer SprechstundenID unterscheiden kann, sofern ich nicht die Kategorie hinzunehme. Ist das ein Problem?

Eure Meinung würde mich da sehr interessieren.
LG,
Darokh

2.223 Beiträge seit 2005
vor 14 Jahren

Hallo Darokh,

auf den ersten Blick sieht das ganze doch recht in Ordnung aus

bis auf Gutachten Punkt 5.

die sollte man doch auch, in eine Extra Tabelle auslagen (können ja mehrer sein).

und halt entweder, über eine Mapping Tabelle die Relationen herstellen oder falls es sich ja nur um eine 1:n Verbindung handelt, mit einem FK zur Gutachten Tabelle.

die Status ID würde so wie ich das sehe definitiv in das Gutachten reingehören.

falls du im nachhinein zb nachvollziehen musst, welches Gutachten welchen Status zu welchem Zeitpunkt hatte, könnte man zusätzlich eine art History Tabelle hinzunehmen.
(Jede Status Änderung mit GutachenId, Datum, Uhrzeit und UserId, StatusId, würde dann dort reingehören)

auch der Termin Kalender würde mich auch nicht wirklich stören,

denn die Aufgabe, von diesem Termin Kalender wäre ja das Anzeigen von Verschiedenen Terminen, erstmal egal was für ein Termin.
Die Unterscheidung würde ja erst bei der Detail Ansicht kommen.
(Tipp einheitliches Interface wäre an dieser Stelle Ratsam)

Herzliche Grüße
Lars

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Danke für die schnelle Antwort!

oder falls es sich ja nur um eine 1:n Verbindung handelt, mit einem FK zur Gutachten Tabelle.

Was meinst du mit FK?

Danke für den Hinweis mit der History-Tabelle, aber das werde ich zum Glück nicht benötigen 😃

Das mit dem Interface werde ich auf jeden Fall berücksichtigen.

Mir ist nun noch folgendes eingefallen:
In den Terminkalender möchte ich einbauen, welcher Mitarbeiter zu einem Zeitpunkt, den ich im Terminkalender auswähle, noch Zeit hat. Sprich, jeder Mitarbeiter hat sozusagen seinen eigenen Terminkalender. Nun steht der Mitarbeiter.z.B. ein Gutachter ja eigentlich in der Tabelle Gutachten - und müsste nun natürlich, wenn es später noch mehr Kategorien gibt, jedes Gutachten, Meeting, etc pp zu dem Zeitpunkt durchgehen. Da hätte ich nun gesagt, dass das etwas aufwändig ist.

Sollte der jeweilige Mitarbeiter, der für das Ereignis zuständig ist, dann in den Terminkalender?
Spontan hätte ich nun gesagt "Nein", weil der Terminkalender wirklich nur die Zeit verwaltet, alles andere steht in den jeweiligen Kategorien, da jede Kategorie ja seine speziellen Eigenschaften besitzt.
Also Meeting --> viele versch. Mitarbeiter
während Gutachten --> nur eine Person

Wollte den Gedanken nur nochmal kurz in den Raum stellen.
Gruß,
Darokh

J
3.331 Beiträge seit 2006
vor 14 Jahren

FK = ForeignKey

(im DataSet ist es eine DataRelation)

Jürgen

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Achso ok, da rödel ich ja derzeitig eh dran 😃

5.299 Beiträge seit 2008
vor 14 Jahren

Hi!

Ich komm iwo bei untigem raus.
Mittm Terminkalender weißichnich - sollen Termine mehrerer Gutachter geführt werden, oder hat jeder seinen eigenen?

Wieso ein Gutachten eine TerminKategorie ist, versteh ich nicht. Ich stelle mir Gutachten als Dokumente vor, anders als etwa Sprechstunden oder Meetings.

Auch weißichgarnich, wie das mit verschiedenen Termin-Typen geht. Das ist ja keine 1:n - Relation, sondern eine Sprechstunde verweist auf genau einen Termin.
Ich weiß auch nicht, ob man das als 1:1-Relation bezeichnet, denn ein Termin verweist ja nicht unbedingt auf eine Sprechstunde.

Ich glaub, da muß man iwas machen mit erbenden Datenbank-Objekten, iwie, dass das Objekt Termin von Sprechstunde und Meeting beerbt wird.

Habich aber k.A., wie das geht, und ob Access das kann.

Oder man verzichtet auf die Unterscheidung von Sprechstunde und Meeting, und bastelt ein Termin-Objekt, was beides kann.

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

OK, vielen Dank für die Rückmeldung.
Die oberen Tabellen hatte ich nun auch genauso miteinander verknüpft.

Die Vererbung....da werde ich wohl etwas überfordert mit sein G
Habe nun jeweils pro Kategorie eine eigene Tabelle, da pro Kategorie auch sehr unterschiedliche Werte einfließen.

In den Terminen habe ich also dann eine KategorieID (Gutachten, Meeting etc) und dann die SubKategorieID, die mir dann auf den jeweiligen Verweis in der Tabelle zeigt.

Da habe ich noch die Frage:
Wenn ich nun eine ID als FK habe und diese in der anderen Tabelle durch die Find-Klausel suche, ist dies dann langsamer als über die DataRelation?

Vom Kopf und auch vom Coding her komme ich mit dieser Methode um Einiges besser zurecht.

Gruß,
Darokh

5.299 Beiträge seit 2008
vor 14 Jahren

Wassn eine Find-Klausel?

Wenn ich von einem Gutachten den Klienten haben will, machich


      private void foo() {
         PsychoDts.GutachtenRow rwGutachten =
            (PsychoDts.GutachtenRow)((DataRowView)gutachtenBindingSource.Current).Row;
         PsychoDts.KlientRow Klient = rwGutachten.KlientRow;
      }

und alle Tests eines Gutachtens holich mit


         PsychoDts.TestRow[] tests = rwGutachten.GetTestRows();

nicht wirklich, weil ich nutze gerne die Type-Inferenz


      private void foo2() {
         var rwGutachten =
            (PsychoDts.GutachtenRow)((DataRowView)gutachtenBindingSource.Current).Row;
         var Klient = rwGutachten.KlientRow;
         var tests = rwGutachten.GetTestRows();
      }

Daran ist nur der Cast über die BindingSource umständlich, alles weitere legt mir Intellisense unter die Finger.

Also fleißig im ObjectBrowser das generierte Dataset angucken - stecken noch 'ne Menge praktischer Sachen drin.

Zum OB gugge evtl. Möglichkeiten der Informationsgewinnung

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Vielen Dank!
Schaue ich mir heute Abend mal in aller Ruhe an.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Mit Find-Klausel meinte ich, dass ich etwas z.B. so suche:


DataRow meineKategorie = Kategorien.Rows.Find(terminEintrag["KategorieID"]);  

*Lach* also was du mir da an Code geschrieben hast verstehe ich kaum - da bin ich irgendwie noch zu unerfahren für. Ich weiß zwar, was du da grob machst, aber das wars auch schon G

Kannst du mir diesbezüglich ein konkreteres Kapitel / Schlagwort vorschlagen, das ich mir anschaunen kann? Habe schon gesucht, aber da das alles sehr breit gefächert ist...
Möchte mich ja gerne einlesen, aber ohne zu wissen, wonach ich genau suchen soll, ist das schwer 😃

5.299 Beiträge seit 2008
vor 14 Jahren

Das typisierte Dataset bietet statt der amorphen Datarows DataRow-Erben an, die die Werte als ordentliche Eigenschaften verfügbar machen.
Also statt


object DataRow["KategorieID"]

hast du eine Property KategorieID, und zwar vom typ int


int KategorieRow.KategorieID

Damit sind Schreibfehler im String-Schlüssel ausgeschlossen, auch, dass man versehentlich den Schlüssel auf eine falsche DataRow anwendet, und Zeugs.

Dein Beispiel soll wohl die per ForeignKey verknüpfte DataRow aus der Kategorie-Tabelle holen. Da hats auch ne Property für


//TerminRow rwTermin = ...
KategorieRow rwKat = rwTermin.Kategorie;

DataRows der Kategorie-Tabelle sind nicht mehr verwechselbar mit denen der Termin-Tabelle.

Ich weiß nicht recht, wasses da groß an Büchern zu lesen gibt - wie gesagt: Schau dir die Dinger im ObjectBrowser an.
Zu jeder Tabellenspalte hat eine typisierte DataRow eine passende Property, bei ForeignKeys gibts zusätzlich eine Prop, mit der die ParentRow typisiert(!) abgerufen wird, auch Props, mit denen untergeordnete DataRows typisiert abgerufen werden, und auch Methoden zum testen auf IsDBNull, usw.

Die Basis-Typen: DataRow, DataTable, DataRelation werden i.a. überhaupt nicht mehr angefasst.

Du kannst mal im Hilfe-Index "Dataset" eingeben, müsste eiglich ein paar gute Artikel auswerfen.

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

OK, ich versuche mich da mal reinzulesen. Sieht auf jeden Fall übersichtlicher und weniger fehleranfällig aus.

Eine grundlegende Frage habe ich noch zum generellen Vorgehen:

  1. Ich habe es nun so gemacht, dass ich in VS ein Dataset mit Tabellen aus einer Access DB zu den Datenquellen hinzufügt habe (also über Daten --> Datenquelle hinzufügen).

  2. Danach habe ich die Tabellen in den Designer gezogen und entsprechend der Fremdschlüssel / Beziehungen miteinander verknüpft.

  3. Die benötigten TableAdapter aus den Tools in das Windows-Form gezogen.

  4. Beim Load des Forms folgendes gemacht:


Datatable Kategorien = tbl_KategorienTableAdapter1.GetData();

und arbeite nun immer mit der Tabelle "Kategorien" in dem Form weiter.

Denn wenn ich "meinDataset.Kategorien" eingebe, dann erzählt er mir direkt, dass "Kategorien" ein ungültiger Objektverweis sei.... 😕

Bei dem letzten Schritt bin ich mir einfach total unsicher, ob das so richtig ist und genau der Teil wird in jedem Tutorial im Web immer ausgelassen. (auch in dem DB in 10 Minuten). Sondern dann wird immer direkt eine Tabelle in das Windows-Form gezogen. Entweder wird eine Tabelle komplett neu erstellt, dann ist mir das Vorgehen eh klar, oder es wird per Tableadapter gemacht, aber dann wird nicht gezeigt, wie damit weitergearbeitet wird.

Da wäre ich nochmal über Rückmeldung sehr dankbar, bin dann auch vorerst ruhig und lese in aller Ruhe die typisierten Datasets durch 😉

Vielen Dank nochmal an alle für die geduldige Hilfe.
Gruß,
Darokh

5.299 Beiträge seit 2008
vor 14 Jahren

wenn du aus dem Datenfenster Tabellen aufs Form tust, schmeisster ja auch gleich ein Dataset von der passenden Sorte aufs Form.
Und da sind die Tabellen ja alle drin, nur erst noch leer.
Daher nehm ich immer die Fill-Methode, nicht die GetData. Weil GetData erzeugt eine neue DataTable, die dann erstmal keinem Dataset angehört.


tbl_KategorienTableAdapter1.Fill(meinDatasetAuffmForm.Kategorien);

Und dann ist die im meinDatasetAuffmForm enthaltene Tabelle Kategorien befüllt.

Wüsste nicht, dassich den Teil im tut ausgelassen hätte, das steht in der Methode LoadData().

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Vielleicht hab ich das etwas unglücklich ausgedrückt. Ich ziehe die Tabelle nichts ins Form, sondern in den Designer, in dem man die Tabellen miteinander verknüpfen kann.

Und da hab ich dann eben meine Probleme, weil ich irgendwie keine Quelle finde, in der das mal komplett als Beispiel steht, so wie ich das brauche. Irgendwie fehlt mir da ein Stück an Information / Wissen, so dass ich da nicht durchsteige. Keine Ahnung warum.


GutachtenDS = new DataSet();
DataTable TerminKalender = GutachtenDS.Tables.Add();

tbl_TerminkalenderTableAdapter1.Fill(GutachtenDS.TerminKalender);

Das klappt eben nicht und keinen Plan was ich da nun falsch mache...

Ironischerweise klappt alles andere, wenn es nicht um diese ganze Tabellengeschichte geht, gut...tue mich da aus irgendeinem Grunde ziemlich schwer mit 😦

5.299 Beiträge seit 2008
vor 14 Jahren

Jetzt nochmal genau:
Von wo (ServerExplorer, Datenfenster...) ziehst du Tabellen in welchen Designer (FormDesigner, DatasetDesigner...)?

Ich kapier auch nix von der Wissenslücke.

Auf jeden fall solltest du nicht per Code einem typisierten Dataset noch Tabellen zufügen - weil die sind, wie gesagt, schon alle drin.

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Tut mir leid, man was hab ich da im letzten Post für einen Schrott geschrieben.

Also:
Ich habe die Tabellen über Daten --> hinzufügen , äh, hinzugefügt. Das heißt, ich hab ja nun ein typisiertes Dataset.

In jedem anderen Tutorial sehe ich nun, wie jemand die Tabellen dann nimmt, und in das Form hineinzieht. Aber das mache ich nun nicht, da ich nicht unbedingt immer mir die Tabellen anziegen lassen, sondern nur darin etwas suchen lassen möchte.

Darum ziehe ich dann aus der Toolbox den entsprechenden Tableadapter in das Form.

So, und nun stehe ich wie der Ochs vorm Berg: Bestimmte Sachen, die ihr mir an Code zeigt, gehen dann gar nicht oder ich weiß nicht, was ich damit anfangen soll.
(z.B.

 tbl_KategorienTableAdapter1.Fill(meinDatasetAuffmForm.Kategorien);

Also fehlt mir da irgendwie ein Schritt und ich weiß nicht was. Und wie gesagt, im MSDN etc stehen immer nur die Schritte, wenn man die Tabelle dann ins Form direkt zieht ODER direkt im Form eine Tabelle neu erstellt, füllt, oder per Code direkt die Verbindung zur DB herstellt, und dann sieht das für mich wieder komplett anders aus.

Da ist nun meine Frage, was muss ich nun machen, um in einer Tabelle etwas suchen zu lassen / Zugriff auf die Tabelle / Daten der Tabelle zu haben, nachdem ich die Schritte, die ich oben beschrieben habe, gegangen bin.

5.299 Beiträge seit 2008
vor 14 Jahren

In jedem anderen Tutorial sehe ich nun, wie jemand die Tabellen dann nimmt, und in das Form hineinzieht. Aber das mache ich nun nicht, da ich nicht unbedingt immer mir die Tabellen anziegen lassen, sondern nur darin etwas suchen lassen möchte.

Ah!

Frage: willst du in einer DataTable suchen oder direkt ein Suchkommando an die DB absetzen, und die Ergebnisse in eine DataTable füllen?


Ersteres ist günstig, wenn du dieselben Daten öfter durchsuchen willst, unds nicht so irre viele sind.
[CSHARP]tbl_KategorienTableAdapter1.Fill(meinDatasetAuffmForm.Kategorien);[/CSHARP]
befüllt dir die DataTable meinDatasetAuffmForm.Kategorien, und nun kannste darin herumsuchen - ob du sie zusätzlich anzeigst, ist egal.

Für letzteres musste im TableAdapter eine zusätzliche Query anlegen, zb. per Rechtsklick auffm TableAdapter. Dabei kannman auch sonen SQL-Assistenten usen.

Unten habich zb für eine KundeDataTable eine Query "FillKundeByID" angelegt. 

Das generiert eine neue Methode im TableAdapter, nämlich [CSHARP]int FillKundeByID(KundeDataTable dataTable, int KundeID)[/CSHARP]
Kannst natürlich auch GetKundeByID machen, dann gibter dir jeweils eine neue KundeDataTable zurück.

Beachte: Indem ich in der KundeID-Zeile Filter-Spalte "=?" eingetragen hab, habe den Parameter konfiguriert.

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Also erstelle ich im ersten Weg auf dem Form ein neues DataSet mit Tabellen, und befülle die dann durch den TableAdapter (mit Fill), wodurch das also eine eigenständige Einheit auf dem Form wird, die ich der DB dann später mit .Update wieder zurückschicke.


meinDataSetAufm Form = new DataSet();
DataTable Kategorien = meinDataSetAufm.Tables.Add();

tbl_TerminkalenderTableAdapter1.Fill(meinDataSetAufm.Kategorien);

Und beim zweiten Weg habe ich die einzelnen Abfragen und hole mir die gewünschten Daten aus der DB direkt - das ist dann ja eine normale SQL-Abfrage.
Die Ergebnisse kommen dann auch wieder in eine DataTable, die ich in dem Form definiert habe.

Ich hoffe, das habe ich nun richtig gecheckt.

Wann fängt für dich "nicht so irre viel" an? 😃

5.299 Beiträge seit 2008
vor 14 Jahren

Also erstelle ich im ersten Weg auf dem Form ein neues DataSet mit Tabellen, und befülle die dann durch den TableAdapter (mit Fill), wodurch das also eine eigenständige Einheit auf dem Form wird, die ich der DB dann später mit .Update wieder zurückschicke.

soweit richtig. Im weiteren habichdas Gefühl, du liest nicht genau genug, wassich schreibe.

  
meinDataSetAufm Form = new DataSet();  
DataTable Kategorien = meinDataSetAufm.Tables.Add();  
  
tbl_TerminkalenderTableAdapter1.Fill(meinDataSetAufm.Kategorien);  
  
  1. Zeile: dein Dataset darf nicht im Code instanziert werden, sondern der Designer packtes dir aufs Form. Wenn du die Tabelle nicht angucken willst, schmeisste das DatagridView halt wieder runter (den BindingNavigator-Müll sowieso runterschmeißen), behälst aber TableAdapter und Dataset.
  2. Zeile: Keine DataTables zu generierten Datasets adden!! Die sind schon drin!!
  3. Zeile: die ist ok, ausser, dass du diesen unerfreulichen "tbl_" - prefix offenbar schon in der DB angelegt hast.

total unpraktisch und überflüssig diese Prefixe - machen nur den Code unleserlich, und behindern die Intellisense, weil nun zig Properties generiert werden, die alle mit "tbl_" anfangen.

Und beim zweiten Weg habe ich die einzelnen Abfragen und hole mir die gewünschten Daten aus der DB direkt - das ist dann ja eine normale SQL-Abfrage.
Die Ergebnisse kommen dann auch wieder in eine DataTable, die ich in dem Form definiert habe.

vorzugsweise in dieselbe von oben - die der Designer dir draufgepackt hat.

Wann fängt für dich "nicht so irre viel" an? 🙂

Ich vergleiche gerne mit bild-Dateien. Da belegt eine Bitmap locker 10MB zusammenhängenden (!!) Arbeitsspeicher.

von daher würdich denken, wenn ein Dataset 20MB hat, tut das immer noch keinem weh, v.a., weil der durchs Dataset belegte Speicher nicht en bloc sein muß.

einen wirklichen Plan, was wieviel belegt, habich nicht, aber angenommen ein Datensatz mit 10 Spalten, - lass ihn 500Byte belegen.
Da bräuchte man also 40000 von, um 20MB zu beanspruchen.

Daran anschließt sich die Frage ans Gui: Welcher arme User soll sich 40000 Datensätze angucken?

Der frühe Apfel fängt den Wurm.

D
Darokh Themenstarter:in
32 Beiträge seit 2009
vor 14 Jahren

Ich habe es mir sogar sehr genau durchgelesen,aber jetzt wo du sagst, dass ich den anderen Schrott ja einfach wieder löschen kann, wenn ich die Daten nicht anschauen möchte - nun wird mir das erst klar, wie du das meinst.
Tut mir leid, wenn das den Eindruck erweckt hat, ich würde nicht richtig lesen.

OK, dann habe ich das nun verstanden, denke ich. Vielen Dank für deine Geduld...

Viele Grüße,
Darokh

5.299 Beiträge seit 2008
vor 14 Jahren

Ein Sample, was ein klein bischen mehr macht, als nur Tabellen anzeigen ist in Vorüberlegung zur Form2Form beigelegt.

Der frühe Apfel fängt den Wurm.