2012-04-10 13 views
0

Ich muss Millionen von Einträgen in einer Datenbank speichern. Jeder Eintrag wird durch eine Menge eindeutiger ganzzahliger Identifizierer identifiziert. Zum Beispiel kann ein Wert durch eine Menge von 10 ganzzahligen Identifizierern identifiziert werden, von denen jeder weniger als 100 Millionen aufweist.Viele ganze Zahlen in eine große ganze Zahl packen

Um die Größe der Datenbank zu reduzieren, dachte ich über die folgende Codierung mit einem einzigen 32-Bit-Integer-Wert.

 
Identifier 1: 0 - 100,000,000 
Identifier 2: 100,000,001 - 200,000,000 
. 
. 
. 
Identifier 10: 900,000,001 - 1,000,000,000 

Ich verwende Java. Ich kann eine einfache Methode zum Kodieren/Dekodieren schreiben. Der Benutzercode muss nicht wissen, dass ich während des Abrufens/Speicherns codiere/decodiere.

Was ich wissen möchte ist: Was ist die effizienteste (schnellste) und empfohlene Art, solche Encodierung/Decodierung zu implementieren. Eine einfache Implementierung wird eine große Anzahl von Multiplikationen/Subtraktionen durchführen.

Ist es möglich, Verschiebungen (oder bitweise Operationen) zu verwenden und eine andere Partitionsgröße zu wählen (die Größe jedes Segments muss immer noch nahe bei 100 Millionen liegen)?

Ich bin offen für alle Vorschläge, Ideen oder sogar ein völlig anderes Schema. Ich möchte die Tatsache ausnutzen, dass die Integer-Kennungen begrenzt sind, um die Speichergröße drastisch zu reduzieren, ohne die Leistung merklich zu beeinträchtigen.

Edit: Ich wollte nur hinzufügen, dass ich einige Antworten in diesem Forum durchging. Eine übliche Lösung bestand darin, die Bits für jede Kennung aufzuteilen. Wenn ich für jeden Bezeichner 2 Bits für insgesamt 10 Bezeichner verwende, wird mein Bereich von Bezeichnern stark eingeschränkt.

+0

müssen Sie Potenzen von 2 für Ihre Bereiche verwenden, Bit-Verschiebung zur Arbeit zu bekommen. – MeBigFatGuy

+1

Können Sie ein Beispiel dafür geben, wie ein solcher codierter Integer aussehen würde (und wie Sie ihn manuell dekodieren würden)? Bitte verwenden Sie beliebige IDs (wie '144,560,000',' 200,0158,945', '399,888,777' usw.) für Ihr Beispiel – Thomas

+1

Beachten Sie, dass Sie bei einer Verschiebung nur 3 Bytes pro ID haben (wenn Sie 10 IDs eingeben möchten) 32 Bits). Somit kann jede ID nur bis zu 8 verschiedene Werte haben. – Thomas

Antwort

1

Es klingt, als ob Sie mehrere ganzzahlige Werte von 0 ... 100m in eine einzelne 32-Bit-Ganzzahl packen möchten. Wenn Sie keine wichtigen Informationen weglassen, die es erlauben würden, diese 0 ... 100m-Werte effizienter zu speichern, gibt es einfach keine Möglichkeit, dies zu tun.

ceil (log2 (100m)) = 27bit, was bedeutet, dass Sie nur 5 "Ersatzbits" haben.

+0

Danke. Ich hatte es nicht durchdacht. –

1

Sie können die Segmentierungsgröße auf 27 Bit setzen, wodurch Sie 32 * 128 M Segmente erhalten. anstelle von 42 * 100 M

int value = 
int high = value >>> 27; 
int low = value & ((1L << 27) -1); 

Es ist nichts wert, diese Berechnung wahrscheinlich ist trivial zu sein im Vergleich zu den Kosten einer Datenbank zu verwenden.

1

Es ist unklar, was Sie wirklich tun wollen, aber es klingt wie Sie einen ganzzahligen Wert wollen, wobei jedes Bit ein bestimmtes Attribut darstellt und mit einer bitmask Anwendung.

Eine 32-Bit-Ganzzahl kann 32 verschiedene Attribute speichern, 64-Bit 64 usw. Um mehr zu haben, benötigen Sie mehrere Integer-Spalten.

Wenn das nicht ist, weiß ich nicht, was Sie mit "encode" meinen.

+0

Sie haben Recht. Ich denke über andere Möglichkeiten nach, Dateigröße zu reduzieren. –