2009-06-21 6 views
3

Angenommen, Sie haben eine Datenbank mit einer einzigen Tabelle haben wie ...Soll ich eine Zeichenkettentabelle verwenden, um die Datenbank effizienter zu machen?

--------------------------------------------- 
| Name | FavoriteFood     | 
--------------------------------------------- 
| Alice | Pizza       | 
| Mark | Sushi       | 
| Jack | Pizza       | 
--------------------------------------------- 

Wäre es platzsparender sein, eine zusätzliche Tabelle „Strings“ genannt zu haben, die Saiten, und ändern Sie die FavoriteFood Spalte eine speichert Index in der String-Tabelle. Im obigen Beispiel sieht "Pizza" so aus, als wäre es zweimal gespeichert, aber mit der zusätzlichen Tabelle scheint es, dass es nur einmal gespeichert wird. Natürlich darf man davon ausgehen, dass es 1.000.000 Zeilen und 1.000 eindeutige Strings statt nur 3 Zeilen und 2 eindeutige Strings gibt.

Edit: Wir wissen nicht, was die FavoriteFoods im Voraus sind: Sie sind vom Benutzer bereitgestellt. Die programmatische Schnittstelle zur String-Tabelle würde so etwas wie ...

String GetString(int ID) { return String at with Row-ID == ID } 

int GetID(String s) { 
    if s exists, return row-id; 
    else { 
    Create new row; 
    return new row id; 
    } 
} 

So ist die String-Tabelle effizienter scheint, aber moderne Datenbanken bereits tun, dass im Hintergrund, so kann ich tun, nur die einfache Tabelle angehen und effizient sein?

Antwort

3

Sie sollten in Bezug auf das, was ein gutes Design in Bezug auf Ihre Problemdomäne macht, eher als Effizienz denken (es sei denn, Sie erwarten, Dutzende von Millionen + Zeilen zu haben).

Eine gut gestaltete Datenbank sollte in 3NF (dritte Normalform) sein. Nur Denormalisierung, wenn Sie ein Leistungsproblem durch Messen identifiziert haben.

+0

Vorausgesetzt, es gibt keine Hilfsdaten mit den Lebensmitteln zugeordnet (z. B. Ernährungsinformationen), dann ist sein Design bereits in 3NF. Nicht jedes Bit von wiederholten Daten muss eine ganze Zahl sein, um eine korrekt normalisierte Datenbank zu haben. –

+2

@Tyler McHenry: Ich habe es nicht gesagt, oder? Ich habe darauf hingewiesen, dass Design wichtiger ist als die Optimierung eines Leistungsproblems, das Sie nicht haben. –

+1

Ich würde sagen, dass der beste Grund, in diesem Fall mit nicht normalisierten Daten zu gehen, einfach darin liegt, dass es sich um vom Benutzer eingegebene Daten handelt. Es wird schwierig sein, sie dazu zu bringen, ihre bereits eingegebene Saite in den 1000 Saiten zu finden, die bereits eingegeben wurden. Sie werden sowieso mit 6 verschiedenen Variationen von jedem Ding enden, weil Benutzer originell sein wollen und sagen, dass sie Peperoni-Pizza mögen, oder Pizza mit nur Käse, oder Pizza mit 6 Arten von Fleisch darauf. Obwohl Pizza einfach ausreichen würde, bekommt man 6 verschiedene Arten von Pizza, also hat es keinen Sinn, sie zu normalisieren. – Kibbee

4

Woran messen Sie die Effizienz? Angenommen, es gibt keine anderen Daten, die mit jedem FavoriteFood verknüpft sind (in diesem Fall sind offensichtlich zwei Tabellen erwünscht), ist ein Ein-Tabellen-Ansatz wahrscheinlich zeiteffizienter, da der unnötige Join zusätzliche Verarbeitungskosten verursachen würde. Auf der anderen Seite ist ein Zwei-Tabellen-Ansatz möglicherweise platzsparender, da weniger Platz für die Speicherung eines Index als für einen String benötigt wird. Dies hängt jedoch davon ab, wie die von Ihnen verwendete Datenbank den Speicher wiederholter Strings optimiert.

+0

Eigentlich haben Sie Recht, Join-Prozess würde mehr Zeit und Leistung verbrauchen und wird schlimmer sein als wiederholte String-Datensätze. – Tarik

2

Wenn Sie eine andere Tabelle haben, um die Zeichenfolgen zu speichern, wird es einfacher, wenn Sie die Beschreibungen aktualisieren möchten, zum Beispiel, wenn Sie alle Pizzas auf italienische Pizza aktualisieren müssen, dann können Sie mit einer Zeilenaktualisierung tun Du benutzt eine separate Tabelle. Ein weiterer Vorteil wären Übersetzungen, Sie können die andere Tabelle verwenden, um Übersetzungen der Zeichenfolge in verschiedenen Sprachen zu speichern, und die auf der aktuellen Sprache basierende auswählen.

Aber das Problem mit diesem Ansatz wäre für Einsätze. Sie müssen in beide Tabellen eingefügt werden und müssen auch die Fremdschlüssel-Constraints beibehalten, so dass sie einer einfachen Tabelle ein wenig Komplexität hinzufügen.

1

Pros eine separate "Strings" Tabelle mit:

  • Wahrscheinlich weniger Platz, wenn Strings wirklich häufig
  • wahrscheinlich wiederholen, schneller typische Abfragen - wegen weniger I \ O

Nachteile:

  • Sie werden schreiben komplexere Abfragen zu die gleichen res erreichen ult
  • Wenn der Wiederholungsfaktor eher klein ist, erhalten Sie höhere Abfrage Ausführung Zeit. Um jede ID in eine Zeichenkette (oder zurück) aufzulösen, führt der Datenbankserver eine einzelne Suche (Suchoperation) für jede ID durch.So erhalten Sie zusätzliche Protokoll (Strings.Count()) Faktor ~ für jede Abfrage dies tun.

Aber eigentlich ist das wirklich effektiv. Z.B. Die meisten Volltext-Suchmaschinen verwenden fast diesen Ansatz, um Dokument-Wort-Karten zu speichern.

Verwandte Themen