Come memorizzare l'indirizzo compatibile con IPv6 in un database relazionale

StackOverflow https://stackoverflow.com/questions/420680

  •  05-07-2019
  •  | 
  •  

Domanda

Come posso farlo?

In questo momento, IPv6 non verrà utilizzato, ma devo progettare l'applicazione per renderla pronta per IPv6. È necessario memorizzare gli indirizzi IP e i blocchi CIDR (anche BGP NLRI, ma questa è un'altra storia) in un database MySQL. Ho sempre usato un INT per IPv4 + un TINYINT per masklen, ma IPv6 è a 128 bit.

Quale approccio sarà migliore per quello? 2xBIGINT ? CHAR (16) per l'archiviazione binaria? CHAR (39) per l'archiviazione del testo? 8xSMALLINT in una tabella dedicata?

Cosa consiglieresti?

È stato utile?

Soluzione

Non sono sicuro di quale sia la risposta giusta per MySQL dato che non supporta ancora i formati di indirizzi IPv6 in modo nativo (sebbene mentre " WL # 798: supporto MySQL IPv6 " suggerisce che sarebbe stato in MySQL v6.0, la documentazione attuale no ' t back up up.)

Tuttavia, tra quelli che hai proposto, suggerirei di scegliere 2 * BIGINT, ma assicurati che siano UNSIGNED. Esiste una sorta di divisione naturale al limite dell'indirizzo / 64 in IPv6 (dato che a / 64 è la dimensione del netblock più piccola) che si allineerebbe perfettamente con quella.

Altri suggerimenti

Si noti che la lunghezza massima di un indirizzo IPv6, incluso l'identificatore di ambito, è di 46 byte come definito da INET6_ADDRSTRLEN nelle intestazioni C standard. Per l'utilizzo di Internet dovresti essere in grado di ignorare identificatore di zona (% 10, # eth0, ecc.), ma fai attenzione quando getaddrinfo restituisce un risultato più lungo del previsto.

Se ti stai inclinando verso char (16), usa invece binary (16). binary (n) non ha un concetto di regole di confronto o set di caratteri (o meglio, è un carattere (n) con un set di caratteri / regole di confronto di "binario"). L'impostazione predefinita per char in mysql è latin1_swedish_ci, il che significa che tenterà l'ordinamento senza distinzione tra maiuscole e minuscole e confronti per valori di byte che sono punti di codice validi in latin1, il che causerà ogni tipo di problema imprevisto.

Un'altra opzione è quella di utilizzare zerofill decimale (39, 0) senza segno, non altrettanto efficiente di due origini (decimale utilizzerà 4 byte per nove cifre nelle versioni correnti di mysql), ma ti consentirà di mantenerlo tutto in uno colonna e stampa bene.

Vorrei scegliere l'intero 39 caratteri "standard" formato stampato: -

"2001:0db8:85a3:0000:0000:8a2e:0370:7334"

40 con un terminatore null.

Questo è il formato utilizzato dagli strumenti della riga di comando * nix e, normalmente, il formato in cui un indirizzo IPV6 è (?) riportato.

L'indirizzo IP verrà utilizzato da un programma per il quale il binario ha senso? O sarebbe meglio conservare una rappresentazione testuale? Inoltre, con IPv6, hai meno probabilità di utilizzare l'indirizzo in generale e più probabilmente di utilizzare i nomi host. Se ciò è rilevante dipende dall'applicazione, in parte. CHAR (16) sarebbe una cattiva scelta; char è per i dati dei caratteri e non gradirà i grandi stream di zero byte che sono prevalenti negli indirizzi IPv6. 2 x BIGINT sarebbe scomodo - due campi che sono davvero uno (in più è il valore memorizzato big-endian o little-endian?). Avevo usato un tipo BINARY a dimensione fissa o, se non è disponibile, un tipo BLOB.

Sto lavorando con un progetto di corrispondenza del prefisso più lungo, quindi separo l'indirizzo in 4 numeri interi per gli indirizzi IPv4. Funziona bene. Lo estenderei agli indirizzi IPv6.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top