Ich werde eine Tabelle mit zwei Feldern erstellen - ID
als BIGINT
und IPAddress
als entweder varchar(45)
oder varbinary(16)
. Die Idee ist, alle eindeutigen IP-Adressen zu speichern und ID
stattdessen eine Referenz zu verwenden, die IP address
in anderen Tabellen tatsächlich ist .
Im Allgemeinen werde ich eine gespeicherte Prozedur erstellen, die die ID
angegebene zurückgibt IP address
oder (falls die Adresse nicht gefunden wurde) die Adresse einfügt und die generierte zurückgibt ID
.
Ich erwarte viele Datensätze (ich kann nicht genau sagen, wie viele), aber ich muss die oben gespeicherte Prozedur so schnell wie möglich ausführen. Ich frage mich also, wie ich die tatsächliche IP-Adresse speichern soll - im Text- oder Byte-Format. Welches wird besser?
Ich habe bereits SQL CLR
Funktionen zum Transformieren von IP-Adressbytes in Zeichenfolgen und umgekehrt geschrieben, sodass die Transformation kein Problem darstellt (Arbeiten mit beiden IPv4
und IPv6
).
Ich denke, ich muss einen Index erstellen, um die Suche zu optimieren, aber ich bin nicht sicher, ob ich das IP address
Feld in den Clustered-Index aufnehmen oder einen separaten Index erstellen soll und mit welchem Typ die Suche schneller sein wird.
IPv4
wäre, würde ich die Adresse in konvertierenINT
und das Feld als Indexschlüssel verwenden. Aber dennIPv6
ich muss zweiBIGINT
Felder verwenden und ich bevorzuge es, den Wert in einem Feld zu speichern - scheint mir natürlicher.Antworten:
Da sich "Text" hier auf
VARCHAR(45)
und "Bytes" beziehtVARBINARY(16)
, würde ich sagen: weder .Angesichts der folgenden Informationen (aus dem Wikipedia-Artikel zu IPv6 ):
Ich würde damit beginnen, 8
VARBINARY(2)
Felder zu verwenden, um die 8 Gruppen darzustellen. Die Felder für die Gruppen 5 bis 8 sollten so sein, dassNULL
sie nur für IPv6-Adressen verwendet werden. Die Felder für die Gruppen 1 bis 4 sollten so sein,NOT NULL
wie sie sowohl für IPv4- als auch für IPv6-Adressen verwendet werden.Wenn Sie jede Gruppe unabhängig halten (anstatt sie in einem
VARCHAR(45)
oder einemVARBINARY(16)
oder sogar zweiBIGINT
Feldern zu kombinieren ), erhalten Sie zwei Hauptvorteile:IF
/IIF
/CASE
Anweisungen verwendet werden, um dies zu erleichtern.ROW COMPRESSION
oder aktivierenPAGE COMPRESSION
. Da beide Arten der KOMPRESSION Felder zulassen0x00
, die 0 Byte belegen sollen , kosten Sie all diese Nullengruppen jetzt nichts mehr. Wenn Sie dagegen die Beispieladresse von oben (im Wikipedia-Zitat) gespeichert haben, nehmen die 3 Sätze aller Nullen in der Mitte ihren vollen Platz ein (es sei denn, Sie haben das getanVARCHAR(45)
und die reduzierte Notation verwendet , aber das funktioniert möglicherweise nicht gut für die Indizierung und erfordert eine spezielle Analyse, um es in das vollständige Format zu rekonstruieren. Nehmen wir also an, dass dies keine Option ist ;-).Wenn Sie das Netzwerk erfassen müssen, erstellen Sie ein
TINYINT
Feld mit dem Namen, ähm,[Network]
:-)Weitere Informationen zum Netzwerkwert finden Sie in einem anderen Wikipedia-Artikel zur IPv6-Adresse :
Für die Indizierung würde ich sagen, dass Sie einen nicht gruppierten Index für die 8 Gruppenfelder und möglicherweise das Netzwerkfeld erstellen, wenn Sie dies einschließen möchten.
Das Endergebnis sollte ungefähr so aussehen:
Anmerkungen:
BIGINT
für das ID-Feld verwenden möchten, aber erwarten Sie wirklich, dass mehr als 4.294.967.295 eindeutige Werte erfasst werden? Wenn ja, ändern Sie einfach das Feld in BIGINT und Sie können sogar den Startwert in 0 ändern. Andernfalls ist es besser, INT zu verwenden und mit dem Mindestwert zu beginnen, damit Sie den gesamten Bereich dieses Datentyps nutzen können .SELECT *
wird , die Felder in der erwarteten Reihenfolge zurück. Aber der Index gehen sie nach oben , von 1 bis 8, wie das ist , wie sie ausgefüllt sind.Ein Beispiel (unvollendet) einer berechneten Spalte zur Darstellung der Werte in Textform ist:
Prüfung:
Ergebnis:
quelle
VARDECIMAL
überVARBINARY
daDATA_COMPRESSION
ist nicht verfügbar?BINARY(16)
;-). Können Sie mir bitte ein Beispiel mit einem Start- / Endbereich und mindestens zwei Zeilen geben, die Sie zurückerhalten, eine gültige und mindestens eine ungültige? Es kann sein, dass VARbinary einige Werte verkürzt.Kleiner wird immer schneller sein. Mit kleineren Werten können Sie mehr davon in eine einzelne Seite einfügen, daher weniger E / A, möglicherweise flachere B-Bäume usw.
Alle anderen Dinge (Übersetzungsaufwand, Lesbarkeit, Kompatibilität, CPU-Auslastung, Index-Sargabilität usw.) sind natürlich gleich.
quelle