Datenbankschema zur Kontaktverwaltung

hankTank

Grünschnabel
Hallo zusammen,

ich plane derzeit ein Datenbankschema das u.a. Kontaktdaten verwalten soll.

Ein Datensatz sieht folgendermaßen aus:
(1)Firstname
(1)Lastname
(1-n)EmailAddresses
(0-n)PhoneNumbers
(1)Street
(1)City

Zu jedem Datum sollte eine 'visibility (public, protected, private)' hinterlegt werden.
Normalerweise würde ich alle Felder mit Multiplizität != 1 in eine extra Tabelle auslagern.
Problematisch wird das jedoch durch die das Attribut Visibility.
Das Schema würde dann in etwa so aussehen:

Code:
Tabelle Contact: 	
[Firstname][Firstname_visibility][Lastname][Lastname_visibility]...[EmailAddressFK][PhoneNumberFK]

Tabelle Emails: 	
[EmailAddress][Visibility]

Tabelle Phone:		
[PhoneNumber][Visibility]

Nicht wirklich schön... daher würde ich folgendes bevorzugen:

Code:
Tabelle Contact:

[Id]	[ContactId]	[TYPE]	[VALUE]		[VISIBILITY]
1	a		EMAIL	xy@xy.de	protected
2	a		EMAIL	xy@ab.de	public
3	a		LNAME	xy		private
4	a		FNAME	ab		private
5	a		STREET...

Das ist aber auch nicht das, was die klassische Datenbanktheorie lehrt.
Zudem wird die BL bzgl. Überprüfung der (Multiplizitäten)Constraints relativ komplex, ungefähr so:

Code:
addContact(Contact aContact){

	for(Iterator it = contacts.iterator();it.hasNext();){
		Contact tmpContact = (Contact)it.next()

		if(tmpContact.getType==LNAME)
			throw new IllegalArgumentException("only one lname per person");


		//...
	}

	contacts.add(aContact);
}

Ich bin nicht so tief im Datenbankdesign.
Kennt jemand einen anderen Weg wie man das Schema aufbauen könnte. Vielen Dank.
 
Hallo,

bei deinem ersten Vorschlag gehören die FKs eher in die Tabellen Emails und Phone, ansonsten sehe ich da kein Problem. Was stört dich denn an diesem Schema?

Grüße,
Matthias
 
Hallo Matthias,

danke für die schnelle Antwort. Stimmt natürlich mit den FKs.
Ich habe eigentlich das zweite Schema bevorzugt, weil es meiner Meinung flexibler ist:

- Die Datenbankstruktur müsste nicht geändert werden, falls z.B. irgendwann ein Attribut 'region' hinzukommt.
- null-Einträge könnten vermieden werden, falls sich z.B. herausstellt, dass 'city' optional (Multiplizität 0-1) sein soll.

Das Problem ist wie so oft: der Kunde kennt seine Anforderungen nicht, dementsprechend vage ist die Formulierung. Trotzdem muss begonnen werden zu entwickeln, um die Termine halten zu können. Das Schema sollte daher natürlich möglichst flexibel sein.
Sorry habe das mit der Flexibilität vorher nicht erwähnt.

Außerdem fand ich es doch etwas seltsam ein Spalte 'Visibility' für jedes Datum anzulegen. Ich bin mir nicht sicher, ob das Best Practice ist.

Gruß
Marco
 
Ich habe eigentlich das zweite Schema bevorzugt, weil es meiner Meinung flexibler ist:

- Die Datenbankstruktur müsste nicht geändert werden, falls z.B. irgendwann ein Attribut 'region' hinzukommt.
- null-Einträge könnten vermieden werden, falls sich z.B. herausstellt, dass 'city' optional (Multiplizität 0-1) sein soll.

Das Problem ist wie so oft: der Kunde kennt seine Anforderungen nicht, dementsprechend vage ist die Formulierung. Trotzdem muss begonnen werden zu entwickeln, um die Termine halten zu können. Das Schema sollte daher natürlich möglichst flexibel sein.
Sorry habe das mit der Flexibilität vorher nicht erwähnt.
Stimmt natürlich, das ist mir nach dem Abschicken meines Beitrags dann auch noch eingefallen.

