it-swarm-eu.dev

Ordnungsgemäße Verwendung von Nachschlagetabellen

Ich habe Probleme, genau herauszufinden, wie gute Grenzen gesetzt werden können, wann und wo Nachschlagetabellen in einer Datenbank verwendet werden sollen. Die meisten Quellen, die ich mir angesehen habe, sagen, dass ich nie zu viele haben kann, aber irgendwann scheint die Datenbank in so viele Teile zerlegt zu sein, dass sie zwar effizient, aber nicht mehr verwaltbar ist. Hier ist ein Beispiel, mit dem ich zusammenarbeite:

Angenommen, ich habe eine Tabelle mit dem Namen Mitarbeiter:

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Stellen Sie sich für einen Moment vor, dass die Daten komplexer sind und Hunderte von Zeilen enthalten. Das offensichtlichste, was ich sehe, das in eine Nachschlagetabelle verschoben werden könnte, wäre Position. Ich könnte eine Tabelle mit dem Namen Positionen erstellen und die Fremdschlüssel aus der Tabelle Positionen in die Tabelle Mitarbeiter in der Spalte Position stecken.

ID  Position
1   Manager
2   Sales

Aber wie weit kann ich die Informationen weiterhin in kleinere Nachschlagetabellen aufteilen, bevor sie nicht mehr verwaltet werden können? Ich könnte eine Gender-Tabelle erstellen und eine 1 für männlich und eine 2 für weiblich in einer separaten Nachschlagetabelle haben. Ich könnte sogar LNames und FNames in Tabellen einfügen. Alle "John" -Einträge werden durch einen Fremdschlüssel von 1 ersetzt, der auf die FName-Tabelle verweist, die besagt, dass eine ID von 1 John entspricht. Wenn Sie dieses Kaninchenloch jedoch zu weit hinuntergehen, wird Ihre Mitarbeitertabelle auf ein Durcheinander von Fremdschlüsseln reduziert:

ID  LName   FName   Gender  Position
1   1       1       1       1
2   1       2       2       2
3   2       1       1       2

Während dies für einen Server möglicherweise effizienter ist oder nicht, ist dies für eine normale Person, die versucht, es zu warten, sicherlich nicht lesbar und erschwert es einem Anwendungsentwickler, auf ihn zuzugreifen. Meine eigentliche Frage ist also, wie weit ist zu weit? Gibt es irgendwo "Best Practices" für diese Art von Dingen oder eine Reihe guter Richtlinien? Ich kann online keine Informationen finden, die wirklich gute, brauchbare Richtlinien für dieses spezielle Problem enthalten. Datenbankdesign ist für mich ein alter Hut, aber GUTES Datenbankdesign ist sehr neu, so dass übermäßig technische Antworten über meinen Kopf gehen können. Jede Hilfe wäre dankbar!

25
Brad Turner

Aber wie weit kann ich die Informationen weiterhin in kleinere Nachschlagetabellen aufteilen, bevor sie nicht mehr verwaltet werden können? Ich könnte eine Gender-Tabelle erstellen und eine 1 für männlich und eine 2 für weiblich in einer separaten Nachschlagetabelle haben.

Sie mischen zwei verschiedene Themen. Ein Problem ist die Verwendung einer "Nachschlagetabelle". Das andere ist die Verwendung von Ersatzschlüsseln (ID-Nummern).

Beginnen Sie mit dieser Tabelle.

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Sie können eine "Nachschlagetabelle" für Positionen wie diese erstellen.

create table positions (
  pos_name varchar(10) primary key
);

insert into positions
select distinct position 
from employees;

alter table employees
add constraint emp_fk1
foreign key (position) 
  references positions (pos_name);

Ihre ursprüngliche Tabelle sieht genauso aus wie vor dem Erstellen der Nachschlagetabelle. Und die Tabelle der Mitarbeiter erfordert keine zusätzlichen Verknüpfungen, um nützliche, für Menschen lesbare Daten daraus zu erhalten.

Die Verwendung einer "Nachschlagetabelle" läuft auf Folgendes hinaus: Benötigt Ihre Anwendung die Kontrolle über Eingabewerte, die eine Fremdschlüsselreferenz bereitstellt? Wenn ja, können Sie immer eine "Nachschlagetabelle" verwenden. (Unabhängig davon, ob ein Ersatzschlüssel verwendet wird.)

In einigen Fällen können Sie diese Tabelle zur Entwurfszeit vollständig füllen. In anderen Fällen müssen Benutzer zur Laufzeit Zeilen zu dieser Tabelle hinzufügen können. (Und Sie müssen wahrscheinlich einige Verwaltungsprozesse einbeziehen, um neue Daten zu überprüfen.) Das Geschlecht, das tatsächlich einen ISO-Standard hat, kann zur Entwurfszeit vollständig ausgefüllt werden. Straßennamen für internationale Online-Produktbestellungen müssen wahrscheinlich zur Laufzeit hinzugefügt werden.

In Ihrer Employees-Tabelle würde ich nur nach "Position" suchen, da es sich um einen begrenzten Datensatz handelt, der erweitert werden kann.

  • Das Geschlecht ist selbstbeschreibend (z. B. M oder F), auf 2 Werte begrenzt und kann mit einer CHECK-Einschränkung erzwungen werden. Sie werden keine neuen Geschlechter hinzufügen (politische Korrektheit ignorieren).
  • Der Vorname "John" ist nicht Teil eines begrenzten, eingeschränkten Datensatzes: Der potenzielle Datensatz ist so groß, dass er praktisch unbegrenzt ist, sodass er nicht nachgeschlagen werden sollte

