Menyimpan alamat IP

25

Saya harus menyimpan alamat IP semua pengguna terdaftar dalam database. Saya bertanya-tanya, berapa banyak karakter yang harus saya nyatakan untuk kolom seperti itu?

Haruskah saya mendukung IPv6 juga? Jika demikian, berapa panjang maksimum alamat IP?

Cleankod
sumber

Jawaban:

27

Jangan simpan sebagai string. Gunakan int unsignedkolom dan simpan / ambil dengan INET_ATON()dan INET_NTOA()masing - masing. AFAIK mysql tidak mendukung INET_ * untuk ipv6.

Sunting sesuai komentar

Menggunakan fungsi bawaan untuk mengonversi IP ke / dari bilangan bulat (dan menyimpan bilangan bulat itu dalam basis data) memiliki efek samping secara otomatis memvalidasi IP tersebut. Katakanlah Anda menyimpan IP sebagai VARCHAR (16), Anda harus memastikan untuk tidak menyimpan IP yang tidak valid (seperti 999.999.999.999 sebagai contoh) dengan beberapa validasi khusus. INET_ * fungsi menangani hal itu.

Tuan Shunz
sumber
1
-1, alamat IP hingga 128 bit dan tipe integer terbesar yang didukung oleh MySQL adalah 64 bit.
Hendrik Brummermann
3
IPv4 adalah 32-bit. 128-bit untuk IPv6, yang, seperti yang ia sebutkan, hal-hal INET_ * tidak mendukung.
Richard
1
Untuk alamat IPv6, gunakan fungsi INET6_ATON () dan INET6_NTOA (), lihat contoh - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA
6

Mungkin saatnya untuk mulai mempertimbangkan IPv6. MySQL tidak memiliki metode untuk mengubah alamat IPv6 ke format biner. String empat puluh karakter akan menangani alamat IPv6 normal. Ada format yang bisa melebihi 40 karakter, saya akan menganggap itu tidak mungkin terjadi latihan.

Anda dapat menghitung ukuran sejak saat itu informasi bahwa akan ada paling banyak 8 empat kelompok karakter dengan 7 karakter pemisah. Format abnormal menggantikan dua grup terakhir dengan alamat format IPv4. Tanpa kompresi alamat, ia menggantikan 9 karakter terakhir hingga 15 karakter.

Jika Anda menyimpan blok, indikasi ukuran blok dapat mengambil 4 karakter daripada 3 karakter yang diperlukan untuk IPv4.

Anda harus memastikan pemformatan yang Anda dapatkan konsisten, tetapi semua perangkat lunak yang saya lihat memberikan format yang konsisten untuk alamat.

BillThor
sumber
2
Saya sepenuhnya setuju, IPv6 akan datang dan lebih baik untuk siap daripada menunggu seperti Y2K: D
Jeff
Tidak hanya datang, tetapi sudah ada di sistem saya.
BillThor
6

Saya menyarankan migrasi ke PostgreSQL dan penggunaan tipe data INET atau CIDR .

CREATE TABLE test ( test_id serial PRIMARY KEY, address inet );
INSERT INTO test ( address ) VALUES ( '1.2.3.4'::inet );
INSERT INTO test ( address ) VALUES ( 'a:b::c:d'::inet );
SELECT * FROM test;
 test_id | address  
---------+----------
       1 | 1.2.3.4
       2 | a:b::c:d
jkj
sumber
Untuk mendapatkan IP mana yang ada dalam jaringan SELECT * FROM test WHERE address << '1.2.3.0/24'::inet;
jkj
4

Inilah jawaban terbaik yang dibuat di salah satu milis MySQL. Baca Terbaik Fieldtype untuk menyimpan alamat IP ... .

Secara singkat itu menyarankan, yang saya kedua, untuk menggunakan INT (10) TANDA TANGAN.

  1. Ini menggunakan lebih sedikit memori (hanya 4 byte)
  2. Terbaik untuk menyortir dan mencari rentang IP, terutama jika Anda mencari negara asal pengunjung Anda.

Jadi, menggunakan 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (hasil pada 192.168.10.50)

Di MySQL, Anda bisa langsung menggunakan SELECT INET_ATON('192.168.10.50'); untuk mendapatkannya 3232238130.

Atau

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (Mundur, menghasilkan 50.10.168.192)

Di MySQL, Anda dapat langsung menggunakan SELECT INET_NTOA(3232238130); untuk 192.168.10.50kembali.

Mata
sumber
Mengesankan, +1 untuk Anda !!! Menggunakan 4 byte yang tidak ditandatangani pasti mengalahkan manipulasi string anyday.
RolandoMySQLDBA
-1, alamat IP hingga 128 bit dan tipe integer terbesar yang didukung oleh MySQL adalah 64 bit.
Hendrik Brummermann
3
nhnb, IPv6 adalah 128 bit, tetapi percakapannya tentang IPv4 yang IS 32 bit. Tidak perlu mengomentari setiap komentar / jawaban bersikeras pada pengetahuan Anda.
Mata
Jawaban Anda tidak menyebutkan bahwa itu hanya berkaitan dengan protokol internet yang lama, sedangkan pertanyaannya secara eksplisit menyebutkan IPv6 di bagian akhir. Mengingat bahwa penyedia internet walikota terakhir (setidaknya di negara saya) akan mendukung IPv6 sebelum akhir tahun ini, merupakan ide yang sangat buruk untuk merancang struktur basis data yang tidak dapat menanganinya.
Hendrik Brummermann
1

Anda dapat menyimpan hingga 15 karakter. Tolong jangan gunakan VARCHAR (15) karena itu adalah 16 byte (byte pertama mengelola panjang string dan dengan demikian pengambilan dan penyimpanan lebih lambat). Gunakan CHAR (15) selalu pada sesuatu seperti alamat IP.

RolandoMySQLDBA
sumber
Panjang maksimal alamat IP adalah 45 karakter.
Hendrik Brummermann
Apakah CHAR tidak akan menambahkannya dengan spasi?
Gayus
0

Maaf, tidak dapat mengomentari jawaban. Ada pertanyaan tentang hal itu di stackoverflow. Dan saya sangat setuju dengan jawaban yang dipilih: menggunakan 2xBIGINT mungkin merupakan cara terbaik untuk ipv6 saat ini.

Saya sarankan pergi untuk 2 * BIGINT, tetapi pastikan mereka tidak ditandatangani. Ada semacam perpecahan alami pada batas alamat / 64 di IPv6 (karena / 64 adalah ukuran netblock terkecil) yang akan selaras dengan itu.

Dimungkinkan juga untuk menyimpan ipv4 pada bigints ini - baik dengan menandai salah satunya NULL atau dengan menggunakan format V4COMPAT

rvs
sumber