Ein elegantes Schema zu diesem Problem hab ich aber leider auch nicht parat. Deine zweite Idee krankt an der Umsetzung der Constraints, wie du schon erwähnt hast. Man könnte natürlich für die Attribute, die jeder Contact nur einmal haben soll, eine extra Tabelle anlegen und dann einen Unique-Constraint auf ContactId und Type legen, aber besonders schön ist das auch nicht. Auf Flexibilität in Bezug auf sich ändernde Multiplizitäten sind relationale Datenbanken an sich eben nicht ausgelegt…

Grüße,
Matthias
 
Ja, das ist irgendwie alles bißchen problematisch. Ich denke ich komme nicht darum herum alles flexibel zu halten.
Was mache ich wenn plötzlich noch Kontaktdaten wie IPPone oder MobilePhone hinzukommen sollten. (Was durchaus denkbar wäre.)
Spätestens dann müsste ich auch in der Tabelle 'Phone' ein Type-Feld (Enum: PHONE, MOBILE, IPPHONE) einführen.
Dann kann ich auch gleich alles in eine Tabelle (wie in dem zweiten Schema) auslagern.
Evtl. könnte man die Constraint-Überprüfung mit Hibernates NamedQueries etwas verschlanken.

Ich werde eine Nacht drüber schlafen und mir das mit den extra Tabellen nochmal überlegen. Aber das würde schon recht umfangreich werden -
und ich weiß nicht, ob bei Abfragen über so viele Tabellen nicht die Performance leidet.
Trotzdem schonmal vielen Dank für Deine Hilfe.

Ich frage mich nur wie das andere machen. Das Problem an sich ist ja nicht so ungewöhnlich. Es gibt genügend Web-Plattformen, die die Sichtbarkeit von Kontaktdaten auf bestimmte Nutzergruppen einschränken.
Haben die alle Kontaktfelder fest in die Datenbank gegossen und wenn einmal z.B. ein Instant Messenger Protokoll hinzukommt wird die Datenbank neu aufgesetzt?

Gruß
Marco
 
Ich habe nicht viel Erfahrung mit Db-Design, aber wie wäre es hiermit?

Code:
Tabelle Kontakt:
[Kontakt_Id][Firstname][Lastname][Street][City]

Code:
Tabelle Kontaktmoeglichkeiten:
[Kontakt_Id][Typ][Inhalt]

[Typ] gibt hier an ob es eine Emailadresse, eine Telefonnummer oder sonst etwas ist.

Code:
Tabelle Visible:
[Kontakt_Id][Visi_First][Visi_Last][Visi_Street][Visi_City][Visi_Typ1][Visi_Typ2] etc.

Das wäre meine erste Möglichkeit, wenn alle Einträge eines Typs die gleiche Sichtbarkeit haben.
Sollte dies nicht der Fall sein, so würde ich die Sichtbarkeit für die Kontaktmöglichkeiten direkt in der Tabelle speichern.
Dieses Design ist auch sehr flexibel im Bezug auf Erweiterungen der Kontaktmöglichkeiten.

Ich würde mich sehr über eine Rückmeldung freuen, vor allem wenn dieses Design irgendwelche Denkfehler oder ähnliches enthält. Ich lerne ja noch.
Sonst wünsche ich noch einen netten Abend.
Dunas
 
Hallo Dunas,

die Idee an sich ist gut. Ich habe mir auch schon überlegt die Visibility in eine extra Tabelle "Config" oder eben "Visibility" auszulagern. Das Problem dabei ist, dass bestimmte Kontaktmöglichkeiten eine Multiplizität > 1 haben und dass ...

...wenn alle Einträge eines Typs die gleiche Sichtbarkeit haben.

... leider nicht der Fall ist.


Sollte dies nicht der Fall sein, so würde ich die Sichtbarkeit für die Kontaktmöglichkeiten direkt in der Tabelle speichern.

Wenn ich es richtig verstanden habe, wäre das gleich wie mein zweites Schema?

Gruß
Marco
 
Habe ich mir doch gedacht, dass es nicht so einfach ist.
Wenn jede Kontaktmöglichkeit ihre eigene Visibleeinstellung hat, dann würde ich deine erste Idee nehmen und nur die Tabellen "Email" und "Phone" zu einer Tabelle "Kontaktmöglichkeiten" zusammenfügen. Damit du weiter sehr flexibel auf neue Kontatkmöglichkeiten reagieren kannst.
 
Zurück