Verständnisfrage zur Normalisierung, ERM Model

json1948

Neuer Benutzer
Beiträge
4
Hey community,

ich bin noch relativ neu in der Datenbank-Welt und muss sehr dringend etwas wissen bevor ich in die mündliche Prüfung geh

Ich habe in Microsoft Visual Studio eine Dienstbasierte Datenbank mit folgenden 2 Tabellen:

1.Tabelle

id [PK] | Name | passwort | Straße | Hausnummer | Ort | PLZ | Automarke | Ø-Sprtiverbrauch
1 | john | 12345 | Heistraße | 9 | Berlin | 10978 | VW | 7
2 | Tom | tom234 | Lotstraße | 123 | Berlin | 10978 | BMW | 8

2. Tabelle

Zeit [PK] | Datum | Erdgaspreis | Benzinpreis | Dieselpreis
14:23 | 13.03.2015 | 1,09 | 1,48 | 1,25 |
18:19 | 18.04.2015 | 1,07 | 1,48 | 1,28 |

Wie ihr sehen könnt haben beide Tabellen keinen Zusammenhang miteinander. Die 1. Tabelle dient für eine Anmeldungsfunktion und mit der 2.Tabelle werden Werte in ein Diagramm gefüllt.

Ist es richtig, dass beide Tabellen sich in der 1.Normalform befinden weil die Attribute nicht weiter gespalten werden können?

Wenn ein ERM Model erstellt werden müsste bezüglich aller Tabellen in der Datenbank könnte man mit diesen zwei, von einander völlig unabhängigen Tabellen ein ERM Model machen ?

Findet ihr die Tabellen gut ? Bezüglich der Redundanzfreiheit

MFG

json
 
Werbung:
Was machst Du, wenn Du am 26. August um 14:24 Uhr weitere Preise speichern willst? Und was, wenn auch noch Heizöl dazu kommen soll?
 
kann das nicht einfach gespeichert werden? Und ich hab einen kleinen Fehler drin die Zeit wird so gespeichert.
14:23:12 also die Sekunden auch. Worauf willst du mit Heizöl hinaus :S ?
 
Wenn nur die Zeit der PK ist, dann kannst Du nur einmal 14:23:12 speichern. Es ist sehr ungeschickt, Datum und Zeit getrennt zu speichern, warum willst Du das?
Heizöl: Dein Datenmodell skaliert nicht. Falls später noch Heizöl dazu kommt, mußt Du es ändern.
 
Wenn nur die Zeit der PK ist, dann kannst Du nur einmal 14:23:12 speichern. Es ist sehr ungeschickt, Datum und Zeit getrennt zu speichern, warum willst Du das?

Da ich in meiner Anwendung ein Diagramm darstelle, welches eine Tagesansicht ermöglicht. Sprich, der User kann ein Datum aus der Datenbank wählen und bekommt ein Diagramm mit allen Tageszeiten die in der Datenbank für dieses Datum vorhanden sind. Das funktioniert eigentlich in der getrennten Form Zeit und Datum relativ gut, aber wenn man dies zusammen in einer Spalte speichern würde, wäre doch das ganze nicht mehr atomisiert und schwer alle Daten für ein Datum auszugeben oder ?

Heizöl: Dein Datenmodell skaliert nicht. Falls später noch Heizöl dazu kommt, mußt Du es ändern.

Wie müsste die Veränderung genau aussehen?
 
Zuletzt bearbeitet:
vielleicht so:

Code:
test=# create table artikel (id int primary key, name text);
CREATE TABLE
Time: 6,619 ms
test=*# create table preise (id int primary key, artikel int references artikel, zeitraum daterange, preis numeric, exclude using gist(artikel with =, zeitraum with &&));
CREATE TABLE
Time: 23,422 ms

Da hast auch noch die Information, von - bis der preis gilt, und es kann keine Überscheidungen geben (exclusion constraint).
 
test=# create table artikel (id int primary key, name text); CREATE TABLE Time: 6,619 ms test=*# create table preise (id int primary key, artikel int references artikel, zeitraum daterange, preis numeric, exclude using gist(artikel with =, zeitraum with &&)); CREATE TABLE Time: 23,422 ms

Ich tue mich etwas schwer damit den Code zu lesen

artikel

id [PK] | Name |
1 | Erdgas|
2 | Benzin |
3 | Diesel |

2. Tabelle

id [PK] | artikel | Zeitraum | Preis |
----1---- |---- 2--- |-----?----- | 1,48 |
----2----|---- 2--- |-----?----- | 1,48 |

Habe ich das so richtig dargestellt?

Ich habe folgende stellen im Code nicht verstanden :
artikel int references artikel


exclude using gist(artikel with =, zeitraum with &&));
 
das, was hinter dem # steht, sind meine Befehle. Der Rest sind Ausgaben der DB. Also z.B. wie lange es gedauert hat. References <tabelle> ist einfach nur die Definition eine Foreign Keys, das exclude using ... ist ein Exclude - Constraint, bei gleichem Artikel dürfen sich die Zeiträume nicht überschneiden. Das ist eine sehr coole Geschichte, solche Constraints - die aber derzeit (nach meinem Wissen) nur eine Datenbank dieser Welt kann - die 'Beste' halt ;-)
 
