Seite 1 von 1

Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 29.04.2011 23:27
von John
Moin Leute,

ich brächte mal ein paar Anregungen, vorzugsweise von erfahrenen DB Profis.

Es geht um das Design (also welche und wie viele Tabellen, welche Feldnamen in welcher Tabelle?) einer einfach Datenbankanwendung.

Also, ein Musikverein hat ein paar hundert Lieder. Gut, das kommt in eine Tabelle.

Nun hat der Musikverein Auftritte. Gut, dass kommt in die zweite Tabelle. Hier ist mir jedoch noch nicht ganz klar, welche Felder diese Tabelle haben sollte.

Und nun ist es ja so, dass bei einem Auftritt (kann ein Übungsabend, eine Probe, oder auch ein "echter" Auftritt sein) nur einige wenige der einstudierten Musikstücke / Lieder gespielt werden. Gut, also eine dritte Tabelle. Aber spätestens hier ist mir unklar, wie diese gestaltet sein sollte.

Hier mal ein Beispiel, vielleicht kann das ja mal der eine oder andere verbessern.

Danke.

Code: Alles auswählen

; BEGINN für Tabelle 1  (Musikstücke)
	statement_create1 = "CREATE TABLE " + db_tablename1 + " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"
	statement_create1 + ",titel VARCHAR(50)"		; Feld 1, denn Feld 0 ist die ID
	statement_create1 + ",musik VARCHAR(30)"
	statement_create1 + ",bearbeitet VARCHAR(30)"
	statement_create1 + ",genre VARCHAR(30)"
	statement_create1 + ",takt VARCHAR(30)"
	statement_create1 + ")"
	; CREATE Table erste Datentabelle....
	DatabaseUpdate(0, statement_create1)		; statement für CREATE TABLE 1
	;Debug statement_create1
	db_error_str = DatabaseError()			; letzten Fehler als Textstring speichern.
	;---
	;---
	; CREATE Tabelle 2 (Auftritte)
	statement_create2 = "CREATE TABLE " + db_tablename2 + " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"
	statement_create2 + ",ort VARCHAR(30)"		; Feld 1, denn Feld 0 ist die ID
	statement_create2 + ",platz CHAR(30)"
	statement_create2 + ",tag CHAR(2)"
	statement_create2 + ",monat CHAR(2)"
	statement_create2 + ",jahr CHAR(4)"
	statement_create2 + ",startzeit CHAR(5)"
	statement_create2 + ",endzeit CHAR(5)"
	statement_create2 + ",grund VARCHAR(30)"
	statement_create2 + ")"
	; CREATE Table zweite Datentabelle...
	DatabaseUpdate(0, statement_create2)		; statement für CREATE TABLE 2
	db_error_str = DatabaseError()			; letzten Fehler als Textstring speichern.
	;--
	;--
	; CREATE Tabelle 3 (gespielte Stücke)
	statement_create3 = "CREATE TABLE " + db_tablename3 + " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"
	statement_create3 + ",titel CHAR(2)"		; Feld 1, denn Feld 0 ist die ID
	statement_create3 + ")"
	; CREATE Table zweite Datentabelle...
	DatabaseUpdate(0, statement_create3)		; statement für CREATE TABLE 3
	db_error_str = DatabaseError()			; letzten Fehler als Textstring speichern.
__________________________________________________
Code-Tags hinzugefügt
29.04.2011
RSBasic

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 29.04.2011 23:59
von shadow
Hi :mrgreen:

Als Tip:
Es wäre besser wenn du die SQL-Anweisungen extern auslagerst und dann über IncludeBinary der Exe hinzufügst. So hast du eine bessere Übersicht über die einzelnen Skripte und kannst uns diese besser vorführen (reines SQL zu verstehen ist leichter als den Misch-Masch innerhalb eines Programms).

So, jetzt zu deinem Problem. Also die Normalisierung hast du an sich ja vorgenommen. Es kommt ganz drauf an wie detailliert du die Datenhaltung brauchst. Bisher kommt es mir eher wie ein Flussdiagramm vor (das wird von das benötigt, das wird von jenem benötigt, dieses führe an diesem tag aus ...). Also ich meine, ich verstehe dein Problem nicht so recht? Klar, einige können es für dich ausstoffieren und verkomplizieren (also optimieren wie das einige nennen :freak: ) aber an sich ist das doch so wie es ist ausreichend. Sonst müsstest du halt (jedenfalls für mich :( ) eine konkretere Problemstellung definieren...

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 30.04.2011 00:22
von John
Hi Shadow,

gut, bevor ich zur Nachruhe gehe, versuche ich es noch mal;-)

