Autor Beitrag
Talemantros
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 10.04.14 09:32 
Hallo,
um Anfängerfehler zu vermeiden würde ich euch gern meine ersten Tabellen in meiner MySQL Datenbank zeigen und 2 Fragen stellen.

Umsetzen sollen diese beiden Tabellen folgendes:

Die erste Tabelle enthält Namen aller Forms, die in meinem Projekt enthalten sind und eine Beschreibung zu diesen Modulen.
Diese werden dann in einem DataGridView angezeigt später und sollen ausgewählt werden können um eine Benutzergruppe zu bauen

Die zweite Tabelle enthält den Namen der Benutzergruppe mit dem entsprechenden Verweis zu der ersten Tabelle um zu wissen welche Gruppe was darf.

Erste Tabelle habe ich mir so vorgestellt:

id --> AutoIncrement --> Primary Key
modulname --> varchar(50)
Beschreibung --> varchar(50)

Die zweite Tabelle soll die Gruppen enthalten mit den Verweisen

id --> ForeignKey auf id der ersten Tabelle
gruppe --> varchar(100)


Wenn in der ersten Beispielsweise ein Modul namens VerbindungDatenbank steht mit der id 5

und es eine Gruppe geben soll, die das kann, würde in der zweiten stehen

id 5
gruppenname "admin"

Ich hoffe, dass dies verständlich war/ist.
Meine Frage ist wie folgt, weil es ja nicht nur dieses Beispiel sondern viele andere mit Datenbanken betrifft.

1.) Ist der grundsätzliche Aufbau der Tabelle ok? Oder würde man dies anders machen?
2.) Wenn nun einer in dem Datagridview eine Zeile markiert wie müsste den dann der Insert für die zweite Tabelle lauten

Muss ich erst in die Tabelle eins gehen, den markierten Eintrag suchen und mit dem gefundenen Eintrag die ID auslesen und mit diesem in der Tabelle 2 ein Insert machen, oder gibt es da eine andere Lösung und ich denke zu kompliziert?

Vielen Dank

Freundliche Grüße
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 10.04.14 12:52 
Du hast Module und Gruppen. Und die stehen in einer n zu n Beziehung. Also Gruppen können Beziehungen zu mehreren Modulen haben (das kann dein gerade angedachtes Model gerade nicht) und umgekehrt (das ginge).

Ich bringe da mal ein paar (meine) Best Practises beim Tabellendesign unter. Ich erhebe da aber keinerlei Anspruch auf ~Wahrheit~. Die entsprechen auch nicht was üblicherweise in einem DB Buch als BestPractides zu finden ist. Die stammen ja da auch üblicherweise von DB Experten und nicht von Programmieren die auch irgendwie mit dem System arbeiten müßen ;) Das sind also hier meine Best Practises aus Programmierer Sicht.

a.) Jede Tabelle sollte eine eigenen Primary Key haben. Innerhalb einer Datenbank am besten immer vom gleichen Typ und Art (also wenn Autoincrement dann immer Autoincrement, wenn mit einem Generator dann immer, wenn vom Typ x dann immer Typ x). Das Einhalten eines Musters läßt dir in Zukunft immer die Möglichkeit für zukünftige Erweiterungen generische Lösungen zu schreiben die bei allen Tabellen funktionieren.
b.) Der PrimaryKey sollte den Tabellennamen enthalten das macht es einfacher lesbares SQL zu schreiben wenn alles ID heißt bist du an vielen Stellen sonst gezwungen den Tabellenamen auch anzugeben.
(Klingt so als würde es a.) wiedersprechen. Stimmt aber denn Gewinn erachte ich hier höher als denn Verlust :wink: )
c.) ForeignKeys sollten so heißen wie der PrimaryKey auf den er verweist. Davon sollte man nur abweichen wenn eine Tabelle mehrere Foreignkeys auf die gleiche Tabelle hat. Auch ein Punkt aus der Lesbarkeit Ecke.
d.) Für TabellenName entscheide dich eindeutig immer für Plural oder Singular. Nicht anfangen zu mischen. Gerade wenn es um den PK geht. Also Tabelle im Plural(Module) den PK aber in Singular (ModulId)

Dann jetzt zu denn eigentlichen Tabellen. Da es eine n zu n Beziehung ist bietet sich an Zwischen Modul und Gruppe eine Mapping Tabelle zu haben.
Also

Tabelle Modul
ModulId(PK) long, ModulName varchar(50), Beschreibung varchar(50)

Tabelle Gruppe
GruppeId(PK) long, GruppeName varchar(50), Beschreibung varchar(50)

Tabelle ModulGruppe
ModulGruppeId(PK) long, GruppeID(FK) long, ModulID(FK) long
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 10.04.14 18:19 
Hi,
ich finde es immer wieder klasse wie viel Zeit und Mühe du in deine Antworten steckst und wie ausführlich diese sind.
Danke, dass ihr/du deine Zeit für mich opferst.