Das wäre ja eher ein Thema für Datenbankmodelierung denn ich glaube hier geht es weniger um die Praxis sondern mehr um die Theorie in der ersten Normalform. Wenn du sagst Datum und Zeit sollen atomar sein müsste man ja eigentlich Stunden, Minuten, Sekunden, Tag, Monat und Jahr in getrennten Atributen unterbringen. In der Praxis ist das Schwachsinn und mit DATETIME viel leichter, ich bin leider jetzt nicht so fit das ich sagen kann warum man das in der ersten Normalform zerlegen oder nicht zerlegen sollte.
 
Zwei Gründe warum man es nicht zerlegen sollte:
Im Sinne des Datentyps DATETIME ist dieser Wert atomar :)

Genauso wie die Zahl 20 auch im Sinne des Datentyps atomar ist, obwohl man Sie in 2 und 0 zerlegen kann.
Und ich hab noch keinen gesehn der statt Int(2) zwei Spalten Int(1) anlegt nur um die Zahlen wirklich atomar zu haben ;)
(Das ist erstmal aus reiner Datenbank-Sicht)

Im Sinne der Aufgabe ist eine Zeitangabe auch atomar.
D.h. eine Zeitangabe (Timestamp) soll einen bestimmten Moment am Tag darstellen... Und das ist nur so, wenn sämtliche Informationen zusammen in einer Spalte stehen :)
Das verhält sich genauso mit einem Datum, einer Datei (Beliebiger Byte-Datentyp einfügen), Bildern (In MS SQL gibt es glaube ich den Image-Datentyp?) ... usw.

D.h. man hat quasi zwei Sichten aus der man "atomar" betrachten sollte:
- Was bietet mir die Datenbank ?
- Was will ich eigentlich abbilden?
 
Werbung:
Hier vllt. mal ein Anfang:
Ist noch kein fertiges Modell... Ich kenne auch keine genaueren Anforderungen... Sollte aber trotzdem eine Stabile Grundlage bilden...
(Dein Anwender-Geraffel hab ich mal dezent entfernt... Wozu meldet man sich denn an der Datenbank an? Bestimmt nicht um sich dann nochmal an der Applikation anzumelden ;) Die Datenbank ist die Basis - deine Applikation baut darauf auf... Solange es keinen triftigen Grund dagegen gibt, nimm einfach den User der Datenbank)

Vllt. noch als kleine Anmerkung: Oracle-Syntax... Es soll ja sowieso nur eine Idee geben :)
Code:
Create Table cities_tab
(
plz Varchar2(20)
,description Varchar2(50)

,Constraint cities_tab_pk Primary Key (plz)
);

Create Table fuel_tab
(
fuel_id Integer
,description Varchar2(30)

,Constraint fuel_tab_pk Primary Key (fuel_id)
);

Create Table person_tab
(
person_id Integer
,title Varchar2(50)
,first_name Varchar2(50)
,additional_name Varchar2(1000) -- Zusatznamen hatten für mich bis jetzt immer nur rein informativen Wert... Deswegen sind die hier zusammengefasst.
                                -- Wenn man sie braucht, sollte man eine eigene Tabelle anlegen
,last_name Varchar2(200)
,plz Varchar2(20)
,street Varchar2(50)
,house_number Varchar2(10)

,Constraint person_tab_pk Primary Key (person_id)
,Constraint person_tab_fk_01 Foreign Key (plz) References cities_tab (plz)
);

Create Table cars_tab
(
car_id Integer
,description Varchar2(200)
,fuel_id Integer
-- technische Informationen hier...

,Constraint car_tab_pk Primary Key (car_id)
,Constraint car_tab_fk_01 Foreign Key (fuel_id) References fuel_tab(fuel_id)
);

Create Table cars_per_person_tab
(
person_id Integer
,car_id Integer

,Constraint cars_per_person_tab_pk Primary Key (person_id, car_id) -- Oder (car_id, person_id)... Kommt auf die Abfragen an die du später haben willst
,Constraint cars_per_person_tab_fk_01 Foreign Key (person_id) References person_tab(person_id)
,Constraint cars_per_person_tab_fk_02 Foreign Key (car_id) References cars_tab(car_id)
,Constraint cars_per_person_tab_uk_01 Unique (car_id) -- Jedes Auto kann nur einen Besitzer haben
);

Create Table fuel_price_tab
(
fuel_id Integer
,valid_from Date
,price Number

,Constraint fuel_price_tab_pk Primary Key (fuel_id, valid_from)
);

Create Table fuel_usage_tab
(
car_id
,entry_date Date -- Verbrauch wird hier erstmal pro Tag hinterlegt (bzw. eher verbrauchte Menge X und zurückgelegte Strecke y)
,used_fuel Number
,travelled Number
,travelled_unit Integer -- Hier müsste dann wieder eine Referenztabelle für Einheiten her... Ich hab aber keine Lust mehr :P
,average_per_day Number Generated Always As (used_fuel * 100 / travelled) Virtual -- virtuelle Spalte, die den Durchschnittlichen Verbrauch für diesen Tag beinhaltet (derzeit pro hundert Einheiten)

,Constraint fuel_usage_tab_pk Primary Key (car_id, entry_date)
,Constraint fuel_usage_tab_fk_01 Foreign Key (car_id) References cars_tab(car_id)
);

Create View average_fuel_usage As
-- ... Hier käme dann die View, die dir den Verbrauch so berechnet wie du ihn haben willst
 
Zuletzt bearbeitet von einem Moderator:
Zurück
Oben