กำลังจัดเก็บที่อยู่ IP


25

ฉันต้องเก็บที่อยู่ IP ของผู้ใช้ที่ลงทะเบียนทั้งหมดในฐานข้อมูล ฉันสงสัยว่าฉันควรประกาศตัวละครในคอลัมน์นี้กี่ตัว?

ฉันควรสนับสนุน IPv6 ด้วยหรือไม่ ถ้าเป็นเช่นนั้นความยาวสูงสุดของที่อยู่ IP คืออะไร?

คำตอบ:


27

อย่าเก็บเป็นสตริง ใช้int unsignedคอลัมน์และร้านค้า / ดึงด้วยINET_ATON()และINET_NTOA()ตามลำดับ AFAIK mysql ไม่รองรับ INET_ * สำหรับ ipv6

แก้ไขตามความคิดเห็น

การใช้ฟังก์ชันในตัวเพื่อแปลง IP เป็น / จากจำนวนเต็ม (และเพื่อเก็บจำนวนเต็มเหล่านั้นในฐานข้อมูล) มีผลข้างเคียงของการตรวจสอบ IP เหล่านั้นโดยอัตโนมัติ สมมติว่าคุณเก็บ IP เป็น VARCHAR (16) คุณต้องแน่ใจว่าจะไม่เก็บ IP ที่ไม่ถูกต้อง (เช่น 999.999.999.999 เป็นตัวอย่าง) ด้วยการตรวจสอบที่กำหนดเอง ฟังก์ชั่น INET_ * ดูแลสิ่งนั้น


1
-1, ที่อยู่ IP สูงถึง 128 บิตและประเภทจำนวนเต็มที่ใหญ่ที่สุดที่สนับสนุนโดย MySQL คือ 64 บิต
Hendrik Brummermann

3
IPv4คือ 32 บิต 128- บิตสำหรับ IPv6 ซึ่งสิ่งที่เขากล่าวถึงสิ่งที่ INET_ * ไม่สนับสนุน
ริชาร์ด

1
สำหรับที่อยู่ IPv6 ใช้ INET6_ATON () และ INET6_NTOA () ฟังก์ชั่นดูตัวอย่าง - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA

6

อาจเป็นเวลาที่จะเริ่มพิจารณา IPv6 MySQL ไม่มีวิธีการแปลงที่อยู่ IPv6 เป็นรูปแบบไบนารี สตริงอักขระสี่สิบตัวจะจัดการกับที่อยู่ IPv6 ปกติใด ๆ มีรูปแบบที่ยาวเกิน 40 ตัวอักษรฉันจะพิจารณาสิ่งที่ไม่น่าจะเกิดขึ้นได้

คุณสามารถคำนวณขนาดจากนั้นข้อมูลที่จะมีกลุ่มตัวละครสูงสุดสี่สี่กลุ่มที่มีตัวคั่น 7 ตัว รูปแบบที่ผิดปกติแทนที่สองกลุ่มสุดท้ายด้วยที่อยู่รูปแบบ IPv4 หากไม่มีการบีบอัดที่อยู่ระบบจะแทนที่อักขระ 9 ตัวสุดท้ายที่มีอักขระสูงสุด 15 ตัว

หากคุณกำลังเก็บบล็อกตัวบ่งชี้ขนาดบล็อกสามารถใช้อักขระ 4 ตัวแทนที่จะเป็น 3 ตัวอักษรที่จำเป็นสำหรับ IPv4

คุณควรตรวจสอบให้แน่ใจว่าการจัดรูปแบบที่คุณได้รับนั้นสอดคล้องกัน แต่ซอฟต์แวร์ทั้งหมดที่ฉันได้เห็นจะให้รูปแบบที่สอดคล้องกันสำหรับที่อยู่


2
ฉันเห็นด้วยอย่างเต็มที่ว่า IPv6 กำลังจะมาและมันจะดีกว่าที่จะพร้อมสำหรับมันมากกว่าที่จะรอมันเหมือน Y2K: D
Jeff

ไม่เพียง แต่จะมา แต่อยู่ที่นี่ในระบบของฉัน
BillThor

6

ฉันขอแนะนำให้โยกย้ายไปยัง PostgreSQL และใช้ชนิดข้อมูลINET หรือ 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

ในการรับไอพีใดที่อยู่ในเครือข่ายSELECT * จากการทดสอบ WHERE address << '1.2.3.0/24'::inet;
jkj

4

นี่คือคำตอบที่ดีที่สุดที่เกิดขึ้นในรายการส่งเมลของ MySQL อ่านที่ดีที่สุด FieldType ในการจัดเก็บที่อยู่ IP ...