Also, es soll eine Spielstatistik von einem Musikverein in einem PB Programm auf Basis von SQLite erstellt werden.

In Tabelle 1 sind alle Musikstücke enthalten, die der Verein überhaupt spielen kann. Also Titel, und weitere Infos.

Nun hat dieser Verein ja Übungsabende (Proben) und auch echte Auftritte.

Bei jedem Auftritt wird nun erfasst, welches Musikstück gespielt wurde, ggf. auch warum dieses gespielt wurde (z.B. es wurde gewünscht).

Also müsste man doch eine zweite Tabelle haben, wo man erstmal die ganzen Termine für Übungsabende und Proben und Auftritte festhalt, richtig?

Und die dritte Tabelle - so stelle ich mir das vor, weiss aber nicht ob das so sein sollte, oder es anders besser ist - enthält dann die gespielten Musikstücke.

Meine Frage; wie muss so eine DB "geplant" werden, damit hinterher mit SELECT.... alle möglichen und unmöglichen Abfragen machbar sind.

z.B. Liste mir mal alle Titel auf, die immer auf dem Schützenfest in..... am meisten gespielt wurden..

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 30.04.2011 01:26
von Kiffi
Im Prinzip recht einfach:

Tabelle_1: Musikstücke
Tabelle_2: Auftritte

Tabelle_1 und Tabelle_2 haben je ein Feld 'ID' (INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)

Nun baust Du Dir noch eine dritte Tabelle mit den Feldern:
'ID' (INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)
'ID_aus_Tabelle_1' (INTEGER)
'ID_aus_Tabelle_2' (INTEGER)

Wenn nun also Musikstück 2 bei Auftritt 5 gespielt wird, trägst Du in die dritte Tabelle folgendes ein:

Code: Alles auswählen

Insert Into Tabelle_3 (ID_aus_Tabelle_1, ID_aus_Tabelle_2) Values (2, 5)
Somit steht auch einer späteren statistischen Auswertung nichts im Weg.

(die Tabellen- und Feldbezeichnungen wählst Du natürlich nach Deinem
Geschmack; ich habe sie nur zur Verdeutlichung so sperrig gewählt)

Grüße ... Kiffi

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 30.04.2011 10:59
von John
Hi Kiffi,

danke dir.

Ist das wirklich schon alles?

Kann ich so wirklich alle möglichen und "unmöglichen" Anfragen machen?

So wird doch nur gespeichert, was gespielt wurde. NICHT was NICHT gespielt wurde.

Wie kann ich also abfragen, was z.B. auf dem Schützenfest in .....noch nie gespielt wurde?

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 30.04.2011 13:18
von SirMatti74
Ja, ist es. Da Du Playlisten der einzelnen Auftritte und Proben verwalten willst solltest Du die 3. Tabelle auch so nennen: PLAYLIST.

Ich würde Dir aber empfehlen, zu den 3 genannten Feldern noch ein 4. für die Reihenfolge hinzuzufügen: POSITION (INT). Damit könntest Du komplette Ablaufprogramme verwalten.

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 30.04.2011 13:42
von Kiffi
John hat geschrieben:Ist das wirklich schon alles?
Jop
John hat geschrieben:Kann ich so wirklich alle möglichen und "unmöglichen" Anfragen machen?
hier mal ein kleiner Auszug:

Code: Alles auswählen

UseSQLiteDatabase()

Global DB

DB = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)

; Tabellen erstellen
DatabaseUpdate(DB, "Create Table Musik (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Titel)")
DatabaseUpdate(DB, "Create Table Auftritte (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Ort)")
DatabaseUpdate(DB, "Create Table GespielteMusik (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ID_Musik, ID_Auftritt)")

; Musikstücke
DatabaseUpdate(DB, "Insert Into Musik (Titel) Values ('Alle meine Entchen')")
DatabaseUpdate(DB, "Insert Into Musik (Titel) Values ('Alle Vögel sind schon da')")
DatabaseUpdate(DB, "Insert Into Musik (Titel) Values ('Drei Chinesen mit dem Kontrabass')")
DatabaseUpdate(DB, "Insert Into Musik (Titel) Values ('Häschen in der Grube')")

