จะทำอย่างไรเมื่อเขตข้อมูลในตารางใกล้จำนวนสูงสุด 32 บิตหรือไม่ได้ลงนาม?


14

ในฐานข้อมูลที่กำหนดใด ๆ ที่เก็บบันทึกผู้ใช้ในรูปแบบของฟิลด์การเพิ่มอัตโนมัติที่ไม่ซ้ำกัน (เพื่อประโยชน์ของตัวอย่างข้อความระหว่างผู้ใช้) ... จะทำอย่างไรเมื่อถึงเวลาและใกล้ถึงจำนวนสูงสุดที่ลงนามหรือไม่ได้ลงนาม ชนิดข้อมูลปัจจุบัน (INT 32- บิต) ฉันเดาว่าเซิร์ฟเวอร์ฐานข้อมูลจะล้นเมื่อพยายามกำหนดหมายเลข (2∧32) -1 ให้กับรายการถัดไปดังนั้นวิธีหลีกเลี่ยงเหตุการณ์นั้น (โดยไม่ต้องเปลี่ยนประเภทข้อมูลเพื่อประโยชน์ของคำถาม) และ เพิ่มระเบียนต่อไปไหม คุณจะทำอย่างไร

ทำไมฉันถึงต้องใช้ INT และไม่ใช้ตัวอย่างเช่น VARCHARS

หลายวันแล้วที่ฉันถามคำถามสมมุตินี้กับตัวเองและฉันอยากจะรู้ว่ามืออาชีพทำอะไร

คำตอบ:


12

โดยทั่วไปคุณจะใช้จำนวนเต็มมากกว่า varchars เพราะใช้พื้นที่น้อยกว่ามีรูปแบบการเรียงที่เข้าใจได้ง่ายในการจัดทำดัชนีเป็นต้นจำนวนเต็มเป็นประเภทข้อมูลตามธรรมชาติของ CPU ดังนั้นประสิทธิภาพจึงเหมาะสมที่สุด โดยทั่วไปแล้วจำนวนเต็มคือ 4 ไบต์เทียบเท่ากับเพียง 4 ตัวอักษรใน varchar (ไม่ใช่ยูนิโค้ด)

หากคุณกังวลว่าพื้นที่ในประเภท INT จะหมดให้ลองใช้ BIGINT ซึ่งจะให้ตัวเลข 8 ไบต์ ข้อ จำกัด ในเรื่องนี้ค่อนข้างใหญ่และคุณอาจหมดพื้นที่ดิสก์ก่อนที่คุณจะถึงขีด จำกัด ของเรคคอร์ด :-) ประสิทธิภาพของ BIGINT ก็จะดีเช่นกันโดยเฉพาะอย่างยิ่งเมื่อเซิร์ฟเวอร์จำนวนมากตอนนี้ 64- บิตเช่นกัน .

คำตอบสำหรับคำถามแรกของคุณเกี่ยวกับสิ่งที่เกิดขึ้นเมื่อคุณหมดใน INT ไม่ใช่เรื่องง่ายโดยเฉพาะอย่างยิ่งที่คุณพูดโดยไม่เปลี่ยนประเภทข้อมูลเป็น BIGINT โดยทั่วไปคุณสามารถทำอะไรได้ไม่มากและสิ่งที่คุณสามารถทำได้นั้นมี จำกัด มากโดยธรรมชาติของข้อมูลในฐานข้อมูลของคุณ เร็กคอร์ดใดที่เป็นข้อมูลสำคัญต่างประเทศสำหรับข้อมูลนี้ คุณยังต้องการข้อมูลทั้งหมดในตารางนั้นและระเบียนที่เกี่ยวข้องหรือไม่ บนสมมติฐานที่ว่าคุณสามารถเก็บถาวรข้อมูลเริ่มต้นจำนวนมาก (และข้อมูลที่เกี่ยวข้อง) จากนั้นสิ่งเดียวที่ฉันสามารถแนะนำคือย้ายข้อมูลออกจากตาราง (สมมติว่า 1 ถึง X ล้านระเบียนแรก) จากนั้น การรีเซ็ตเมล็ดพันธุ์เอกลักษณ์เป็น 1 มีเหตุผลหลายประเภทแม้ว่าฉันจะไม่แนะนำ - เช่นมีหลายบิตของรหัสที่ฉันได้เห็นว่าทำสิ่งต่าง ๆ เช่นตรวจสอบค่าสูงสุดของเขตข้อมูล id เพื่อดูสิ่งที่เพิ่งถูกเพิ่มเข้ามาและนั่นจะไม่ทำงาน (และไม่ควรทำ) นอกจากนี้ผู้คนสมมติว่าระเบียน N ถูกสร้างขึ้นก่อน N + 1 ไม่มีคำตอบที่ง่ายฉันคิดว่า

ในที่สุดฉันไม่รู้เกี่ยวกับ MySQL แต่ SQL Server จะให้ข้อผิดพลาดมากเกินไปหากคุณถึงขีด จำกัด


