Frage

Eine Webanwendung, an der ich arbeite, ist auf einen unerwarteten "Fehler" gestoßen - die Datenbank der App enthält zwei Tabellen (unter anderem) als "Zustände" und "Städte".

'Zustände'Tischfelder:

-------------------------------------------
idStates   |   State   |   Lat   |   Long
-------------------------------------------

'Idstates'ist ein automatisch inkrementierender Primärschlüssel.

'Städte'Tischfelder:

----------------------------------------------------------
idAreaCode   |   idStates   |   City   |   Lat   |   Long
----------------------------------------------------------

'IdareACODE'ist ein Hauptschlüssel, der aus Ländercode + Vorwahl besteht (z. B. 91422, wobei 91 der Ländercode für Indien und 422 der Vorwahl Code einer Stadt in Indien ist). ''Idstates"ist ein fremder Schlüssel, der abgeleitet ist"Zustände'Tabelle, um jede Stadt in die' zu verbinden 'Städte'Tabelle mit seinem entsprechenden Zustand.

Wir haben festgestellt, dass die Kombination aus Ländercode + Vorwahl für jede Stadt eindeutig wäre und daher sicher als Hauptschlüssel verwendet werden könnte. Alles funktionierte. Ein Standort in Indien fand jedoch einen unerwarteten "Fehler" im DB -Design - Indien ist wie die USA eine Bundesdemokratie und ist geografisch in viele Bundesstaaten oder Gewerkschaftsgebiete unterteilt. Sowohl die Daten der Bundesstaaten als auch die Daten der Gewerkschaft werden in der '"gespeichert" gespeichert.Zustände' Tisch. Es gibt jedoch einen Ort - - Chandigarh - was zu zwei Staaten gehört (Haryana und Punjab) und ist auch ein Gewerkschaftsgebiet für sich.

Offensichtlich erlaubt uns das aktuelle DB -Design nicht, mehr als einen Rekord der Stadt zu speichern.Chandigarh'.

Eine der vorgeschlagenen Lösungen besteht darin, einen Primärschlüssel zu erstellen, der die Säulen kombiniert. 'IdareACODE' und 'Idstates'.

Ich möchte wissen, ob dies die bestmögliche Lösung ist?

(FYI: Wir verwenden MySQL mit dem InnoDB -Engine).


Mehr Informationen:

  • Die Datenbank speichert meteorologische Informationen für jede Stadt. Somit sind Staat und Stadt der Ausgangspunkt jeder Abfrage.
  • Frische Daten für jede Stadt werden täglich mit einer CSV -Datei eingefügt. Die CSV -Datei enthält eine IDStates (für Status) und IdareAcode (für City), mit der jeder Datensatz identifiziert wird.
  • Die Datenbanknormalisierung ist uns wichtig.

HINWEIS: Der Grund für die Nicht -Verwendung eines automatischen Inkrementierungs -Primärschlüssels für die Stadttabelle ist, dass die Datenbank täglich / stündlich mit einer CSV -Datei aktualisiert wird (die von einer anderen App generiert wird). Und jeder Datensatz in der CSV -Datei wird von der Spalte IDStates und IdareAcode identifiziert. Daher wird bevorzugt, dass der in der Stadttisch verwendete Primärschlüssel für jede Stadt gleich ist, auch wenn der Tisch erneut gelöscht und aktualisiert wird. ZIP -Codes (oder PIN -Codes) und Flächencodes (oder STD -Codes) erfüllen die Kriterien, die eindeutig, statisch (nicht oft ändern) und eine fertige Liste davon sind leicht verfügbar. (Wir haben uns vorerst für Gebietscodes entschieden, weil Indien dabei seine PIN -Codes in einem neuen Format aktualisiert hat.)

Das Lösung Wir haben uns entschieden, dies auf Anwendungsebene zu verarbeiten, anstatt Änderungen am Datenbankdesign vorzunehmen. In der Datenbank werden wir nur einen Datensatz von 'Chandigarh' speichern. In der Anwendung haben wir eine Flagge für jede Suche nach "Chandigarh, Punjab" oder "Chandigarh, Haryana" erstellt, um die Suche in diesen Datensatz umzuleiten. Ja, es ist nicht ideal, aber ein akzeptabler Kompromiss, da dies die einzige Ausnahme ist, auf die wir bisher gestoßen sind.

War es hilfreich?

Lösung

Es hört sich so an, als würden Sie Daten für ein Telefonverzeichnis sammeln. Sind Sie? Warum sind Ihnen Zustände wichtig? Die Antwort auf diese Frage wird wahrscheinlich bestimmen, welches Datenbankdesign für Sie am besten geeignet ist.

