Câu trả lời:
Đừng lưu trữ dưới dạng chuỗi. Sử dụng một int unsigned
cột và lưu trữ / truy xuất với INET_ATON()
và INET_NTOA()
tương ứng. AFAIK mysql không hỗ trợ INET_ * cho ipv6.
EDIT theo nhận xét
Sử dụng chức năng tích hợp để chuyển đổi IP thành / từ số nguyên (và do đó lưu trữ các số nguyên đó trong cơ sở dữ liệu) có tác dụng phụ là tự động xác thực các IP đó. Giả sử bạn lưu trữ IP dưới dạng VARCHAR (16), bạn phải đảm bảo không lưu trữ IP không hợp lệ (như 999.999.999.999 làm ví dụ) với một số xác thực tùy chỉnh. Các hàm INET_ * đảm nhiệm việc đó.
Có lẽ đã đến lúc bắt đầu xem xét IPv6. MySQL không có phương pháp để chuyển đổi địa chỉ IPv6 sang định dạng nhị phân. Một chuỗi bốn mươi ký tự sẽ xử lý bất kỳ địa chỉ IPv6 bình thường. Có một định dạng có thể vượt quá 40 ký tự, tôi sẽ xem xét những điều không thể xảy ra trong thực tế.
Bạn có thể tính kích thước từ đó thông tin sẽ có tối đa 8 nhóm bốn ký tự với 7 ký tự phân cách. Định dạng bất thường thay thế hai nhóm cuối cùng bằng địa chỉ định dạng IPv4. Không nén địa chỉ, nó thay thế 9 ký tự cuối cùng với tối đa 15 ký tự.
Nếu bạn đang lưu trữ các khối, chỉ báo kích thước khối có thể mất 4 ký tự thay vì 3 ký tự được yêu cầu cho IPv4.
Bạn nên đảm bảo định dạng bạn nhận được là nhất quán, nhưng tất cả các phần mềm tôi đã thấy cung cấp các định dạng nhất quán cho các địa chỉ.
Tôi khuyên bạn nên di chuyển sang PostgreSQL và sử dụng các loại dữ liệu INET hoặc 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
Đây là câu trả lời tốt nhất được thực hiện trong một trong các danh sách gửi thư của MySQL. Đọc nhất Fieldtype để lưu trữ địa chỉ IP ... .
Tóm lại, nó gợi ý, mà tôi thứ hai, sử dụng INT (10) KHÔNG ĐƯỢC KÝ.
Vì vậy, sử dụng 192.168.10.50:
(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (kết quả trong 192.168.10.50)
Trong MySQL, bạn có thể trực tiếp sử dụng
SELECT INET_ATON('192.168.10.50');
để có được3232238130
.
Hoặc là
192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (Ngược lại, kết quả là 50.10.168.192)
Trong MySQL, bạn có thể trực tiếp sử dụng
SELECT INET_NTOA(3232238130);
để lấy192.168.10.50
lại.
Kể từ MySQL v5.6.3, họ đã thêm hỗ trợ INET6_ATON
và INET6_NOTA
điều đó sẽ chăm sóc các địa chỉ IPv4 và IPv6. Nhưng họ không còn lưu trữ nó như một số nguyên. IPv6 trả về a varbinary(16)
và IPv4 trả về a varbinary(4)
.
http://dev.mysql.com/doc/refman/5.6/en/misiverse-fifts.html#feft_inet6-aton
Bạn có thể lưu trữ tối đa 15 characaters. Vui lòng không sử dụng VARCHAR (15) vì đó là 16 byte (byte đầu tiên quản lý độ dài chuỗi và do đó việc truy xuất và lưu trữ chậm hơn). Sử dụng CHAR (15) luôn trên một cái gì đó như địa chỉ IP.
Xin lỗi, không thể nhận xét về câu trả lời. Có một câu hỏi về nó trên stackoverflow. Và tôi hoàn toàn đồng ý với câu trả lời được chọn: sử dụng 2xBIGINT có lẽ là cách tốt nhất cho ipv6 hiện tại.
Tôi khuyên bạn nên chọn 2 * BIGINT, nhưng hãy chắc chắn rằng họ KHÔNG ĐƯỢC KÝ. Có một sự phân chia tự nhiên tại ranh giới địa chỉ / 64 trong IPv6 (vì a / 64 là kích thước mạng nhỏ nhất) sẽ phù hợp với điều đó.
Cũng có thể lưu trữ ipv4 trên các gợi ý này - bằng cách đánh dấu một trong số chúng NULL hoặc bằng cách sử dụng định dạng V4COMPAT