1
ฉันยินดีกับคำตอบอย่างละเอียด ขอบคุณสำหรับคำอธิบายของ VARCHAR, INT และ BIGINT deal เนื่องจากคำถามนั้นเป็นสมมติฐานฉันสงสัยว่าจะเกิดอะไรขึ้นถ้าถึงขีด จำกัด BIGINT คำถามนั้นเกิดจากการโพสต์ที่ฉันเห็นเกี่ยวกับ Facebook โดยใช้ INT และถึงขีด จำกัด และฉันเห็นว่าเป็นไปได้โดยสิ้นเชิง การเก็บถาวรจะใช้งานได้หรือสร้างตารางที่สองด้วยคำสั่งแบบมีเงื่อนไข (ซึ่งตามที่คุณบอกว่าจะต้องมีการอัปเดตสคริปต์ด้วยและมันก็ค่อนข้างซับซ้อน) โดยรวมแล้วคำตอบที่ดี ฉันซาบซึ้งเวลาที่ใช้
AeroCross

9

สิ่งหนึ่งที่ถูกมองข้ามก็คือชาวบ้านจำนวนมากเริ่มหมายเลขอัตโนมัติหรืออัตลักษณ์ที่ 1 ดังนั้นจึงเสียช่วงครึ่งที่เป็นไปได้ทันที (สำหรับเซ็นชื่อ)

คุณเพียงแค่กำหนดหมายเลขใหม่เพื่อเริ่มต้นที่ -1 เพิ่มขึ้น -1 ในกรณีนี้

หากคุณคาดว่าจะเติมคอลัมน์ข้อมูลประจำตัวของคุณคุณควรออกแบบและใช้ประเภทข้อมูลที่กว้างขึ้นตั้งแต่เริ่มต้น

ดูคำถามล่าสุดนี้เมื่อ: SQL Server 2008: เกิดอะไรขึ้นถ้า identity เกินค่าสูงสุดของ int?


มันมีเหตุผลที่ฉันจะใช้ประเภทข้อมูลที่กว้างกว่า (สำหรับตารางที่มีปริมาณข้อมูลแบบนั้น) แต่เนื่องจากเป็นคำถามสมมุติฉันจึงต้องการความเข้าใจที่ลึกซึ้ง หากมีการเซ็นชื่อนั่นอาจใช้ได้ (แต่ฉันแปลกเล็กน้อยที่มีคีย์หลักที่มีตัวเลขติดลบ IMHO) และฉันคิดว่ามันค่อนข้างฉลาด มันให้เวลาสำหรับ DBA เพื่อเก็บข้อมูลเชิงบวกและเริ่มใหม่อีกครั้ง หากไม่ได้ลงนามก็ดีปัญหา ...
AeroCross

อีกวิธีหนึ่งคือใช้การเพิ่มค่า -1 จาก -1 เริ่มต้นที่ (-2147483648) และเพิ่มขึ้น 1 แต่ใช่หลังจากคุณข้าม INT_MAX แล้วคุณจะถูกแขวนไว้อย่างดีและต้องกลับมาออกแบบใหม่และลบดัชนีเก่ามาแทนที่ กับอันที่ใหญ่กว่าใหม่ และถ้าคุณผ่าน BIGINT ที่ไม่ได้ลงชื่อฉันต้องการทำงานกับทีมของคุณ;)
jcolebrand

PostgreSQL ใช้ลำดับเพื่อสร้างหมายเลข id คำสั่ง CREATE SEQUENCE ให้คุณระบุ CYCLE ซึ่งจะล้อมรอบหากคุณถึงค่าสูงสุด (หรือค่าต่ำสุดถ้าคุณไปในทิศทางอื่น) ตัวเลือก CYCLE อยู่ในมาตรฐาน SQL ทันที (ตั้งแต่อย่างน้อยปี 2003)
Mike Sherrill 'Cat Recall'

4

ล้น BIGINT? ฮ่าฮ่า ก่อนอื่นให้หาวิธีที่จะบรรลุความเป็นอมตะ INT ไม่ได้ลงนาม (4 พันล้าน) เข้าถึงได้ยาก 100 INSERT ต่อวินาทีจะเข้าใกล้ INT ที่ล้นในหนึ่งปี BIGINT จะใช้เวลาหลายพันล้านปี

วิธีแก้ไข: แก้ไขตาราง foo MODIFY COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ไม่ได้; แต่นั่นจะใช้เวลาเป็นชั่วโมงเพราะมันจะคัดลอกตาราง (ซึ่งมีจำนวนเกือบ 4 พันล้านแถวใช่มั้ย) และสร้างดัชนีรองทั้งหมดใหม่ วางแผนล่วงหน้า.

โดยทั่วไปเมื่อคุณพยายามจัดเก็บตัวเลขที่มีขนาดใหญ่เกินไปสำหรับเขตข้อมูล (เช่น 999 ใน TINYINT UNSIGNED) ค่าดังกล่าวจะกำหนดให้สูงสุดสำหรับเขตข้อมูล (255 ในกรณีนี้) อาจมี "คำเตือน" แต่คนส่วนใหญ่ไม่ใส่ใจที่จะตรวจสอบคำเตือน หากเป็นฟิลด์ที่ไม่ซ้ำกันหรือมีคีย์ต่างประเทศคุณอาจได้รับข้อผิดพลาดที่ร้ายแรงกว่านี้

CHAR หรือ VARCHAR ถูกตัดทอนไปยังพื้นที่ที่มีอยู่อย่างเงียบ ๆ

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