Saya akan membuat tabel dengan dua bidang - ID
sebagai BIGINT
dan IPAddress
sebagai varchar(45)
atau varbinary(16)
. Idenya adalah untuk menyimpan semua alamat IP unik dan menggunakan referensi ID
bukan yang sebenarnya IP address
di tabel lain.
Secara umum, saya akan membuat prosedur tersimpan yang mengembalikan yang ID
diberikan IP address
atau (jika alamat tidak ditemukan) masukkan alamat dan kembalikan yang dihasilkan ID
.
Saya berharap memiliki banyak catatan (saya tidak tahu persis berapa banyak), tetapi saya perlu prosedur tersimpan di atas untuk dieksekusi secepat mungkin. Jadi, saya bertanya-tanya bagaimana cara menyimpan alamat IP yang sebenarnya - dalam format teks atau byte. Mana yang lebih baik?
Saya sudah menulis SQL CLR
fungsi untuk mengubah byte alamat IP menjadi string dan sebaliknya, jadi transformasi bukanlah masalah (bekerja dengan keduanya IPv4
dan IPv6
).
Saya kira saya perlu membuat indeks untuk mengoptimalkan pencarian, tetapi saya tidak yakin apakah saya harus memasukkan IP address
bidang ke indeks berkerumun, atau untuk membuat indeks terpisah dan dengan jenis pencarian yang akan lebih cepat?
IPv4
saya kira saya akan mengkonversi alamatINT
dan menggunakan bidang sebagai kunci indeks. Tetapi untukIPv6
saya perlu menggunakan duaBIGINT
bidang dan saya lebih suka menyimpan nilai dalam satu bidang - bagi saya lebih alami.Jawaban:
Karena "teks" di sini merujuk ke
VARCHAR(45)
dan "byte" merujukVARBINARY(16)
, saya akan mengatakan: keduanya .Diberikan informasi berikut (dari artikel Wikipedia tentang IPv6 ):
Saya akan mulai dengan menggunakan 8
VARBINARY(2)
bidang untuk mewakili 8 grup. Bidang untuk Grup 5 - 8 harusNULL
karena hanya akan digunakan untuk alamat IPv6. Bidang untuk Grup 1 - 4 harusNOT NULL
seperti yang akan digunakan untuk alamat IPv4 dan IPv6.Dengan menjaga masing-masing kelompok mandiri (sebagai lawan menggabungkan mereka ke dalam satu
VARCHAR(45)
atau duaVARBINARY(16)
atau bahkan duaBIGINT
bidang) Anda mendapatkan dua manfaat utama:IF
/IIF
/CASE
pernyataan sederhana untuk memfasilitasi ini.ROW COMPRESSION
atauPAGE COMPRESSION
. Karena kedua jenis KOMPRESI akan memungkinkan untuk bidang yang0x00
mengambil 0 byte, semua kelompok nol itu sekarang tidak akan dikenakan biaya apa pun. Di sisi lain, jika Anda menyimpan contoh alamat dari atas (dalam kutipan Wikipedia), maka 3 set semua nol di tengah akan mengambil jumlah penuh ruang mereka (kecuali jika Anda melakukanVARCHAR(45)
dan pergi dengan notasi berkurang) , tapi itu mungkin tidak berfungsi dengan baik untuk pengindeksan dan akan membutuhkan parsing khusus untuk merekonstruksi ke format penuh, jadi mari kita asumsikan itu bukan pilihan ;-).JIKA Anda perlu menangkap Jaringan, buat
TINYINT
bidang untuk yang disebut, um,[Network]
:-)Untuk info lebih lanjut tentang nilai Jaringan, berikut adalah beberapa info dari artikel Wikipedia lain di alamat IPv6 :
Untuk pengindeksan, saya akan mengatakan membuat indeks Non-Clustered pada bidang 8 Grup, dan mungkin bidang Jaringan jika Anda memutuskan untuk memasukkan itu.
Hasil akhirnya harus seperti ini:
Catatan:
BIGINT
untuk bidang ID, tetapi apakah Anda benar-benar berharap untuk mendapatkan lebih dari 4.294.967.295 nilai unik? Jika demikian maka ubah saja bidang menjadi BIGINT dan Anda bahkan dapat mengubah nilai seed menjadi 0. Tetapi sebaliknya Anda lebih baik menggunakan INT dan mulai dengan nilai minimum sehingga Anda dapat menggunakan seluruh rentang datatype tersebut. .SELECT *
akan mengembalikan bidang dalam urutan yang diharapkan. Tapi indeks membuat mereka naik , dari 1 menjadi 8, karena begitulah mereka diisi.Contoh (belum selesai) dari kolom yang dihitung untuk mewakili nilai-nilai dalam bentuk teks adalah:
Uji:
Hasil:
sumber
VARDECIMAL
selesaiVARBINARY
karenaDATA_COMPRESSION
tidak tersedia?BINARY(16)
;-). Bisakah Anda memberi saya contoh dengan rentang awal / akhir dan setidaknya dua baris yang Anda dapatkan kembali, satu valid dan setidaknya satu tidak valid? Mungkin VARbinary mempersingkat beberapa nilai.Lebih kecil selalu akan lebih cepat. Dengan nilai yang lebih kecil Anda dapat memasukkan lebih banyak dari mereka ke dalam satu halaman, sehingga lebih sedikit IO, berpotensi lebih dangkal B-Trees dll.
Semua hal lain (terjemahan overhead, keterbacaan, kompatibilitas, beban CPU, indeks sargabilitas dll) sama, tentu saja.
sumber