it-swarm.asia

Menyimpan alamat IP

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?

26
Cleankod

Jangan simpan sebagai string. Gunakan kolom int unsigned Dan simpan/ambil dengan INET_ATON() dan INET_NTOA() secara berurutan. AFAIK mysql tidak mendukung INET_ * untuk ipv6.

EDIT 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.

27
Mr Shunz

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

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
7
jkj

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 dari informasi tersebut 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.

6
BillThor

Inilah jawaban terbaik yang dibuat di salah satu milis MySQL. Baca Fieldtype Terbaik 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 dapat langsung menggunakan SELECT INET_ATON('192.168.10.50'); untuk mendapatkan 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 mendapatkan 192.168.10.50 Kembali.

4
Eye

Pada MySQL v5.6.3 mereka menambahkan dukungan untuk INET6_ATON Dan INET6_NOTA Yang akan menangani alamat IPv4 dan IPv6. Tetapi mereka tidak lagi menyimpannya sebagai bilangan bulat. IPv6 mengembalikan varbinary(16) dan dan IPv4 mengembalikan varbinary(4).

http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton

2
Vizjerai

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

1
RolandoMySQLDBA

Maaf, tidak dapat mengomentari jawaban. Ada pertanyaan tentang it 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

0
rvs