; Auftritte
DatabaseUpdate(DB, "Insert Into Auftritte (Ort) Values ('Peters Partykeller')")
DatabaseUpdate(DB, "Insert Into Auftritte (Ort) Values ('Zupfenberger Seniorenresidenz')")
DatabaseUpdate(DB, "Insert Into Auftritte (Ort) Values ('Eurovision Song Contest')")

; In Peters Partykeller werden alle 3 Stücke gespielt
DatabaseUpdate(DB, "Insert Into GespielteMusik (ID_Musik, ID_Auftritt) Values (1, 1)")
DatabaseUpdate(DB, "Insert Into GespielteMusik (ID_Musik, ID_Auftritt) Values (2, 1)")
DatabaseUpdate(DB, "Insert Into GespielteMusik (ID_Musik, ID_Auftritt) Values (3, 1)")

; In der Seniorenresidenz werden nur 2 Stücke gespielt
DatabaseUpdate(DB, "Insert Into GespielteMusik (ID_Musik, ID_Auftritt) Values (1, 2)")
DatabaseUpdate(DB, "Insert Into GespielteMusik (ID_Musik, ID_Auftritt) Values (2, 2)")

; Und auf dem Eurovision Song Contest nur ein Stück
DatabaseUpdate(DB, "Insert Into GespielteMusik (ID_Musik, ID_Auftritt) Values (1, 3)")


; Nun die Abfragen

Procedure ExecuteQuery(Query.s)
  If DatabaseQuery(DB, Query)
    While NextDatabaseRow(DB)
      Debug GetDatabaseString(DB, 0)
    Wend
    FinishDatabaseQuery(DB)
  EndIf
EndProcedure

Define Query.s

Debug "Welche Stücke wurden in der Seniorenresidenz gespielt?"

Query = " Select Titel From Musik, Auftritte, GespielteMusik"
Query + " Where Musik.ID = GespielteMusik.ID_Musik"
Query + " And Auftritte.ID = GespielteMusik.ID_Auftritt"
Query + " And Auftritte.Ort = 'Zupfenberger Seniorenresidenz'"

ExecuteQuery(Query)

Debug ""
Debug "Wo wurde 'Alle Vögel sind schon da' gespielt?"

Query = " Select Ort From Auftritte, Musik, GespielteMusik"
Query + " Where Musik.ID = GespielteMusik.ID_Musik"
Query + " And Auftritte.ID = GespielteMusik.ID_Auftritt"
Query + " And Musik.Titel = 'Alle Vögel sind schon da'"

ExecuteQuery(Query)

Debug ""
Debug "Welches Stück ist am häufigsten gespielt worden?"

Query = " Select Musik.Titel, Count(GespielteMusik.ID_Musik) As Anzahl From GespielteMusik, Musik"
Query + " Where GespielteMusik.ID_Musik = Musik.ID"
Query + " Group By GespielteMusik.ID_Musik"
Query + " Order By Anzahl Desc"
Query + " Limit 1"

ExecuteQuery(Query)

Debug ""
Debug "Welches Stück ist am seltensten gespielt worden?"

Query = " Select Musik.Titel, Count(GespielteMusik.ID_Musik) As Anzahl From GespielteMusik, Musik"
Query + " Where GespielteMusik.ID_Musik = Musik.ID"
Query + " Group By GespielteMusik.ID_Musik"
Query + " Order By Anzahl Asc"
Query + " Limit 1"

ExecuteQuery(Query)

Debug ""
Debug "Welches Stück ist noch nie gespielt worden?"

Query = " Select Musik.Titel From Musik "
Query + " Where Musik.ID Not In (Select ID_Musik From GespielteMusik) "

ExecuteQuery(Query)
Alle anderen 'unmöglichen' Queries darfst Du selber ausknobeln ;-)

Grüße ... Kiffi

Re: Design(Hilfe) einer (SQLite) Datenbank

Verfasst: 30.04.2011 16:20
von John
Hi SirMatti74,
Hi Kiffi,

also erstmal danke, besondern natürlich an Kiffi.

Finde ich echt supernett das du dir hier so viel Arbeit macht.

Gut, ich speicher mir das alles, denn die nächsten Tage komme ich nicht dazu.

Wünche euch allen ein tolles WE.