Wenn Sie eine neue Position hinzufügen möchten, fügen Sie der Nachschlagetabelle einfach eine Zeile hinzu. Dadurch werden auch Datenänderungsanomalien entfernt, was ein Punkt der Normalisierung ist

Sobald Sie eine Million Mitarbeiter haben, ist es effizienter, tinyint PositionID als varchar zu speichern.

Fügen wir eine neue Spalte "Gehaltswährung" hinzu. Ich würde hier eine Nachschlagetabelle mit einem Schlüssel von CHF, GBP, EUR, USD usw. verwenden: Ich würde keinen Ersatzschlüssel verwenden. Dies könnte durch eine CHECK-Einschränkung wie Geschlecht eingeschränkt werden, es handelt sich jedoch um einen begrenzten, aber erweiterbaren Datensatz wie Position. Ich gebe dieses Beispiel, weil ich den natürlichen Schlüssel verwenden würde, selbst wenn er in einer Million Zeilen von Mitarbeiterdaten angezeigt wird, obwohl er eher char (3) als tinyint ist

Zusammenfassend verwenden Sie also Nachschlagetabellen

  1. wo Sie eine endliche, aber erweiterbare Menge von Daten in einer Spalte haben
  2. wo ist nicht selbstbeschreibend
  3. zu vermeiden Datenänderungsanomalien
8
gbn

Die Antwort lautet "es kommt darauf an". Nicht sehr befriedigend, aber es gibt viele Einflüsse, die das Design drücken und ziehen. Wenn App-Programmierer die Datenbank entwerfen, funktioniert eine von Ihnen beschriebene Struktur für sie, da der ORM die Komplexität verbirgt. Sie werden sich beim Schreiben von Berichten die Haare ausreißen und müssen an zehn Tischen teilnehmen, um eine Adresse zu erhalten.

Design für die Verwendung, den beabsichtigten Gebrauch und die wahrscheinliche zukünftige Verwendung. Hier kommt Ihr Wissen über den Geschäftsprozess ins Spiel. Wenn Sie eine Datenbank für ein Veterinärunternehmen entwerfen, gibt es vernünftige Annahmen über Größe, Verwendung und Anweisungen in Bezug auf die Funktionalität, die sich erheblich von denen eines High-Tech-Start-ups unterscheiden.

Ein Lieblingszitat wiederverwenden

"Ein weiser Mann hat mir einmal gesagt" normalisieren, bis es weh tut, denormalisieren, bis es funktioniert ".

Irgendwo drin ist der Sweet Spot. Ich habe die Erfahrung gemacht, dass es nicht so schwerwiegend ist, eine Schlüssel-ID in mehr als einer Tabelle zu haben, wie manche denken, wenn Sie niemals Primärschlüssel ändern.

Nehmen Sie dieses abgekürzte Beispiel für stark normalisierte Tabellen aus einem realen System

CREATE TABLE PROPERTY
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_TYPE
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_LOCALE 
PROPERTY_ID                  NUMBER(9)           NOT NULL,
(LOCALE_ID                   NUMBER(9)           NOT NULL,  --language 
VALUE                        VARCHAR2(200)       NOT NULL);

CREATE TABLE PROPERTY_DEPENDENCY
(PROPERTY_ID                 NUMBER(9)           NOT NULL,
 PARENT_PROPERTY_ID          NUMBER(9)                   ,
 PROPERTY_TYPE_ID            NUMBER(9)           NOT NULL);

Diese Tabellen erstellen eine verknüpfte Liste einzelner Eigenschaften und übergeordneter untergeordneter Eigenschaften und werden hier verwendet

  CREATE TABLE CASE_PROPERTY
  (ID                        NUMBER(9)           NOT NULL,
  PARENT_ID                  NUMBER(9),
  CASE_ID                    NUMBER(9)           NOT NULL,
  PROPERTY_ID                NUMBER(9),
  PROPERTY_TYPE_ID           NUMBER(9)           NOT NULL);

Das sieht gut aus: Holen Sie sich alle Fälle mit einer property_id in einer Auswahl

Lassen Sie uns eine Liste zur Auswahl bekommen

 Select pl.value, pd.property_id
 from property_locale pl, property_dependency pd
 where pl.property_id = pd.property_id
 and pd.property_type_id = 2;  --example number

Versuchen Sie nun, alle Eigenschaften eines Falls auszuwählen, wenn er Eigenschaftstypen von 3 und 4 und 5 hat oder nicht ...

SELECT   cp2.case_id,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 2
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE1,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 34
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE2,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 4
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE3
  FROM   case_property cp2
 WHERE   cp2.case_id = 10293  

Das tut einfach weh ... auch wenn Sie eleganter damit umgehen. Fügen Sie jedoch ein wenig De-Normalisierung hinzu, indem Sie Eigenschaften aufteilen, für die ein Fall nur eine property_id hat, und dies könnte viel besser sein.

Um herauszufinden, wann Sie zu viele Tabellen haben oder nicht genug, versuchen Sie, die Datenbank mit Fragen abzufragen, die die Anwendung, ein Bericht und eine Analyse von Jahr zu Jahr verwenden.

5
kevinsky