Ich habe die folgende Tabelle (PostgreSQL 8.3), die Preise einiger Produkte speichert. Die Preise sind mit einer anderen Datenbank synchronisiert, im Grunde werden die meisten der folgenden Felder (abgesehen von einem) nicht von unserem Kunden aktualisiert - sondern stattdessen ab und wieder aktualisiert und mit einer anderen Lagerdatenbank synchronisiert:
%Vor%Bei der Synchronisation lösche ich die meisten der oben genannten Daten, mit Ausnahme der Daten, für die my_custom_field TRUE ist (wenn der Wert TRUE ist, bedeutet dies, dass der Client dieses Feld über seinen CMS aktualisiert hat und dieser Datensatz daher nicht gelöscht werden sollte). Ich fügt dann 100s bis 1000s Zeilen in die Tabelle ein, und UPDATE, wo die INSERT fehlschlägt (d. H. Wo die Kombination von (template_sku, siteid, currencyid, colourid) bereits existiert).
Meine Frage ist - welche Best Practice sollte hier angewendet werden, um einen Primärschlüssel zu erstellen? Wird ein Primärschlüssel benötigt? Ich wollte den Primärschlüssel = (template_sku, siteid, currencyid, colourid) machen - aber das colourid-Feld kann NULL sein, und die Verwendung in einem zusammengesetzten Primärschlüssel ist nicht möglich.
Nach dem, was ich in anderen Forenbeiträgen gelesen habe, denke ich, dass ich das oben Gesagte richtig gemacht habe und nur klarstellen muss:
1) Sollte ich einen "seriellen" Primärschlüssel verwenden, nur für den Fall, dass ich jemals einen brauche? Im Moment tue ich das nicht und werde es auch nicht tun, denn die wichtigen Daten in der Tabelle sind der Preis und mein benutzerdefiniertes Feld, die nur durch die Kombination (template_sku, siteid, currencyid, colourid) identifiziert werden.
>2) Da (template_sku, siteeid, currencyid, colourid) die Kombination ist, die ich verwenden werde, um den Preis eines Produkts abzufragen, sollte ich meinen Spalten weitere Indizierung hinzufügen, wie zum Beispiel "template_sku", das ein varchar ist? Oder ist die UNIQUE-Einschränkung bereits ein guter Index für meine SELECTs?
Soll ich einen "seriellen" Primärschlüssel verwenden, nur für den Fall, dass ich je einen brauche?
Sie können später problemlos eine serielle Spalte hinzufügen, wenn Sie eine benötigen:
%Vor%Die Spalte wird automatisch mit eindeutigen Werten gefüllt. Sie können es sogar zum Primärschlüssel in derselben Anweisung machen (wenn noch kein Primärschlüssel definiert ist):
%Vor%Wenn Sie die Tabelle aus anderen Tabellen referenzieren, rate ich Ihnen, einen solchen Ersatz-Primärschlüssel zu verwenden, da es ziemlich unhandlich ist, ihn durch vier Spalten zu verknüpfen. Es ist auch langsamer in SELECTs mit JOINs.
In beiden Fällen sollten Sie einen Primärschlüssel definieren . Der UNIQUE-Index mit einer Nullwert-Spalte ist kein vollständiger Ersatz. Es erlaubt Duplikate für Kombinationen, die einen NULL-Wert enthalten, da zwei NULL-Werte niemals als gleich betrachtet werden. Dies kann zu Problemen führen.
Wie
Das Farbfeld kann NULL sein
Sie möchten möglicherweise zwei eindeutige Indizes erstellen. Die Kombination (template_sku, siteid, currencyid, colourid)
darf wegen der Nullable PRIMARY KEY
keine colourid
sein, aber Sie können eine UNIQUE
Einschränkung erstellen, wie Sie sie bereits haben (indem Sie automatisch einen Index implementieren):
Dieser Index deckt perfekt die Fragen ab, die Sie in 2) erwähnt haben.
Erstellen Sie zusätzlich einen partiellen eindeutigen Index, wenn Sie "Duplikate" mit (colourid IS NULL)
vermeiden wollen:
Um alle Grundlagen abzudecken. Ich habe mehr über diese Technik in einer ähnlichen Antwort auf dba.SE geschrieben.
Die einfache Alternative zum obigen Beispiel besteht darin, colourid
NOT NULL zu machen und einen Primärschlüssel anstelle des obigen product_pricebands_uni_idx
zu erstellen.
Auch, wie Sie
lösche grundsätzlich die meisten Daten
Bei der Nachfüllung wird es schneller möglich sein, Indizes, die während des Nachfüllvorgangs nicht benötigt sind, zu löschen und diese anschließend neu zu erstellen. Es ist um eine Größenordnung schneller, einen Index von Grund auf neu zu erstellen, als alle Zeilen inkrementell hinzuzufügen.
Woher wissen Sie, welche Indizes verwendet werden (benötigt)?
EXPLAIN ANALYZE
. Es kann auch schneller sein, die wenigen Zeilen mit my_custom_field = TRUE
in einer temporären Tabelle auszuwählen, TRUNCATE
die Basistabelle und INSERT die Überlebenden. Hängt davon ab, ob Sie Fremdschlüssel definiert haben. Würde so aussehen:
Dies vermeidet viel Staubsaugen.
Tags und Links postgresql indexing primary-key database-design null