Antworten auf Ihre individuellen Fragen
Wenn ich eine Spalte hinzufügen möchte Club
, die den Eigentümer beschreibt, der auch Mitglied sein wird, was ist der beste Ansatz, ohne dass dasselbe Mitglied zweimal aufgeführt wird?
Wenn Sie - wie in Ihren Spezifikationen angegeben a Person can be a Member of only one Club
- daran interessiert sind, dieses Datum einfach als wahr oder falsch zu speichern , können Sie der Tabelle eine BIT(1)
oder eine BOOLEAN
( TINYINT
) -Spalte hinzufügen Person
, und Sie möchten diese Spalte möglicherweise aufrufen IsClubOwner
. Auf diese Weise können Sie die Tatsache registrieren , dass eine bestimmte Person ist ein Clubbesitzer ausschließlich einmal. Abgesehen davon , dass diese Methode ermöglicht es auch die Möglichkeit der Beibehaltung mehr Personen als Inhaber des gleichen Club Auftreten. Sie können eine logische Darstellung dieses Ansatzes in Abbildung 1 sehen .
Sie suchen jedoch nach dem besten Ansatz, und meiner Erfahrung nach beinhaltet ein solcher Ansatz die Entwicklung einer viel erweiterbareren und vielseitigeren Struktur. Befolgen Sie in diesem Zusammenhang den Verlauf einer Modellierungsübung für diese und andere Punkte in den Abschnitten "Abdecken Ihrer verbleibenden Spezifikationen", "Person als Mitglied mehrerer Clubs" und "Mitglied und Eigentümer als separate Entitätstypen".
Sollte ich alle meine Tabellen automatisch inkrementieren id
oder wäre dies eine schlechte Idee? (Vorteile / Nachteile?)
Wenn Sie einer expliziten Anforderung gegenüberstehen, die die Definition einer Tabelle mit einer Spalte mit solchen Merkmalen angibt und diese Spalte eine gültige Kontextbedeutung hat oder einem bestimmten Zweck dient, z. B. als Ersatz für einen breiten natürlichen PRIMARY KEY (PK), dann ja, Sie sollten so vorgehen.
Andernfalls halte ich es für unnötig , wenn Sie diese Anforderung nicht angegeben haben, da Sie eine bedeutungslose zusätzliche Spalte und (möglicherweise?) Auch einen zusätzlichen INDEX in Ihrer Datenbank speichern und verwalten müssen .
Wie üblich müssen Sie jeden Fall zusammen mit seinen allgemeinen Auswirkungen analysieren, um zu entscheiden, wie Sie fortfahren möchten.
Wenn ich auf der Registerkarte Fremdschlüssel Fremdschlüssel hinzufüge, entsprechen diese automatisch der richtigen Tabelle oder muss ich diese auch zu den Spalten hinzufügen?
In diesem Zusammenhang rate ich Ihnen, Ihre Datenbankstruktur manuell zu erstellen und Ihre eigenen DDL
Anweisungen zu codieren , bis Sie das Thema richtig verstanden haben. Wenn Sie dies tun, können Sie die Prozesse, die grafische Tools „unter der Haube“ ausführen, leichter verstehen.
Für mich zum Beispiel, eine Aussage wie die folgende zu erstellen:
CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)
Ist viel lehrreicher als die Verwendung von GUI-Tools, um diese Art von Aufgaben auszuführen, insbesondere jetzt, wo Sie Ihre ersten Entwürfe erstellen.
Und meine wahrscheinlich noobiest Frage von allen ... Platziere ich die Fremdschlüssel von phone_number
und email
in ihrer jeweiligen Tabelle, die mit einem verknüpft sind, person_id
oder sollte ich phone_number
und email
ids
in die Personentabelle setzen?
Persönlich denke ich, dass diese und alle Ihre anderen Fragen vollständig gültig und gut kontextualisiert sind .
Um auf die technischen Aspekte zurückzukommen, die uns betreffen, bietet diese genaue Untersuchung eine gute Gelegenheit, die beiden folgenden Behauptungen zu überprüfen:
A Person can be reached through zero-one-or-many PhoneNumbers
A PhoneNumber can be used to reach one-to-many People
So kann man schließen , dass es eine viele-zu-viele - Beziehung zwischen Person
und PhoneNumber
deshalb schlage ich vor , die Schaffung eines assoziativen Tabelle namens PersonPhoneNumber
auf die Beziehung in der Datenbank zu repräsentieren. Die PK dieser Tabelle sollte aus zwei verschiedenen Spalten bestehen: PersonId
(ein AUSLÄNDISCHER SCHLÜSSEL [FK], auf den verwiesen wird Person.PersonId
) und PhoneNumber
(ein FK, auf den verwiesen wird PhoneNumber.Number
). Eine Beschreibung aller oben genannten Punkte auf logischer Ebene finden Sie in Abbildung 1 .
Lassen Sie uns andererseits die beiden folgenden Sätze untersuchen:
A Person can be contacted via zero-one-or-many EmailAddresses
An EmailAddress can be used to contact exactly one Person
Dann sollten Sie eine FK-Referenzierung in Person
der EmailAddress
Tabelle festlegen , und diese Tabelle sollte auch eine zusammengesetzte PK enthalten, die aus den Spalten PersonId
und besteht Address
. Auf diese Weise können Sie sicherstellen, dass dieselbe Kombination von EmailAddress.PersonId
und EmailAddress.Address
nur einmal eingefügt werden kann.
Wenn Sie auch sicherstellen möchten, dass eine bestimmte EmailAddres.Address
Zeile in einer einzigen Zeile gespeichert werden kann, müssen Sie nur eine EINZIGARTIGE BESCHRÄNKUNG für diese Spalte festlegen .
Vorgeschlagene logische Datenmodelle
Um meine Vorschläge klarer darzustellen , habe ich vier verschiedene logische IDEF1X [1] -Modelle aufgenommen, die in Abbildung 1 , Abbildung 2 , Abbildung 3 und Abbildung 4 dargestellt sind . In den entsprechenden Abschnitten werde ich die wichtigsten Funktionen erläutern, die in den einzelnen Funktionen angezeigt werden. Sie können auch ein PDF von Dropbox herunterladen, das die meisten der diskutierten Elemente in ein einziges Modell integriert.
Deckt Ihre verbleibenden Spezifikationen ab
Personen und Adressen in Beziehung setzen
Lassen Sie uns die beiden folgenden (leicht umformulierten) Aussagen untersuchen, die für Personen und Adressen relevant sind :
A Person can only have one Address
An Address can belong to different People (couples or siblings)
Um diese Einschränkungen zu umgehen, können Sie ein Datenmodell implementieren, das dem in Abbildung 1 gezeigten ähnelt .
Unter Berücksichtigung des angegebenen Modells sollten Sie die folgenden Schritte ausführen:
Erstellen Sie eine Tabelle mit dem Namen PersonAddress
Fixieren einer Beziehung zwischen Person
und Address
. Legen Sie die Spalten PersonId
und AddressId
als zusammengesetzte PK dieser Tabelle fest.
Konfigurieren Sie eine EINZIGARTIGE EINSCHRÄNKUNG für die PersonAddress.PersonId
Spalte, um sicherzustellen, dass ein bestimmter Wert in höchstens eine Zeile der Tabelle eingefügt werden kann. Auf der logischen Ebene impliziert dieser Umstand, dass er PersonAddress.PersonId
zu einem ALTERNATIVEN SCHLÜSSEL geworden ist [2] .
Wenn der Wert von AddressId
in einem bestimmten PersonAddress
Einfügeversuch noch nicht gespeichert wurde, lassen Sie die Einfügung fortgesetzt werden. Wenn dieser Wert bereits in einer Zeile vorhanden ist, müssen Sie überprüfen, ob (a) PersonId
derjenige, der sich registriert hat, AddressId
auch als registriert ist Marriage.WifeId
Wenn das PersonId
ein Mann ist (Datum abgeleitet über das Person.GenreCode
) oder (b), PersonId
ist das das, Marriage.HusbandId
wenn das PersonId
eine Frau ist (abgeleitet auch aufgrund von Person.GenreCode
). Wenn eine dieser Bedingungen in der entsprechenden Situation erfüllt ist, sollten Sie das INSERT fortsetzen.
Wenn die oben genannten Bedingungen nicht erfüllt sind, besteht immer noch die Möglichkeit, dass ein PersonAddress
Einfügungsversuch erfolgreich ist. Sie müssen überprüfen, ob der PersonId
Wert, der an dem Einfügungsversuch beteiligt ist, mindestens einen Progeny.ParentId
mit dem Wert teilt PersonId
, der den bereits registriert hat PersonAddress.AddressId
. Wenn diese Bedingung erfüllt ist, dann bedeutet es , dass sie gespeichert wie Siblings
in der Datenbank, so dass diese INSERT gelingen muss.
Wie bei jeder Implementierung einer relationalen Datenbank sollten Sie ernsthaft in Betracht ziehen, Ihre DML
Vorgänge in ACID-Transaktionen auszuführen , damit Sie die Integrität und Konsistenz der Daten, mit denen Sie arbeiten, schützen können .
Beachten Sie die Anforderungen, die Sie in den Kommentaren hinzugefügt haben: Adressen und Telefonnummern, die Clubs und Personen gleichermaßen dienen
Unter der Bedingung, dass Sie Adressen und Telefonnummern die Möglichkeit geben möchten, sowohl Personen als auch Clubs zu bedienen , können Sie eine Supertyp-Subtyp-Beziehung verwenden . Hier ist eine Antwort, in der ich diese Art von Strukturen detaillierter behandle, falls Sie interessiert sind.
Im vorliegenden Szenario könnten Sie einen Begriff definieren Person
und Club
als Untertypen einer neuen benannten Entität Party
einen Begriff verwenden, der in Rechtskreisen häufig verwendet wird, um für (a) eine Person oder (b) eine Gruppe von Personen zu stehen (wie in Sinn Nr. 6 angegeben ). Bei dieser Methode werden die Beziehungen zwischen Addresses
(oder PhoneNumbers
) und People
und Clubs
durch Party
den Supertyp definiert. In Abbildung 2 ist dieser Vorschlag dargestellt.
Party und Adresse
So können wir in diesem neuen Modell lesen, dass:
A Party keeps zero-one-or-many Addresses
An Address is kept by one-to-many Parties
Somit gibt es eine viele-zu-viele - Beziehung beteiligt Party
und Address
das ist durch die zum Ausdruck gebracht PartyAddress
Einheit.
Party und Telefonnummer
Darüber hinaus können wir das interpretieren:
A Party is reached through zero-one-or-many PhoneNumbers
A PhoneNumber is used by one-to-many Parties
Aus diesem Grund habe ich die PartyPhoneNumber
Entität hinzugefügt , die die Viele-zu-Viele-Zuordnung beschreibt, die zwischen den Entitätstypen Party
und wirksam wird PhoneNumber
.
Party und Club oder Person
Dann kann man auch lesen, dass:
A Party is either a Club or a Person
Liefert daher Party
eine Verbindung von entweder Clubs
oder People
nach Addresses
(oder PhoneNumbers
).
Person als Mitglied mehrerer Clubs
Als @aldwinaldwin mentiones in seiner Antwort, wenn Sie die Funktionalität für einen zur Verfügung stellen möchten Person ein sein Mitglied mehrerer Vereine , dann können Sie eine Tabelle enthalten genannt , ClubMember
dass als eine weitere many-to-many relaltionship handeln würde, diesmal natürlich , Verbinden Person
und Club
.
Ich möchte dem oben Gesagten hinzufügen, dass diese Tabelle auch nützlich sein kann, um eine konkrete Person als Eigentümer mehrerer Clubs zu speichern , indem die bereits erwähnte IsClubOwner
boolesche Spalte eingefügt wird. In der Tat kann man sagen, dass diese neue Tabelle die Darstellung eines eigenständigen integralen Entitätstyps ist.
Wie in gezeigt , Figur 3 erfordert eine solche Tabelle , die eine Verbund PK der Spalten aus ClubId
und MemberId
(einen Rollennamen [3] gegeben PersonId
), und diese Spalten auch als FKs zeigt, entsprechend festgelegt werden, zu Club
und Person
.
Eine anpassungsfähigere Struktur
Mit dieser Einstellung können Sie auch die ursprüngliche Regel einhalten, die dies besagt. a Person can be a member of only one Club
Sie müssen der MemberId
Spalte jedoch nur eine EINZIGARTIGE BESCHRÄNKUNG hinzufügen , damit ein bestimmter Wert nur einmal eingegeben werden kann. Wie Sie feststellen können, ist diese Struktur viel anpassungsfähiger als die in Abbildung 1 gezeigte , da Sie durch Löschen der EINZIGARTIGEN EINSCHRÄNKUNG (oder des INDEX) die oben genannte Funktionalität öffnen würden, die es einer Person ermöglicht, Mitglied verschiedener Clubs bei der zu werden gleiche Zeit.
Mitglied und Eigentümer als separate Entitätstypen
Wie Sie wissen, kann die Aufbewahrung mehrerer Fakten über die Rolle einer Person als Eigentümer eines Clubs - abgesehen von der bloßen Existenz eines wahren oder falschen Attributs - sehr vorteilhaft sein. Zum Beispiel können Sie das halten Zeitpunkt des Inkrafttretens , in dem eine bestimmte Person die sich Besitzer eines Club , daher können Sie diese Situation verwalten , indem eine separate Einheit Typ namens Einführung ClubOwner
, wie dargestellt in Abbildung 4 .
Sobald Sie eine Tabelle basierend auf diesem neuen Entitätstyp erstellt haben, können Sie die Anpassungsspalten hinzufügen, die die Merkmale darstellen, die ausschließlich dann ins Spiel kommen, wenn a Person
das Owner
von a ist Club
. Wie dargestellt, würde diese Tabelle eine PK enthalten, die aus den FK-Spalten besteht, auf die verwiesen wird, Person.PersonId
und auf Club.ClubId
diese Weise eine beliebige Kombination von ClubOwner.OwnerId
(oder ClubOwner.PersonId
, wenn Sie es vorziehen) und ClubOwner.ClubId
kann in nur einer Gelegenheit eingefügt werden.
Natürlich mit dieser Konfiguration können Sie immer noch in boolean Form ableiten , wenn ein Person
das ist Owner
eines bestimmten Club
mit Hilfe einer Abfrage , dass die Renditen einen skalaren Wert, der ausgewertet werden kann wahr oder falsch .
Anmerkungen
1. Die Integrationsdefinition für die Informationsmodellierung ( IDEF1X ) ist eine sehr empfehlenswerte Datenmodellierungstechnik , die im Dezember 1993 vom Nationalen Institut für Standards und Technologie ( NIST ) der Vereinigten Staaten als Standard definiert wurde . Es basiert fest auf (a) einigen theoretischen Arbeiten, die vom Urheber des relationalen Modells verfasst wurden , dh Dr. EF Codd ; zu (b) der von Dr. PP Chen entwickelten Entity-Relationship-Theorie ; und auch auf (c) der Logical Database Design Technique , erstellt von Robert G. Brown . Es ist erwähnenswert, dass IDEF1X warformalisiert durch Logik erster Ordnung .
2. Ein ALTERNATIVER SCHLÜSSEL ist ein Attribut (oder eine Kombination von Attributen), das Werte enthält, die ein Entitätsvorkommen eindeutig identifizieren, jedoch nicht als PK des entsprechenden Entitätstyps ausgewählt wurden. Jeder Entitätstyp kann null, einen oder mehrere ALTERNATE KEYS haben. In einem IDEF1X-Modell werden sie als "AK" plus ihrer jeweiligen Nummer angezeigt, z. B. AK1, AK2 usw. Sie werden normalerweise in einer SQL-DDL- Struktur über eine EINZIGARTIGE EINSCHRÄNKUNG (oder einen EINZIGARTIGEN INDEX ) implementiert .
3. Rollennamen sind Bezeichnungen (oder Aliase), die FK-Attributen zugewiesen werden, um die Bedeutung auszudrücken, die sie im Rahmen ihrer jeweiligen Entität haben. Ihre Verwendung wird seit 1970 von Dr. Codd in seinem wegweisenden Artikel mit dem Titel „Ein relationales Datenmodell für große gemeinsam genutzte Datenbanken“ empfohlen . Für seinen Teil, IDEF1X -keeping Treue hinsichtlich relationalen Practices - befürwortet auch Rolle Namensgebung.
clubId
Telefonnummer ein und lasse entweder den Club oder die Person auf null setzen?