Die Erläuterungen sind sehr gut und machen Sinn. Ich denke, dass ich mir das so auch angewöhnen werden.
Wie bereits erwähnt macht es am Anfang jetzt viel Sinn die Zeit zu investieren es gleich "richtig" zu machen.

Wenn ich nun diese Konstellation deiner Tabellen annehme, wärst du bereit mir zu erklären wie die Abfragen gegen die Datenbank lauten müssten.
Tabelle Modul wäre dabei ja schon gefüllt. Diese Daten sind ja im DataGridView zu sehen und anwählbar.
Das angewählte soll dann in die beiden anderen Tabellen geschrieben werden.

Ich als Anfänger würde jetzt wie folgt vorgehen:

1.) Auswahl des Textes im DataGridView einlesen und mit Tabelle Modul vergleichen um die ModulID in eine Variable einzulesen
2.) Name der Gruppe in Tabelle Gruppe schreiben
3.) Danach schauen welche GruppeId die neue Gruppe erhalten hat und in eine Variable speichern
4.) Beide Daten in Tabelle ModulGruppe schreiben

Irgendwie scheint dies sehr aufwendig und ich vermute es geht einfacher.

Danke schonmal

Gruß
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 15.04.14 14:02 
Warum willst du etwas in der Gruppe Tabelle erzeugen? Für mich ist die genauso ~vordefiniert~ wie die Modul Tabelle (es gibt die Module A,B,C,D,E und die Gruppen Benutzer, Admin etc.)
Du würdest alle in einem Dialog das Modul auswählen und eine passende Gruppe. Von beidem sollte leicht die ID ermittelbar sein und dann muß die Kombi einfach in die Mapping Tabelle eingetragen werden.
Die Modul und Gruppen Tabelle sollten unverändert bleiben.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 17.04.14 10:24 
Guten Morgen,
die Idee dahinter war, dass ich ja nicht vordefinieren kann für den entsprechenden Bereich, wie diese Ihre Gruppen benennen wollen bzw. auch neue Anlegen können sollen.

Ich bin jetzt schon mal soweit beim Lesen und schlau machen gekommen, dass die Methode ExecuteNonQuery die id als Rückgabewert hat und ich diese danach nicht noch mal neu einlesen muss.

Weiterhin würde ich die Id des Moduls aus der Tabelle mit ins DataGridVirew laden und die Spalte dann ausblenden, so könnte ich die ID des angeklickten einlesen ohne dies auch über einen SQL Befehl zu machen.

Wäre die grobe Richtung soweit ok?!

Viele Grüße
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 17.04.14 10:34 
Zitat:
die Idee dahinter war, dass ich ja nicht vordefinieren kann für den entsprechenden Bereich, wie diese Ihre Gruppen benennen wollen bzw. auch neue Anlegen können sollen.


Ok, ich würde persönlich das trotzdem in 2, räumlich in der UI getrennten, Aufgaben lösen. Einmal das Anlegen der möglichen Gruppen und das andere mal halt die Zuordnung Modul<->Gruppe.
Das als Freitext in ein Grid einzutragen und einfach nur neu in der Gruppen Tabelle zu erzeugen führt mit hoher Wahrscheinlichkeit nur dazu das derjenige der das macht nicht prüft was es bereits für Gruppen gibt da er nicht einfach eine Übersicht der vorhandene Gruppen vor sich hat. Am Ende hast du dann die Gruppen Admin, admin, Administrator, root, sa etc. die vermutlich alle das gleiche meinen aber nun n*mal da sind.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 17.04.14 10:40 
Hallo Talemantros,

bzgl. des Rückgabewerts von ExecuteNonQuery hast du aber anscheinend etwas falsches gelesen, denn der Rückgabewert ist nur die Anzahl der Änderungen (Insert, Delete, etc.), keine Id, s. z.B. SqlCommand.ExecuteNonQuery (unter "Remarks").
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 17.04.14 10:58 
Stimmt das würde man mit ExecuteScalar machen und dort direkt einen passenden Select an den Insert hängen um die im Batch auszuführen (Das Beispiel in der Hilfe zeigt genau das).
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 17.04.14 11:13 
Hi ihr beiden,
vielen Dank.
Werde ich mir bei Zeiten anschauen, die Hilfe lesen und an einer Umsetzung arbeiten.

Schöne Ostern

Viele Grüße

Edit:
Habe mir gerade schon mal die Hilfe angeschaut und glaube habe dies in meinem Post nur verwechselt. Den Code bin ich der Meinung in der Menge schon mal gelesen zu haben :-)
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Mo 21.04.14 09:51 
Hallo und schöne Ostern,
Ich habe das nun gebaut und kann auch die Daten schreiben.

Leider bekomme ich den SQL String nicht hin der die Daten wieder ausgibt.
Wenn einer über die Combobox eine Gruppe auswählt sollen die zugehörigen Module angezeigt ( ausgegeben ) werden.

Wäre dankbar für Hilfe.

Gruß

Edit: Habe es mit Join hinbekommen. Danke