Sie mögen denken, dass es offensichtlich ist, was eine Stadt ist. Es ist nicht. Es hängt davon ab, was Sie mit den Daten tun werden. In den USA gibt es diese Einheit namens MSA (statistischer Metropolregion). Die Kansas City MSA erstreckt sich sowohl in Kansas City, Kansas und Kansas City, Missouri. Ob die MSA -Einheit sinnvoll ist oder nicht, hängt von der beabsichtigten Verwendung der Daten ab. Wenn Sie in uns Bereichscodes verwendet haben, um Städte zu bestimmen, würden Sie eine ganz andere Gruppierung haben als MSAs. Auch hier hängt es davon ab, was Sie mit den Daten tun werden.

Im Allgemeinen, wenn hierarchische Muster politischer Unterteilungen zusammenbrechen, besteht die allgemeinste Lösung darin, die Beziehung zu viel zu viel zu betrachten. Sie lösen dieses Problem genauso wie andere, viele zu viele Probleme. Durch Erstellen eines neuen Tisches mit zwei fremden Schlüssel. In diesem Fall sind die Fremdschlüssel Idareacode und Idstates.

Jetzt können Sie in vielen Bundesstaaten einen Arecode und einen Staat über viele Flächencodes haben. Es scheint eine Schande zu sein, diesen zusätzlichen Overhead nur eine Ausnahme abzudecken. Wissen Sie, ob die Ausnahme, die Sie entdeckt haben, nur die Spitze des Eisbergs ist und es viele solche Ausnahmen gibt?

Andere Tipps

Ein zusammengesetzter Schlüssel kann problematisch sein, wenn Sie auf diese Tabelle verweisen möchten, da die Überweisungstabelle alle Spalten haben müsste, die der Primärschlüssel hat.

Wenn dies der Fall ist, möchten Sie möglicherweise einen Sequenz -Primärschlüssel haben und den Idareacode und die Idstates in einer eindeutigen Null -Gruppe definieren lassen.

Ich denke, es ist am besten, einen weiteren Tisch hinzuzufügen, Länder. Ihr Problem ist ein Beispiel, warum die Datenbanknormalisierung wichtig ist. Sie können nicht einfach verschiedene Schlüssel zu einer Spalte mischen und anpassen.

Ich empfehle Ihnen also, diese Tabelle zu erstellen:

Länder:

+------------+--------------+
| Country_id | country_name |
+------------+--------------+

Zustände:

+------------+----------+------------+
| Country_id | STATE_ID | state_name |
+------------+----------+------------+

Städte

+------------+----------+---------+-----------+
| Country_id | STATE_ID | City_id | city_name |
+------------+----------+---------+-----------+

Daten

+------------+----------+---------+---------+----------+
| Country_id | STATE_ID | City_id | Data_id | your_CSV |
+------------+----------+---------+---------+----------+

Die fetten Felder sind Primärschlüssel. Geben Sie ein Standard Country_id wie 1 für uns, 91 für Indien und so weiter ein. City_id sollte auch ihre Standard -ID verwenden.

Sie können dann feststellen, dass etwas ziemlich schnell zueinander mit minimalem Overhead gehört. Alle Daten können dann direkt in die Datentabelle eingegeben werden, wodurch als ein Einstiegspunkt dient und alle Daten in einen einzelnen Punkt gespeichert werden. Ich weiß es mit MySQL nicht, aber wenn Ihre Datenbank Partitionierung unterstützt, können Sie Datentabellen entsprechend dem Country_ID oder Country_id+State_ID an ein paar Serverarrays partitionieren, sodass dies auch Ihre Datenbankleistung erheblich beschleunigt wird. Die erste, zweite und dritte Tabelle wird bei der Serverlast überhaupt nicht viel getroffen und nur als Referenz dienen. Sie arbeiten hauptsächlich an der vierten Datentabelle. Sie können Daten so viel hinzufügen, wie Sie möchten, ohne wieder ein Duplikat.

Wenn Sie nur eine Daten pro Stadt haben, können Sie die Datentabelle weglassen und CSV_DATA in die Tabelle der Städte wie folgt verschieben:

Städte

+------------+----------+---------+-----------+----------+
| Country_id | STATE_ID | City_id | city_name | CSV_data |
+------------+----------+---------+-----------+----------+

Wenn Sie dem Schlüssel eine zusätzliche Spalte hinzufügen, damit Sie einen zusätzlichen Datensatz für eine bestimmte Stadt hinzufügen können, normalisieren Sie Ihre Daten nicht ordnungsgemäß. Angesichts der Tatsache, dass Sie jetzt entdeckt haben, dass eine Stadt ein Mitglied mehrerer Staaten sein kann, würde ich vorschlagen, einen Hinweis auf einen Staat aus der Städtabelle zu beseitigen, und dann eine Stadetabelle hinzugefügt, mit der Sie Zustände mit Städten in Verbindung bringen können (Erstellen von AM: M. Beziehung).

Einen Ersatzschlüssel im Vorbehalt. Was werden Sie tun, wenn Bereichscodes taub wechseln oder geteilt werden? Die Verwendung von Geschäftsschlüssel als Hauptschlüssel fast immer ist ein Fehler.

Ihre obige Zusammenfassung ist ein weiteres Beispiel dafür, warum.

