Konzepte
Sie haben einige grundlegende Konzepte missverstanden, und daraus resultieren die Schwierigkeiten. Wir müssen uns zuerst mit den Konzepten befassen, nicht mit dem Problem, wie Sie es wahrnehmen, und folglich wird Ihr Problem verschwinden.
automatisch inkrementierte IDs, die natürlich Primärschlüssel sind.
Nein sind sie nicht. Das ist ein weit verbreiteter Irrglaube. Und Probleme sind garantiert.
Eine ID
Feld kann kein Primärschlüssel im englischen oder technischen oder relationalen Sinne sein.
-
Sicher, in SQL können Sie any deklarieren Feld als
PRIMARY KEY
, aber das verwandelt es nicht auf magische Weise in einen Primärschlüssel im englischen, technischen oder relationalen Sinne. Man kann einen Chihuahua „Rottweiller“ nennen, aber das macht ihn nicht zu einem Rottweiller, er bleibt ein Chihuahua. Wie jede Sprache führt SQL einfach die Befehle aus, die Sie ihm geben, es verstehtPRIMARY KEY
nicht um etwas Relationales zu bedeuten, schlägt es einfach einen eindeutigen Index auf die Spalte (oder das Feld). -
Das Problem ist, da Sie deklariert haben die
ID
einPRIMARY KEY
sein , denken Sie davon als Primärschlüssel, und Sie können erwarten dass es einige Qualitäten eines Primärschlüssels hat. Abgesehen von der Eindeutigkeit des ID-Werts , bringt es keinen Nutzen. Es hat keine der Qualitäten eines Primärschlüssels oder irgendeiner Art von relationalem Schlüssel für diese Angelegenheit. Es ist kein Schlüssel im englischen, technischen oder relationalen Sinne. Indem Sie einen Nicht-Schlüssel zu einem Schlüssel erklären, verwirren Sie sich nur selbst und finden erst heraus, dass etwas furchtbar falsch läuft, wenn sich der Benutzer über Duplikate in der Tabelle beschwert.
Relationale Tabellen müssen row haben Einzigartigkeit
Ein PRIMARY KEY
auf einer ID
Feld stellt keine Zeile bereit Einzigartigkeit. Daher ist es keine relationale Tabelle, die Zeilen enthält, und wenn dies nicht der Fall ist, dann ist es eine Datei, die Datensätze enthält. Sie hat nicht die Integrität oder Leistung (zu diesem Zeitpunkt werden Sie sich nur der Join-Leistung bewusst sein) oder Geschwindigkeit, die eine Tabelle in einer relationalen Datenbank hat.
Führen Sie diesen Code aus (MS SQL 2008) und überzeugen Sie sich selbst. Bitte lesen Sie dies nicht einfach und verstehen Sie es, und lesen Sie dann den Rest dieser Antwort, dieser Code muss ausgeführt werden, bevor Sie weiterlesen . Es hat heilenden Wert.
CREATE TABLE dumb_file (
id INT NOT NULL IDENTITY PRIMARY KEY,
name_first CHAR(30) NOT NULL,
name_last CHAR(30) NOT NULL
)
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds, but not intended
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds, but not intended
SELECT * FROM dumb_file
Beachten Sie, dass Sie doppelte Zeilen haben . Relationale Tabellen müssen eindeutige Zeilen haben . Ein weiterer Beweis dafür, dass Sie keine relationale Tabelle oder irgendwelche Eigenschaften einer solchen haben.
Beachten Sie, dass in Ihrem Bericht nur die ID
eindeutig ist Feld, um das sich kein Benutzer kümmert, das kein Benutzer sieht, weil es keine Daten sind, es ist ein zusätzlicher Unsinn, den Ihnen ein sehr dummer "Lehrer" gesagt hat, Sie sollen jede Datei einfügen. Sie haben Eintrag Eindeutigkeit, aber nicht row Einzigartigkeit.
In Bezug auf die Daten (die echten Daten abzüglich der fremden Zusätze), die Daten name_last
und name_first
kann ohne die ID
existieren Feld. Eine Person hat einen Vornamen und einen Nachnamen, ohne dass ein Ausweis auf der Stirn eingeprägt ist.
Die zweite Sache, die Sie verwenden, die Sie verwirrt, ist AUTOINCREMENT.
Wenn Sie ein Datensatzablagesystem ohne relationale Funktion implementieren, ist es sicherlich hilfreich, dass Sie beim Einfügen von Datensätzen das Inkrement nicht codieren müssen. Aber wenn Sie eine relationale Datenbank implementieren, hat sie überhaupt keinen Zweck, weil Sie sie nie verwenden werden. Es gibt viele Funktionen in SQL, die die meisten Leute nie verwenden.
Korrekturmaßnahme
Wie können Sie also diese dumb_file, die voller doppelter Zeilen ist, auf eine relationale Tabelle aktualisieren, erhöhen, um einige der Eigenschaften und Vorteile einer relationalen Tabelle zu erhalten? Dazu sind drei Schritte erforderlich.
-
Sie müssen Keys verstehen
- Und seit wir von den ISAM-Dateien der 1970er zum Relational Model übergegangen sind , müssen Sie relationale Schlüssel verstehen . Das heißt, wenn Sie die Vorteile (Integrität, Leistung, Geschwindigkeit) einer relationalen Datenbank nutzen möchten.
Dr. E. F. Cood, in seinem RM , hat Folgendes erklärt:
aus den Daten wird ein Schlüssel gebildet
und
Die Zeilen in einer Tabelle müssen eindeutig sein
Ihr „Schlüssel“ besteht nicht aus den Daten. Es ist ein zusätzlicher Parasit ohne Daten, der dadurch verursacht wird, dass Sie mit der Krankheit Ihres "Lehrers" infiziert sind. Erkenne es als solches an und erlaube dir die volle geistige Leistungsfähigkeit, die Gott dir gegeben hat (beachte, dass ich dich nicht auffordere, isoliert oder fragmentiert oder abstrakt zu denken, alle Elemente in einer Datenbank müssen miteinander integriert werden). Erstellen Sie einen echten Schlüssel aus den Daten und nur aus den Daten. In diesem Fall gibt es nur einen möglichen Schlüssel:
(name_last, name_first).
-
Probieren Sie diesen Code aus , erklären eine eindeutige Einschränkung für die Daten:
CREATE TABLE dumb_table ( id INT NOT NULL IDENTITY PRIMARY KEY, name_first CHAR(30) NOT NULL, name_last CHAR(30) NOT NULL CONSTRAINT UK UNIQUE ( name_last, name_first ) ) INSERT dumb_table VALUES ( "Mickey", "Mouse" ) -- succeeds INSERT dumb_table VALUES ( "Mickey", "Mouse" ) -- fails, as intended INSERT dumb_table VALUES ( "Minnie", "Mouse" ) -- succeeds SELECT * FROM dumb_table
Jetzt haben wir Zeileneindeutigkeit . Das ist die Reihenfolge, die den meisten Menschen passiert:Sie erstellen eine Datei, die Duplikate erlaubt; sie haben keine Ahnung, warum Dupes in den Drop-down-Menüs erscheinen; der Benutzer schreit; sie optimieren die Datei und fügen einen Index hinzu, um Duplikate zu verhindern; Sie gehen zum nächsten Bugfix. (Sie können dies richtig tun oder nicht, das ist eine andere Geschichte.)
-
Die zweite Ebene. Für denkende Menschen, die über die Fix-its hinausdenken. Da wir jetzt Zeileneindeutigkeit haben, was in Himmels Namen ist der Zweck der
ID
Feld, warum haben wir es überhaupt ??? Oh, weil der Chihuahua Rotty heißt und wir Angst haben, ihn anzufassen.Die Deklaration, dass es sich um einen
PRIMARY KEY
handelt ist falsch, aber es bleibt und verursacht Verwirrung und falsche Erwartungen. Der einzige echte Schlüssel, den es gibt, ist der(name_last, name_fist),
und es ist ein alternativer Schlüssel an dieser Stelle.Daher die
ID
Feld ist völlig überflüssig; ebenso der Index, der dies unterstützt; und das blödeAUTOINCREMENT
auch; ebenso die falsche Deklaration, dass es sich um einenPRIMARY KEY
handelt; und alle Erwartungen, die Sie daran haben, sind falsch.Entfernen Sie daher die überflüssige
ID
Feld. Probieren Sie diesen Code aus :CREATE TABLE honest_table ( name_first CHAR(30) NOT NULL, name_last CHAR(30) NOT NULL CONSTRAINT PK PRIMARY KEY ( name_last, name_first ) ) INSERT honest_table VALUES ( "Mickey", "Mouse" ) -- succeeds INSERT honest_table VALUES ( "Mickey", "Mouse" ) -- fails, as intended INSERT honest_table VALUES ( "Minnie", "Mouse" ) -- succeeds SELECT * FROM honest_table
Funktioniert einwandfrei, funktioniert wie beabsichtigt, ohne die überflüssigen Felder und Indizes.
Bitte denken Sie daran, und machen Sie es jedes Mal richtig.
Falsche Lehrer
In diesen Endzeiten werden wir, wie empfohlen, viele davon haben. Beachten Sie gut, die "Lehrer", die ID
verbreiten Spalten verstehen aufgrund der detaillierten Beweise in diesem Beitrag das Relationale Modell einfach nicht oder relationale Datenbanken. Vor allem diejenigen, die Bücher darüber schreiben.
Wie sich zeigt, stecken sie in der ISAM-Technologie von vor 1970 fest. Das ist alles, was sie verstehen, und das ist alles, was sie lehren können. Sie verwenden einen SQL-Datenbankcontainer, um den Zugriff, die Wiederherstellung, das Backup usw. zu erleichtern, aber der Inhalt ist ein reines Datensatzablagesystem ohne relationale Integrität, Leistung oder Geschwindigkeit. AFAIC, es ist ein schwerer Betrug.
Zusätzlich zu ID
Natürlich gibt es mehrere Elemente, die Schlüsselkonzepte von Relational oder nicht sind, die mich zusammengenommen zu einer so schwerwiegenden Schlussfolgerung veranlassen. Diese anderen Elemente würden den Rahmen dieses Beitrags sprengen.
Ein bestimmtes Idiotenpaar greift derzeit die First Normal Form an. Sie gehören in die Anstalt.
Antwort
Nun zum Rest Ihrer Frage.
Gibt es eine Möglichkeit, eine relationale Tabelle zu erstellen, ohne die Auto-Increment-Funktionen zu verlieren?
Das ist ein in sich widersprüchlicher Satz. Ich hoffe, Sie werden anhand meiner Erklärung verstehen, dass relationale Tabellen keine Notwendigkeit haben für AUTOINCREMENT
"Merkmale"; wenn die Datei AUTOINCREMENT
hat , es ist keine relationale Tabelle.
AUTOINCREMENT
ist nur für eine Sache gut:wenn, und nur wenn, Sie eine Excel-Tabelle im SQL-Datenbank-Container erstellen möchten, vollgestopft mit Feldern namens A,
B,
und C,
über die Oberseite und Rekordnummern auf der linken Seite. Datenbanktechnisch ist das das Ergebnis eines SELECT, einer abgeflachten Ansicht der Daten, also nicht die Quelle von Daten, die organisiert (normalisiert) sind.
Eine andere mögliche (aber nicht bevorzugte) Lösung könnte darin bestehen, dass es einen anderen Primärschlüssel in der ersten Tabelle gibt, der der Benutzername des Benutzers ist, natürlich nicht mit einer Autoinkrement-Anweisung. Ist es unvermeidlich?
In der technischen Arbeit kümmern wir uns nicht um Vorlieben, denn das ist subjektiv und ändert sich ständig. Wir kümmern uns um technische Korrektheit, denn das ist objektiv und ändert sich nicht.
Ja, es ist unvermeidlich. Denn es ist nur eine Frage der Zeit; Anzahl der Fehler; Anzahl der „Geht nicht“; Anzahl von Benutzerschreien, bis Sie sich den Tatsachen stellen, Ihre falschen Erklärungen überwinden und Folgendes erkennen:
-
der einzige Weg, um sicherzustellen, dass der Benutzer zeilen einzigartig sind, dass user_names einzigartig sind, ist ein
UNIQUE
zu deklarieren Einschränkung darauf -
und
user_id
loswerden oderid
in der Benutzerdatei -
was für
user_name
wirbt zuPRIMARY KEY
Ja, denn dein gesamtes Problem mit dem dritten Tisch ist nicht zufällig damit beseitigt.
Diese dritte Tabelle ist eine assoziative Tabelle . Der einzige erforderliche Schlüssel (Primärschlüssel) ist eine Zusammensetzung der beiden übergeordneten Primärschlüssel. Das stellt die Eindeutigkeit der Zeilen sicher , die durch ihre Schlüssel identifiziert werden, nicht durch ihre IDs.
Ich warne Sie davor, weil dieselben "Lehrer" Ihnen den Fehler beigebracht haben, ID
zu implementieren Felder, lehren den Fehler der Implementierung von ID
Felder in der Assoziativtabelle, wo sie, genau wie bei einer gewöhnlichen Tabelle, überflüssig ist, keinen Zweck erfüllt, Duplikate einführt und Verwirrung stiftet. Und es ist doppelt überflüssig, weil die beiden Schlüssel, die uns versorgen, bereits da sind und uns ins Gesicht starren.
Da sie den RM nicht verstehen , oder relationale Begriffe, nennen sie assoziative Tabellen „Link“- oder „Map“-Tabellen. Wenn sie eine ID
haben Feld, sie sind eigentlich Dateien.
Nachschlagetabellen
ID
Felder sind besonders Dumme Sache für Nachschlage- oder Referenztabellen. Die meisten von ihnen haben erkennbare Codes, es besteht keine Notwendigkeit, die Liste der darin enthaltenen Codes aufzuzählen, da die Codes eindeutig sind (sein sollten).
Außerdem ist es eine gute Sache, die Codes in den untergeordneten Tabellen als FKs zu haben:Der Code ist viel aussagekräftiger und erspart oft einen unnötigen Join:
SELECT ...
FROM child_table -- not the lookup table
WHERE gender_code = "M" -- FK in the child, PK in the lookup
statt:
SELECT ...
FROM child_table
WHERE gender_id = 6 -- meaningless to the maintainer
oder schlimmer:
SELECT ...
FROM child_table C -- that you are trying to determine
JOIN lookup_table L
ON C.gender_id = L.gender_id
WHERE L.gender_code = "M" -- meaningful, known
Beachten Sie, dass dies etwas ist, was man nicht vermeiden kann:Sie brauchen Eindeutigkeit im Suchcode und Einzigartigkeit in der Beschreibung. Das ist die einzige Methode, um Duplikate in jedem zu verhindern der beiden Spalten:
CREATE TABLE gender (
gender_code CHAR(2) NOT NULL,
name CHAR(30) NOT NULL
CONSTRAINT PK
PRIMARY KEY ( gender_code )
CONSTRAINT AK
UNIQUE ( name )
)
Vollständiges Beispiel
Aufgrund der Details in Ihrer Frage vermute ich, dass Sie Probleme mit der SQL-Syntax und der FK-Definition haben, daher werde ich die gesamte Lösung, die Sie benötigen, als Beispiel geben (da Sie keine Dateidefinitionen angegeben haben):
CREATE TABLE user ( -- Typical Identifying Table
user_name CHAR(16) NOT NULL, -- Short PK
name_first CHAR(30) NOT NULL, -- Alt Key.1
name_last CHAR(30) NOT NULL, -- Alt Key.2
birth_date DATE NOT NULL -- Alt Key.3
CONSTRAINT PK -- unique user_name
PRIMARY KEY ( user_name )
CONSTRAINT AK -- unique person identification
PRIMARY KEY ( name_last, name_first, birth_date )
)
CREATE TABLE sport ( -- Typical Lookup Table
sport_code CHAR(4) NOT NULL, -- PK Short code
name CHAR(30) NOT NULL -- AK
CONSTRAINT PK
PRIMARY KEY ( sport_code )
CONSTRAINT AK
PRIMARY KEY ( name )
)
CREATE TABLE user_sport ( -- Typical Associative Table
user_name CHAR(16) NOT NULL, -- PK.1, FK
sport_code CHAR(4) NOT NULL, -- PK.2, FK
start_date DATE NOT NULL
CONSTRAINT PK
PRIMARY KEY ( user_name, sport_code )
CONSTRAINT user_plays_sport_fk
FOREIGN KEY ( user_name )
REFERENCES user ( user_name )
CONSTRAINT sport_occupies_user_fk
FOREIGN KEY ( sport_code )
REFERENCES sport ( sport_code )
)
Dort der PRIMARY KEY
Deklaration ist ehrlich, es ist ein Primärschlüssel; keine ID;
kein AUTOINCREMENT;
keine zusätzlichen Indizes; keine doppelten Zeilen; keine falschen Erwartungen; keine Folgeprobleme.
Datenmodell
Hier ist das Datenmodell für die Definitionen.
-
Wenn Sie nicht an die Notation gewöhnt sind, beachten Sie bitte, dass jedes kleine Häkchen, jede Kerbe und Markierung, die durchgezogenen vs. gestrichelten Linien, die quadratischen vs. runden Ecken, etwas sehr Spezifisches bedeutet. Siehe IDEF1X-Notation .
-
Ein Bild sagt mehr als tausend Worte; in diesem Fall ist ein Standard-Reklamationsbild mehr wert; ein schlechter ist das Papier nicht wert, auf dem er gezeichnet ist.
-
Bitte überprüfen Sie die Verbphrasen sorgfältig, sie bestehen aus einer Reihe von Prädikaten. Der Rest der Prädikate kann direkt aus dem Modell bestimmt werden. Wenn dies nicht klar ist, fragen Sie bitte nach.