Jenis data apa yang harus saya pilih untuk menyimpan Alamat IP di SQL Server?
Dengan memilih tipe data yang tepat, apakah cukup mudah untuk memfilter berdasarkan alamat IP?
Jenis data apa yang harus saya pilih untuk menyimpan Alamat IP di SQL Server?
Dengan memilih tipe data yang tepat, apakah cukup mudah untuk memfilter berdasarkan alamat IP?
Jawaban:
Cara yang benar secara teknis untuk menyimpan IPv4 adalah biner (4), karena memang demikian adanya (tidak, bahkan bukan INT32 / INT (4), bentuk tekstual numerik yang kita semua kenal dan sukai (255.255.255.255) adalah adil konversi tampilan konten binernya).
Jika Anda melakukannya dengan cara ini, Anda akan menginginkan fungsi untuk dikonversi ke dan dari format tampilan tekstual:
Berikut cara mengubah bentuk tampilan tekstual menjadi biner:
Dan inilah cara mengubah biner kembali ke bentuk tampilan tekstual:
Berikut demo cara menggunakannya:
Terakhir, saat melakukan pencarian dan perbandingan, selalu gunakan bentuk biner jika Anda ingin dapat memanfaatkan indeks Anda.
MEMPERBARUI:
Saya ingin menambahkan bahwa salah satu cara untuk mengatasi masalah kinerja bawaan dari UDF skalar di SQL Server, tetapi masih mempertahankan penggunaan kembali kode dari suatu fungsi adalah dengan menggunakan iTVF (fungsi bernilai tabel sebaris) sebagai gantinya. Berikut ini bagaimana fungsi pertama di atas (string ke biner) dapat ditulis ulang sebagai iTVF:
Ini dia dalam contoh:
Dan inilah cara Anda menggunakannya dalam INSERT
sumber
Anda dapat menggunakan varchar. Panjang IPv4 statis, tetapi IPv6 mungkin sangat bervariasi.
Kecuali jika Anda memiliki alasan kuat untuk menyimpannya sebagai biner, tetap gunakan tipe string (tekstual).
sumber
Berikut adalah beberapa kode untuk mengonversi IPV4 atau IPv6 dalam format varchar ke biner (16) dan sebaliknya. Ini adalah bentuk terkecil yang dapat saya pikirkan. Ini harus mengindeks dengan baik dan menyediakan cara yang relatif mudah untuk memfilter subnet. Membutuhkan SQL Server 2005 atau yang lebih baru. Tidak yakin itu benar-benar antipeluru. Semoga ini membantu.
sumber
fn_ConvertIpAddressToBinary
. Lihat jawaban C. Lock dan jawaban saya .Karena saya ingin menangani keduanya
IPv4
danIPv6
, saya menggunakanVARBINARY(16)
danSQL CLR
fungsi berikut untuk mengubahtext
presentasi alamat IP menjadi byte dan sebaliknya:sumber
Bagi orang yang menggunakan .NET dapat menggunakan kelas IPAddress untuk mengurai string IPv4 / IPv6 dan menyimpannya sebagai file
VARBINARY(16)
. Dapat menggunakan kelas yang sama untuk dikonversibyte[]
menjadi string. Jika ingin mengonversiVARBINARY
dalam SQL:sumber
sys.dm_exec_connections
menggunakan varchar (48) setelah SQL Server 2005 SP1. Kedengarannya cukup bagus untuk saya terutama jika Anda ingin menggunakannya dibandingkan dengan nilai Anda.Secara realistis, Anda tidak akan melihat IPv6 sebagai arus utama untuk sementara waktu, jadi saya lebih suka rute 4 tinyint. Mengatakan itu, saya menggunakan varchar (48) karena saya harus menggunakan
sys.dm_exec_connections
...Jika tidak. Jawaban Mark Redman menyebutkan pertanyaan
debatSO sebelumnya .sumber
Terima kasih RBarry. Saya menyusun sistem alokasi blok IP dan menyimpan sebagai biner adalah satu-satunya cara untuk melakukannya.
Saya menyimpan representasi CIDR (mis .: 192.168.1.0/24) dari blok IP di bidang varchar, dan menggunakan 2 bidang terhitung untuk menampung bentuk biner dari awal dan akhir blok. Dari sana, saya dapat menjalankan kueri cepat untuk melihat apakah blok yang diberikan telah dialokasikan atau bebas untuk ditetapkan.
Saya memodifikasi fungsi Anda untuk menghitung Alamat IP akhir seperti:
sumber
Saya biasanya menggunakan penyaringan VARCHAR lama biasa untuk IPAddress berfungsi dengan baik.
Jika Anda ingin memfilter rentang alamat IP, saya akan membaginya menjadi empat bilangan bulat.
sumber
Saya suka fungsi SandRock. Tetapi saya menemukan kesalahan pada kode dbo.fn_ConvertIpAddressToBinary . Parameter masuk dari @ipAddress VARCHAR (39) terlalu kecil saat Anda menggabungkan @delim ke dalamnya.
Anda bisa meningkatkannya menjadi 40. Atau lebih baik lagi gunakan variabel baru yang lebih besar dan gunakan itu secara internal. Dengan begitu Anda tidak kehilangan pasangan terakhir dalam jumlah besar.
sumber
Jawaban berikut ini berdasarkan jawaban M. Turnhout dan Jerry Birchler atas pertanyaan ini tetapi dengan perbaikan berikut:
sys.fn_varbintohexsubstring
,fn_varbintohexstr
) denganCONVERT()
untuk gaya binerCAST('' as xml).value('xs:hexBinary())
) denganCONVERT()
untuk gaya binerfn_ConvertIpAddressToBinary
(sebagai keluar menunjuk oleh C.Plock )Kode telah diuji di SQL Server 2014 dan SQL Server 2016 (lihat kasus uji di bagian akhir)
IPAddressVarbinaryToString
Mengonversi nilai 4 byte menjadi IPV4 dan nilai 16 byte menjadi representasi string IPV6 . Perhatikan bahwa fungsi ini tidak mempersingkat alamat.
Kasus Uji:
IPAddressStringToVarbinary
Mengonversi representasi string IPV4 dan IPV6 menjadi nilai biner 4 byte dan 16 byte. Perhatikan bahwa fungsi ini dapat mengurai sebagian besar (semua yang umum digunakan) dari representasi alamat singkatan (misalnya 127 ... 1 dan 2001: db8 :: 1319: 370: 7348). Untuk memaksa fungsi menipiskan agar selalu mengembalikan nilai biner 16 byte, hapus komentar yang memimpin penggabungan 0 di akhir fungsi.
Kasus Uji
Kasus yang valid
Kasus tidak valid
sumber
Saya menggunakan
varchar(15)
sejauh ini semuanya bekerja untuk saya. Sisipkan, Perbarui, Pilih. Saya baru saja memulai aplikasi yang memiliki Alamat IP, meskipun saya belum melakukan banyak pekerjaan pengembang.Berikut adalah pernyataan pilih:
sumber