Verwalten einer einzelnen Information
Angenommen, in Ihrer Geschäftsdomäne
- Ein Benutzer kann null, eins oder viele Freunde haben .
- Ein Freund muss zuerst als Benutzer registriert sein . und
- Sie werden nach einzelnen Werten einer Freundesliste suchen und / oder diese hinzufügen und / oder entfernen und / oder ändern .
dann repräsentiert jedes spezifische Datum, das in der Friendlist_IDs
mehrwertigen Spalte gesammelt wird, eine separate Information , die eine sehr genaue Bedeutung hat. Daher die Spalte
- beinhaltet eine geeignete Gruppe expliziter Einschränkungen, und
- Seine Werte können durch mehrere relationale Operationen (oder Kombinationen davon) individuell manipuliert werden.
Kurze Antwort
Folglich sollten Sie jeden der Friendlist_IDs
Werte in (a) einer Spalte beibehalten , die ausschließlich einen einzigen Wert pro Zeile in (b) einer Tabelle akzeptiert, die den Assoziationstyp auf konzeptioneller Ebene darstellt , der zwischen Benutzern stattfinden kann , dh eine Freundschaft - wie Ich werde in den folgenden Abschnitten veranschaulichen -.
Auf diese Weise werden Sie in der Lage zu handhaben (i) die Tabelle als eine mathematische Beziehung und (ii) die Säule als eine mathematische Beziehung Attribut -wie viel wie MySQL und seine SQL - Dialekt erlauben, von Kurs-.
Warum?
Da das von Dr. E. F. Codd erstellte relationale Datenmodell Tabellen erfordert, die aus Spalten bestehen, die genau einen Wert der zutreffenden Domäne oder des jeweiligen Typs pro Zeile enthalten. Daher stellt die Deklaration einer Tabelle mit einer Spalte, die mehr als einen Wert der betreffenden Domäne oder des fraglichen Typs (1) enthalten kann, keine mathematische Beziehung dar und (2) würde es nicht ermöglichen, die im oben genannten theoretischen Rahmen vorgeschlagenen Vorteile zu erzielen.
Modellieren von Freundschaften zwischen Benutzern : Definieren Sie zuerst die Regeln für die Geschäftsumgebung
Ich empfehle dringend, eine Datenbank zu erstellen, die - vor allem - das entsprechende konzeptionelle Schema aufgrund der Definition der relevanten Geschäftsregeln abgrenzt , die unter anderem die Arten von Wechselbeziehungen beschreiben müssen, die zwischen den verschiedenen interessierenden Aspekten bestehen, d. H. , die anwendbaren Entitätstypen und ihre Eigenschaften ; z.B:
- Ein Benutzer wird hauptsächlich durch seine Benutzer- ID identifiziert
- Ein Benutzer wird abwechselnd durch die Kombination seines Vornamens , Nachnamens , Geschlechts und Geburtsdatums identifiziert
- Ein Benutzer wird abwechselnd durch seinen Benutzernamen identifiziert
- Ein Benutzer ist der Antragsteller von null-eins-oder-vielen Freundschaften
- Ein Benutzer ist der Adressat von null, eins oder vielen Freundschaften
- Eine Freundschaft wird hauptsächlich durch die Kombination ihrer RequesterId und ihrer AddresseeId identifiziert
Expository IDEF1X-Diagramm
Auf diese Weise konnte ich das in Abbildung 1 gezeigte IDEF1X 1- Diagramm ableiten , das die meisten zuvor formulierten Regeln integriert:
Wie dargestellt, sind Anforderer und Adressat Bezeichnungen, die die Rollen ausdrücken, die von den spezifischen Benutzern ausgeführt werden , die an einer bestimmten Freundschaft teilnehmen .
Unter diesen Umständen zeigt der Entitätstyp " Freundschaft" einen Assoziationstyp mit einem Kardinalitätsverhältnis von vielen zu vielen (M: N), der verschiedene Vorkommen desselben Entitätstyps, dh Benutzer, umfassen kann . Als solches ist es ein Beispiel für das klassische Konstrukt, das als "Stückliste" oder "Teileexplosion" bekannt ist.
1 Integration Definition für Information Modeling ( IDEF1X ) ist eine sehr empfehlenswerte Technikdie als etabliert wurde Standard im Dezember 1993 von der US National Institute of Standards and Technology (NIST). Es basiert fest auf (a) dem frühen theoretischen Material, das vom alleinigen Urheber des relationalen Modells verfasst wurde, dh Dr. EF Codd ; zu (b) dervon Dr. PP Chen entwickelten Entity-Relationship- Ansicht von Daten; und auch auf (c) der Logical Database Design Technique, erstellt von Robert G. Brown.
Illustratives logisches SQL-DDL-Design
Aus dem oben dargestellten IDEF1X-Diagramm ist es dann viel „natürlicher“, eine DDL-Anordnung wie die folgende zu deklarieren:
-- You should determine which are the most fitting
-- data types and sizes for all the table columns
-- depending on your business context characteristics.
-- At the physical level, you should make accurate tests
-- to define the mostconvenient INDEX strategies based on
-- the pertinent query tendencies.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE UserProfile ( -- Represents an independent entity type.
UserId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
BirthDate DATE NOT NULL,
GenderCode CHAR(3) NOT NULL,
Username CHAR(20) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
FirstName,
LastName,
GenderCode,
BirthDate
),
CONSTRAINT UserProfile_AK2 UNIQUE (Username) -- Single-column ALTERNATE KEY.
);
CREATE TABLE Friendship ( -- Stands for an associative entity type.
RequesterId INT NOT NULL,
AddresseeId INT NOT NULL, -- Fixed with a well-delimited data type.
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Friendship_PK PRIMARY KEY (RequesterId, AddresseeId), -- Composite PRIMARY KEY.
CONSTRAINT FriendshipToRequester_FK FOREIGN KEY (RequesterId)
REFERENCES UserProfile (UserId),
CONSTRAINT FriendshipToAddressee_FK FOREIGN KEY (AddresseeId)
REFERENCES UserProfile (UserId)
);
In dieser Mode:
- Jede Basistabelle repräsentiert einen einzelnen Entitätstyp.
- Jede Spalte steht für eine alleinige Eigenschaft des jeweiligen Entitätstyps.
- Für jede Spalte wird ein bestimmter Datentyp a festgelegt , um sicherzustellen, dass alle darin enthaltenen Werte zu einer bestimmten und genau definierten Menge gehören , sei es INT, DATETIME, CHAR usw.; und
- Mehrere Einschränkungen b werden (deklarativ) konfiguriert, um sicherzustellen, dass die Zusicherungen in Form von Zeilen, die in allen Tabellen beibehalten werden , den im konzeptionellen Schema festgelegten Geschäftsregeln entsprechen.
Vorteile einer einwertigen Spalte
Wie gezeigt, können Sie z.
Nutzen Sie die referenzielle Integrität, die vom Datenbankverwaltungssystem (DBMS für die Kürze) für die Friendship.AddresseeId
Spalte erzwungen wird , da die Einschränkung als AUSLÄNDISCHER SCHLÜSSEL (FK für die Kürze), der auf die UserProfile.UserId
Spalte verweist, garantiert, dass jeder Wert auf eine vorhandene Zeile verweist .
Erstellen Sie einen zusammengesetzten PRIMARY KEY (PK), der aus der Kombination von Spalten besteht (Friendship.RequesterId, Friendship.AddresseeId)
und dabei hilft, alle eingefügten Zeilen elegant zu unterscheiden und natürlich ihre Eindeutigkeit zu schützen .
Dies bedeutet natürlich, dass das Anhängen einer zusätzlichen Spalte für vom System zugewiesene Ersatzwerte (z. B. eine Spalte, die mit der IDENTITY- Eigenschaft in Microsoft SQL Server oder mit dem AUTO_INCREMENT- Attribut in MySQL eingerichtet wurde) und dem unterstützenden INDEX völlig überflüssig ist .
Beschränken Sie die beibehaltenen Werte Friendship.AddresseeId
auf einen genauen Datentyp c (der z. B. dem für UserProfile.UserId
INT festgelegten Datentyp entsprechen sollte ), damit das DBMS die entsprechende automatische Validierung übernimmt .
Dieser Faktor kann auch dazu beitragen, (a) die entsprechenden integrierten Typfunktionen zu nutzen und (b) die Speicherplatznutzung zu optimieren.
Optimieren Daten Retrieval auf der physikalischen Ebene durch die Konfiguration kleinen und schneller untergeordneten Indizes für die Friendship.AddresseeId
Spalte, da diese physikalischen Elemente im wesentlichen durch in unterstützen die Beschleunigung der Abfragen , die Spalte sagte beinhalten.
Natürlich können Sie beispielsweise einen einspaltigen INDEX für sich Friendship.AddresseeId
allein erstellen , einen mehrspaltigen, der Friendship.RequesterId
und Friendship.AddresseeId
oder beides umfasst.
Vermeiden Sie die unnötige Komplexität, die durch das „Suchen“ nach bestimmten Werten entsteht, die in derselben Spalte zusammengefasst sind (sehr wahrscheinlich dupliziert, falsch eingegeben usw.). Diese Vorgehensweise würde möglicherweise die Funktion Ihres Systems verlangsamen, weil Sie dies tun würden müssen auf ressourcen- und zeitaufwändige nicht relationale Methoden zurückgreifen, um diese Aufgabe zu erfüllen.
Es gibt mehrere Gründe, die eine sorgfältige Analyse des relevanten Geschäftsumfelds erfordern, um den Typ d jeder Tabellenspalte genau zu kennzeichnen .
Wie bereits erläutert, ist die Rolle des Datenbankdesigners von größter Bedeutung, um (1) die Vorteile des relationalen Modells auf logischer Ebene und (2) die vom DBMS der Wahl bereitgestellten physikalischen Mechanismen optimal zu nutzen .
a , b , c , d Offensichtlich können Sie bei der Arbeit mit SQL-Plattformen (z. B. Firebird und PostgreSQL ), die die DOMAIN-Erstellung unterstützen (eine besondere relationale Funktion), Spalten deklarieren, die nur Werte akzeptieren, die zu ihren jeweiligen gehören (entsprechend eingeschränkt und manchmal) geteilt) DOMAINs.
Ein oder mehrere Anwendungsprogramme, die die betreffende Datenbank gemeinsam nutzen
Wenn Sie arrays
den Code der Anwendungsprogramme verwenden müssen, die auf die Datenbank zugreifen, müssen Sie lediglich die relevanten Datensätze vollständig abrufen und sie dann an die betreffende Codestruktur „binden“ oder ausführen zugehörige App-Prozesse, die stattfinden sollen.
Weitere Vorteile einwertiger Spalten: Datenbankstrukturerweiterungen sind viel einfacher
Ein weiterer Vorteil des Haltens des AddresseeId
Datenpunkts in seiner reservierten und ordnungsgemäß typisierten Spalte besteht darin, dass die Erweiterung der Datenbankstruktur erheblich erleichtert wird, wie ich weiter unten veranschaulichen werde.
Fortschreiten des Szenarios: Einbeziehung des Friendship Status- Konzepts
Da sich Freundschaften im Laufe der Zeit entwickeln können, müssen Sie möglicherweise ein solches Phänomen im Auge behalten. Daher müssten Sie (i) das konzeptionelle Schema erweitern und (ii) einige weitere Tabellen im logischen Layout deklarieren. Lassen Sie uns also die nächsten Geschäftsregeln festlegen, um die neuen Eingliederungen abzugrenzen:
- Eine Freundschaft enthält eins zu viele FriendshipStatuses
- Ein FriendshipStatus wird hauptsächlich durch die Kombination seiner RequesterId , seiner AddresseeId und seiner SpecifiedDateTime identifiziert
- Ein Benutzer gibt null, eins oder viele FriendshipStatuses an
- Ein Status klassifiziert null, eins oder viele FriendshipStatuses
- Ein Status wird hauptsächlich durch seinen StatusCode identifiziert
- Ein Status wird abwechselnd durch seinen Namen identifiziert
Erweitertes IDEF1X-Diagramm
Nacheinander kann das vorherige IDEF1X-Diagramm erweitert werden, um die oben beschriebenen neuen Entitätstypen und Wechselbeziehungstypen einzuschließen. Ein Diagramm mit den vorherigen Elementen, die den neuen Elementen zugeordnet sind, ist in Abbildung 2 dargestellt :
Logische Strukturergänzungen
Anschließend können wir das DDL-Layout mit den folgenden Deklarationen verlängern:
--
CREATE TABLE MyStatus ( -- Denotes an independent entity type.
StatusCode CHAR(1) NOT NULL,
Name CHAR(30) NOT NULL,
--
CONSTRAINT MyStatus_PK PRIMARY KEY (StatusCode),
CONSTRAINT MyStatus_AK UNIQUE (Name) -- ALTERNATE KEY.
);
CREATE TABLE FriendshipStatus ( -- Represents an associative entity type.
RequesterId INT NOT NULL,
AddresseeId INT NOT NULL,
SpecifiedDateTime DATETIME NOT NULL,
StatusCode CHAR(1) NOT NULL,
SpecifierId INT NOT NULL,
--
CONSTRAINT FriendshipStatus_PK PRIMARY KEY (RequesterId, AddresseeId, SpecifiedDateTime), -- Composite PRIMARY KEY.
CONSTRAINT FriendshipStatusToFriendship_FK FOREIGN KEY (RequesterId, AddresseeId)
REFERENCES Friendship (RequesterId, AddresseeId), -- Composite FOREIGN KEY.
CONSTRAINT FriendshipStatusToMyStatus_FK FOREIGN KEY (StatusCode)
REFERENCES MyStatus (StatusCode),
CONSTRAINT FriendshipStatusToSpecifier_FK FOREIGN KEY (SpecifierId)
REFERENCES UserProfile (UserId)
);
Folglich müssten die Benutzer jedes Mal, wenn der Status einer bestimmten Freundschaft auf den neuesten Stand gebracht werden muss, nur eine neue Zeile einfügen , die Folgendes enthält:FriendshipStatus
die geeigneten RequesterId
und AddresseeId
Werte - entnommen aus der betreffenden Friendship
Zeile -;
der neue und bedeutungsvolle StatusCode
Wert - gezogen von MyStatus.StatusCode
-;
der genaue INSERTion-Zeitpunkt, dh - SpecifiedDateTime
vorzugsweise mithilfe einer Serverfunktion, damit Sie sie zuverlässig abrufen und aufbewahren können -; und
Der SpecifierId
Wert, der den jeweiligen Wert angibt, der UserId
das Neue FriendshipStatus
in das System eingegeben hat - idealerweise mithilfe Ihrer App-Funktionen.
Nehmen wir insofern an, dass die MyStatus
Tabelle die folgenden Daten enthält - mit PK-Werten, die (a) Endbenutzer-, App-Programmierer- und DBA-freundlich und (b) klein und schnell in Bezug auf Bytes auf der Ebene der physischen Implementierung sind -:
+ -——————————- + -—————————- +
| StatusCode | Name |
+ -——————————- + -—————————- +
| R | Angefordert |
+ ------------ + ----------- +
| A | Akzeptiert |
+ ------------ + ----------- +
| D | Abgelehnt |
+ ------------ + ----------- +
| B | Bloqued |
+ ------------ + ----------- +
Die FriendshipStatus
Tabelle kann also Daten wie unten gezeigt enthalten:
+ - ———- + -——————————- + -———————————- +
| RequesterId | AddresseeId | SpecifiedDateTime | StatusCode | SpecifierId |
+ - ———- + -——————————- + -———————————- +
| 1750 | 1748 | 2016-04-01 16: 58: 12.000 | R | 1750 |
+ ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
| 1750 | 1748 | 2016-04-02 09: 12: 05.000 | A | 1748 |
+ ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
| 1750 | 1748 | 2016-04-04 10: 57: 01.000 | B | 1750 |
+ ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
| 1750 | 1748 | 2016-04-07 07: 33: 08.000 | R | 1748 |
+ ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
| 1750 | 1748 | 2016-04-08 12: 12: 09.000 | A | 1750 |
+ ------------- + ------------- + --------------------- ---- + ------------ + ------------- +
Wie Sie sehen können, kann gesagt werden, dass die FriendshipStatus
Tabelle dem Zweck dient, eine Zeitreihe zu umfassen .
Relevante Beiträge
Sie könnten genauso gut interessiert sein an:
- Diese Antwort, in der ich eine grundlegende Methode vorschlage, um mit einer gemeinsamen Viele-zu-Viele-Beziehung zwischen zwei unterschiedlichen Entitätstypen umzugehen.
- Das in Abbildung 1 gezeigte IDEF1X-Diagramm, das diese andere Antwort veranschaulicht . Achten Sie besonders auf die Entitätstypen " Ehe" und " Nachkommen" , da dies zwei weitere Beispiele für den Umgang mit dem "Teileexplosionsproblem" sind.
- Dieser Beitrag enthält eine kurze Überlegung zum Speichern verschiedener Informationen in einer einzelnen Spalte.