แนะนำสั้น ๆ ว่าฉันสองใช้ INT (10) ไม่ได้ลงนาม

  1. ใช้หน่วยความจำน้อยกว่า (4 ไบต์เท่านั้น)
  2. ดีที่สุดสำหรับการเรียงลำดับและค้นหาช่วง IP โดยเฉพาะถ้าคุณมองหาประเทศต้นทางของผู้เข้าชม

ดังนั้นการใช้ 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (ผลลัพธ์ใน 192.168.10.50)

ใน MySQL คุณสามารถใช้ SELECT INET_ATON('192.168.10.50'); เพื่อรับ 3232238130โดยตรง

หรือ

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (ย้อนหลังส่งผลให้ 50.10.168.192)

ใน MySQL คุณสามารถใช้ SELECT INET_NTOA(3232238130); เพื่อรับ192.168.10.50คืนได้ โดยตรง


น่าประทับใจ +1 สำหรับคุณ !!! การใช้ 4 ไบต์ไม่ได้ลงนามแน่ใจว่าการจัดการสตริงเต้นทุกวัน
RolandoMySQLDBA

-1, ที่อยู่ IP สูงถึง 128 บิตและประเภทจำนวนเต็มที่ใหญ่ที่สุดที่สนับสนุนโดย MySQL คือ 64 บิต
Hendrik Brummermann

3
nhnb, IPv6 คือ 128 บิต แต่การสนทนานั้นเกี่ยวกับ IPv4 ซึ่งเป็น 32 บิต ไม่จำเป็นต้องแสดงความคิดเห็นในแต่ละความคิดเห็น / ตอบยืนยันความรู้ของคุณ
ตา

คำตอบของคุณไม่ได้กล่าวถึงว่าจะเกี่ยวข้องกับโปรโตคอลอินเทอร์เน็ตเก่าเท่านั้นในขณะที่คำถามดังกล่าวระบุ IPv6 ในตอนท้าย ระบุว่าผู้ให้บริการอินเทอร์เน็ตนายกเทศมนตรีคนสุดท้าย (อย่างน้อยในประเทศของฉัน) จะสนับสนุน IPv6 ก่อนสิ้นปีนี้เป็นความคิดที่แย่มากในการออกแบบโครงสร้างฐานข้อมูลที่ไม่สามารถจัดการได้
Hendrik Brummermann

2

ในฐานะของ MySQL v5.6.3 พวกเขาเพิ่มการสนับสนุนINET6_ATONและINET6_NOTAจะดูแลที่อยู่ IPv4 และ IPv6 แต่พวกเขาจะไม่เก็บเป็นจำนวนเต็มอีกต่อไป IPv6 ส่งกลับvarbinary(16)และ IPv4 varbinary(4)และส่งกลับ

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


1

คุณสามารถจัดเก็บอักขระได้สูงสุด 15 ตัว โปรดอย่าใช้ VARCHAR (15) เพราะนั่นคือ 16 ไบต์ (ไบต์แรกจัดการความยาวสตริงและทำให้การดึงและการเก็บข้อมูลช้าลง) ใช้ CHAR (15) กับทุกอย่างเช่นที่อยู่ IP


ความยาวสูงสุดของที่อยู่ IP คือ 45 ตัวอักษร
Hendrik Brummermann

CHAR จะไม่อัดมันด้วยช่องว่างหรือไม่?
ออกุสตุส

0

ขออภัยไม่สามารถแสดงความคิดเห็นกับคำตอบ มีคำถามเกี่ยวกับเรื่องนี้ใน stackoverflow และฉันเห็นด้วยกับคำตอบที่เลือกทั้งหมด: การใช้ 2xBIGINT น่าจะเป็นวิธีที่ดีที่สุดสำหรับ ipv6 ในปัจจุบัน

ฉันขอแนะนำให้ไปที่ 2 * BIGINT แต่ให้แน่ใจว่าพวกเขายังไม่ได้ลงชื่อ มีการแบ่งตามธรรมชาติที่ขอบเขต / 64 address ใน IPv6 (เนื่องจาก / 64 เป็นขนาด netblock ที่เล็กที่สุด) ซึ่งจะจัดแนวอย่างดี

นอกจากนี้ยังเป็นไปได้ที่จะเก็บ ipv4 บน bigints นี้ - โดยทำเครื่องหมายหนึ่งในนั้นเป็น NULL หรือโดยใช้รูปแบบ V4COMPAT

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.