ฉันต้องเก็บที่อยู่ IP ของผู้ใช้ที่ลงทะเบียนทั้งหมดในฐานข้อมูล ฉันสงสัยว่าฉันควรประกาศตัวละครในคอลัมน์นี้กี่ตัว?
ฉันควรสนับสนุน IPv6 ด้วยหรือไม่ ถ้าเป็นเช่นนั้นความยาวสูงสุดของที่อยู่ IP คืออะไร?
ฉันต้องเก็บที่อยู่ IP ของผู้ใช้ที่ลงทะเบียนทั้งหมดในฐานข้อมูล ฉันสงสัยว่าฉันควรประกาศตัวละครในคอลัมน์นี้กี่ตัว?
ฉันควรสนับสนุน IPv6 ด้วยหรือไม่ ถ้าเป็นเช่นนั้นความยาวสูงสุดของที่อยู่ IP คืออะไร?
คำตอบ:
อย่าเก็บเป็นสตริง ใช้int unsigned
คอลัมน์และร้านค้า / ดึงด้วยINET_ATON()
และINET_NTOA()
ตามลำดับ AFAIK mysql ไม่รองรับ INET_ * สำหรับ ipv6
แก้ไขตามความคิดเห็น
การใช้ฟังก์ชันในตัวเพื่อแปลง IP เป็น / จากจำนวนเต็ม (และเพื่อเก็บจำนวนเต็มเหล่านั้นในฐานข้อมูล) มีผลข้างเคียงของการตรวจสอบ IP เหล่านั้นโดยอัตโนมัติ สมมติว่าคุณเก็บ IP เป็น VARCHAR (16) คุณต้องแน่ใจว่าจะไม่เก็บ IP ที่ไม่ถูกต้อง (เช่น 999.999.999.999 เป็นตัวอย่าง) ด้วยการตรวจสอบที่กำหนดเอง ฟังก์ชั่น INET_ * ดูแลสิ่งนั้น
อาจเป็นเวลาที่จะเริ่มพิจารณา IPv6 MySQL ไม่มีวิธีการแปลงที่อยู่ IPv6 เป็นรูปแบบไบนารี สตริงอักขระสี่สิบตัวจะจัดการกับที่อยู่ IPv6 ปกติใด ๆ มีรูปแบบที่ยาวเกิน 40 ตัวอักษรฉันจะพิจารณาสิ่งที่ไม่น่าจะเกิดขึ้นได้
คุณสามารถคำนวณขนาดจากนั้นข้อมูลที่จะมีกลุ่มตัวละครสูงสุดสี่สี่กลุ่มที่มีตัวคั่น 7 ตัว รูปแบบที่ผิดปกติแทนที่สองกลุ่มสุดท้ายด้วยที่อยู่รูปแบบ IPv4 หากไม่มีการบีบอัดที่อยู่ระบบจะแทนที่อักขระ 9 ตัวสุดท้ายที่มีอักขระสูงสุด 15 ตัว
หากคุณกำลังเก็บบล็อกตัวบ่งชี้ขนาดบล็อกสามารถใช้อักขระ 4 ตัวแทนที่จะเป็น 3 ตัวอักษรที่จำเป็นสำหรับ IPv4
คุณควรตรวจสอบให้แน่ใจว่าการจัดรูปแบบที่คุณได้รับนั้นสอดคล้องกัน แต่ซอฟต์แวร์ทั้งหมดที่ฉันได้เห็นจะให้รูปแบบที่สอดคล้องกันสำหรับที่อยู่
ฉันขอแนะนำให้โยกย้ายไปยัง 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
นี่คือคำตอบที่ดีที่สุดที่เกิดขึ้นในรายการส่งเมลของ MySQL อ่านที่ดีที่สุด FieldType ในการจัดเก็บที่อยู่ IP ...
แนะนำสั้น ๆ ว่าฉันสองใช้ INT (10) ไม่ได้ลงนาม
ดังนั้นการใช้ 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
คืนได้ โดยตรง
ในฐานะของ 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
คุณสามารถจัดเก็บอักขระได้สูงสุด 15 ตัว โปรดอย่าใช้ VARCHAR (15) เพราะนั่นคือ 16 ไบต์ (ไบต์แรกจัดการความยาวสตริงและทำให้การดึงและการเก็บข้อมูลช้าลง) ใช้ CHAR (15) กับทุกอย่างเช่นที่อยู่ IP
ขออภัยไม่สามารถแสดงความคิดเห็นกับคำตอบ มีคำถามเกี่ยวกับเรื่องนี้ใน stackoverflow และฉันเห็นด้วยกับคำตอบที่เลือกทั้งหมด: การใช้ 2xBIGINT น่าจะเป็นวิธีที่ดีที่สุดสำหรับ ipv6 ในปัจจุบัน
ฉันขอแนะนำให้ไปที่ 2 * BIGINT แต่ให้แน่ใจว่าพวกเขายังไม่ได้ลงชื่อ มีการแบ่งตามธรรมชาติที่ขอบเขต / 64 address ใน IPv6 (เนื่องจาก / 64 เป็นขนาด netblock ที่เล็กที่สุด) ซึ่งจะจัดแนวอย่างดี
นอกจากนี้ยังเป็นไปได้ที่จะเก็บ ipv4 บน bigints นี้ - โดยทำเครื่องหมายหนึ่งในนั้นเป็น NULL หรือโดยใช้รูปแบบ V4COMPAT