Lưu trữ địa chỉ IP


25

Tôi phải lưu trữ địa chỉ IP của tất cả người dùng đã đăng ký trong cơ sở dữ liệu. Tôi tự hỏi, tôi nên khai báo bao nhiêu ký tự cho một cột như vậy?

Tôi có nên hỗ trợ IPv6 không? Nếu vậy, độ dài tối đa của địa chỉ IP là bao nhiêu?

Câu trả lời:


27

Đừng lưu trữ dưới dạng chuỗi. Sử dụng một int unsignedcột và lưu trữ / truy xuất với INET_ATON()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 đó.


1
-1, địa chỉ IP lên tới 128 bit và loại số nguyên lớn nhất được MySQL hỗ trợ là 64 bit.
Hendrik Brummermann

3
IPv4 là 32 bit. 128-bit dành cho IPv6, như ông đã đề cập, công cụ INET_ * không hỗ trợ.
Richard

1
Đối với địa chỉ IPv6, hãy sử dụng các hàm INET6_ATON () và INET6_NTOA (), xem ví dụ - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA

6

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


2
Tôi hoàn toàn đồng ý, IPv6 đang đến và tốt hơn là sẵn sàng cho nó hơn là chờ đợi nó như Y2K: D
Jeff

Không chỉ đến, mà đã ở đây trên hệ thống của tôi.
BillThor

6

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

Để có được IP nào trong mạng CHỌN * TỪ kiểm tra địa chỉ WHERE << '1.2.3.0/24'::inet;
Jkj

4

Đâ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Ý.

  1. Nó sử dụng ít bộ nhớ hơn (chỉ 4 byte)
  2. Tốt nhất để sắp xếp và tìm kiếm các dải IP, đặc biệt nếu bạn tìm quốc gia xuất xứ của khách truy cập.

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ó được 3232238130.

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ấy 192.168.10.50lại.


Ấn tượng, +1 cho bạn !!! Sử dụng 4 byte không dấu chắc chắn sẽ đánh bại chuỗi thao tác bất kỳ ngày nào.
RolandoMySQLDBA

-1, địa chỉ IP lên tới 128 bit và loại số nguyên lớn nhất được MySQL hỗ trợ là 64 bit.
Hendrik Brummermann

3
nhnb, IPv6 là 128 bit, nhưng cuộc trò chuyện là về IPv4 32 bit. Không cần bình luận về mỗi bình luận / câu trả lời nhấn mạnh vào kiến ​​thức của bạn.
Mắt

Câu trả lời của bạn không đề cập đến việc nó chỉ đề cập đến giao thức internet cũ, trong khi câu hỏi đề cập rõ ràng đến IPv6 ở cuối. Cho rằng nhà cung cấp internet thị trưởng cuối cùng (ít nhất là ở nước tôi) sẽ hỗ trợ IPv6 trước cuối năm nay, việc thiết kế một cấu trúc cơ sở dữ liệu không thể xử lý nó là một ý tưởng cực kỳ tồi tệ.
Hendrik Brummermann


1

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.


Độ dài tối đa của địa chỉ IP là 45 ký tự.
Hendrik Brummermann

CHAR sẽ không đệm nó với không gian?
Gaius

0

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.