"Wir haben gedacht, dass die Kombination aus der Landescode + Vorwahl für jede Stadt eindeutig wäre und daher sicher als Hauptschlüssel verwendet werden könnte"

Nachdem ich dies gelesen hatte, habe ich einfach angehalten, um etwas weiter in diesem Thema zu lesen. Wie könnte es jemand auf diese Weise finden?
Bereichscodes per Definition (die erste, die ich im Internet gefunden habe):
- "Ein Vorwahlkodex sind die Präfixnummern, mit denen eine geografische Region basierend auf dem nordamerikanischen Zahlenplan identifiziert wird. Diese 3 -stellige Nummer kann einer beliebigen Zahl in Nordamerika zugewiesen werden, einschließlich Kanada, den USA, Mexiko, Lateinamerika und die Karibik [1

Abgesehen davon, dass sie nur in Nordamerika verändern und nur in Nordamerika definiert sind, sind die Flächencodes in einigen anderen Ländern keine dreistelligen Digiten (3stellige sind einfach nicht genug, um in einigen Ländern hunderttausende Standorte zu haben. Übrigens hat der Vorwahlkodex meiner Mutter 5 Ziffern) und sie sind nicht streng mit festen geografischen Orten verbunden.

Flächencodes haben migrierende Orte wie arktische Lager, die mit Eis, normadischen Stämmen, migrierenden Militäreinheiten oder sogar großen ozeanischen Schiffen usw. driften, usw.

Was ist dann mit dem Zusammenführen einiger Städte in einen (oder umgekehrt)?

[1]
http://www.succesfuloffice.com/articles/answering-service-glossary-rea-code.htm

Ich empfehle, der Städtabelle ein neues Primärschlüsselfeld hinzuzufügen, das einfach automatisch inkrementell ist. Die KISS -Methodik (halten Sie es einfach).

Jede andere Lösung ist meiner Meinung nach umständlich und verwirrend.

  1. Die Datenbank ist nicht normalisiert. Es kann teilweise normalisiert werden. Infolgedessen finden Sie viel mehr Fehler und Einschränkungen in der Erweiterbarkeit.

  2. Eine Hierarchie des Landes, dann ist die Stadt in Ordnung. Sie benötigen keine zusätzliche Tisch, die einige vorschlagen. Die besagte Stadt (und viele in Amerika) vermehren sich in drei Bundesstaaten.

  3. Durch die Platzierung von CountryCode und AreaCode, verkettet, haben Sie in einer einzigen Spalte grundlegende Datenbankregeln unterbrochen, ganz zu schweigen von dem hinzugefügten Code für jeden Zugriff. Zusätzlich ist CountryCode nicht normalisiert.

  4. Das Problem ist, dass CountryCode+AreaCode eine schlechte Wahl für einen Schlüssel für eine Stadt ist. In realer Hinsicht hat es nur sehr wenig mit einer Stadt zu tun, es gilt für riesige Landschwaden. Wenn die Bedeutung der Stadt in die Stadt geändert würde (wie in, beginnt Ihr Unternehmen, Daten für Großstädte zu sammeln), würde die DB vollständig brechen.

  5. Der Zauberer hat die einzige Antwort, die kurz vor dem richtigen Einsatz liegt. Dies würde Sie aufgrund mangelnder Normalisierung vor Ihren aktuellen Einschränkungen bewahren. Es ist nicht genau zu sagen, dass die Antwort des Magiern normalisiert ist. Es ist die richtige Wahl der Kennungen, die in diesem Fall eine Hierarchie bilden. Aber ich würde die "ID" -Säulen entfernen, weil sie unnötige, 100% redundante Säulen und 100% redundante Indizes sind. Die char () -Säulen sind so gut wie sie und für die PK (zusammengesetzte Schlüssel). Denken Sie daran, dass Sie ohnehin einen Index für die Spalte char () benötigen, um sicherzustellen, dass sie eindeutig ist.

    • Wenn Sie dies hätten, die relationale Struktur mit relationalen Kennungen, würde Ihr Problem nicht bestehen.
    • Und Ihre armen Benutzer müssen nicht dumme Dinge herausfinden oder bedeutungslose Kennungen im Auge behalten. Sie geben nur an, natürlich: State.name, City.Name, Readetype, Daten ....
  6. Wenn Sie am unteren Ende der Hierarchie (Stadt) gelangen, ist die Verbindung PK belastend geworden (3 x Char (20)), und ich möchte es nicht in die Datentabelle tragen (insbesondere wenn es tägliche CSV -Importe gibt und viele Lesungen oder Reihen pro Stadt). Deshalb würde ich nur für Stadt einen Ersatzschlüssel als PK hinzufügen.

  7. Aber für die veröffentlichte DDL, auch wenn es ist, ohne die DB zu normalisieren und relationale Kennungen zu verwenden, ist die PK der Stadt falsch. Es sollte (Idstates, idareacode) sein, nicht umgekehrt. Das wird Ihr Problem beheben.

Sehr schlechte Benennung übrigens.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top