InnoDB สร้างข้อผิดพลาดของตาราง:“ ขนาดแถวใหญ่เกินไป”


11

เรามีวิศวกรบางคนที่แผ่โครงสร้างฐานข้อมูลให้เป็นมาตรฐานในตารางชั่วคราวเพื่อวัตถุประสงค์ในการสร้างรายงาน คอลัมน์มีการระบุไว้เป็นTEXT NOT NULL(ฉันรู้ว่า "ทำไมพวกเขาถึงทำอย่างนั้น?" ขอแค่สมมติว่าเรากำลังพูดถึงเรื่องนี้)

เราใช้ MySQL 5.1.48 Community RHEL5 กับปลั๊กอิน InnoDB 1.0.9 บน Linux

เมื่อใช้ MyISAM เราไม่เคยพบข้อ จำกัด ขนาดตารางของคอลัมน์สูงสุดหรือความยาวแถวสูงสุด (ในระหว่างการตรวจสอบเราได้ จำกัด จำนวนคอลัมน์สูงสุดที่ 2598 (2599 ข้อผิดพลาดทำให้เกิดข้อผิดพลาด 1117) ด้วย InnoDB เรากำลังขีด จำกัด ขีด จำกัด เหล่านี้ ตาราง (ไม่มีการแทรกข้อมูล) เป็น:

ข้อผิดพลาด 1118 (42000) ที่บรรทัด 1: ขนาดแถวใหญ่เกินไป ขนาดแถวสูงสุดสำหรับประเภทตารางที่ใช้ไม่นับ BLOB คือ 8126 คุณต้องเปลี่ยนบางคอลัมน์เป็น TEXT หรือ BLOB

ฉันกำลังมองหาคำตอบต่อไปนี้:

  1. สูตรรายละเอียดสำหรับการกำหนดขนาดอนุภาคแถวเมื่อใช้ล็อตของคอลัมน์ v / v / b / t คืออะไร? ฉันได้ลอง formuals ต่าง ๆ โดยใช้varchar(N)คอลัมน์ (โดยที่ N อยู่ระหว่าง 1 ถึง 512), UTF8 charset (* 3) และคอลัมน์ให้มากที่สุดเท่าที่ตารางจะใช้จนกว่าจะล้มเหลว ไม่มีคอมโบที่ฉันได้ลองให้ค่าที่ตรงกับผลการทดสอบจริง

  2. ฉันต้องคำนึงถึงค่าใช้จ่ายอื่นใดเมื่อคำนวณขนาดแถว

  3. ทำไมข้อความแสดงข้อผิดพลาดเปลี่ยนจาก 8126 ถึง 65535 เมื่อฉันไปจากการสร้างตารางที่มีคอลัมน์ varchar (109) เป็นคอลัมน์ varchar (110)


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

HTML ไม่ใช่วายร้าย หรือขนาดของ HTML นั้น คุณต้องมีคอลัมน์ข้อความ / varchar หลายคอลัมน์และมีข้อ จำกัด บางประการที่สามารถแก้ไขได้
Rick James

คำตอบ:


19

คำตอบสำหรับคำถามของคุณมีความซับซ้อนเพราะพวกเขาแตกต่างกันตาม InnoDB รูปแบบไฟล์ วันนี้มีสองรูปแบบที่เรียกว่าละมั่งและ Barracuda

ไฟล์ tablespace ส่วนกลาง (ibdata1) อยู่ในรูปแบบละมั่งเสมอ หากคุณใช้ไฟล์ต่อตารางคุณสามารถทำให้แต่ละไฟล์ใช้รูปแบบBarracudaโดยการตั้งค่าinnodb_file_format=Barracudaใน my.cnf

คะแนนพื้นฐาน:

  • หน้า 16KB หนึ่งหน้าของข้อมูล InnoDB ต้องมีข้อมูลอย่างน้อยสองแถว รวมแต่ละหน้ามีส่วนหัวและส่วนท้ายที่มีการตรวจสอบหน้าและหมายเลขลำดับบันทึกและอื่น ๆ นั่นคือสิ่งที่คุณจะได้รับขีด จำกัด น้อยกว่า 8KB ต่อแถว

  • ประเภทข้อมูลขนาดคงที่เช่น INTEGER, DATE, FLOAT, CHAR จะถูกเก็บไว้ในหน้าข้อมูลหลักนี้และนับรวมไปถึงขีด จำกัด ขนาดแถว

  • ประเภทข้อมูลขนาดผันแปรเช่น VARCHAR, TEXT, BLOB ถูกเก็บไว้ในหน้าเว็บล้นดังนั้นจึงไม่นับรวมอย่างเต็มที่จนถึงขีด จำกัด ขนาดแถว ใน Antelope จะมีการจัดเก็บคอลัมน์ดังกล่าวสูงสุด 768 ไบต์ในหน้าข้อมูลหลักนอกเหนือจากการจัดเก็บไว้ในหน้าล้น Barracuda รองรับรูปแบบแถวแบบไดนามิกดังนั้นจึงอาจจัดเก็บเฉพาะตัวชี้ 20 ไบต์ในหน้าข้อมูลหลัก

  • ชนิดข้อมูลขนาดผันแปรนั้นมีคำนำหน้าด้วย 1 ไบต์ขึ้นไปเพื่อเข้ารหัสความยาว และรูปแบบแถว InnoDB ยังมีชุดของฟิลด์ออฟเซ็ต ดังนั้นจึงมีโครงสร้างภายในที่มากหรือน้อยกว่าการบันทึกไว้ในวิกิพีเดียของพวกเขา [แก้ไข] การเชื่อมโยงตาย - ที่นี่ดูดีกว่าตอนนี้

Barracuda ยังรองรับROW_FORMAT = COMPRESSEDเพื่อเพิ่มประสิทธิภาพในการจัดเก็บข้อมูลล้น

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


2
เป็นเรื่องง่ายมากสำหรับวิศวกรที่ไม่ได้ใช้ฐานข้อมูลดีพอที่จะใช้เส้นทางข้อมูลแบบแบน มันไม่เคยทำงาน ฐานข้อมูลดั้งเดิมของฉันซึ่งมีสถานการณ์คล้ายกันไม่ได้ตีขนาดของแถวอย่างน่าทึ่ง แต่เด็กมันเป็นผลงานที่ยอดเยี่ยม! ฉันจะบอกว่าวิศวกรการรายงานของคุณต้องยอมรับว่าพวกเขาจะต้องเข้าร่วมและทำขึ้นสำหรับงานนั้นด้วยตลอดการทำดัชนี
TechieGurl

1

สถานการณ์ของฉันแตกต่างกันเล็กน้อย องค์ประกอบข้อมูลอย่างหนึ่งที่ฉันต้องจัดเก็บในแต่ละแถวอาจมีขนาดใหญ่มาก (เขตข้อมูลเป็น LONGBLOB สำหรับเอกสารที่อาจมีหลายภาพที่ฝังตัวฐานข้อมูลตัวอย่างของฉันมีเอกสารที่มีขนาดใหญ่ถึง 25 - 30 MB แต่เอกสารเหล่านี้อาจมีขนาดใหญ่กว่าในบางกรณี) ไม่มีวิธีแก้ปัญหาที่ฉันพบทางออนไลน์ . (เปลี่ยนประเภทไฟล์ InnoDB เป็น Barracuda เพิ่มขนาดไฟล์บันทึกตั้งค่ารูปแบบแถวเป็น COMPRESSED)

ทางออกเดียวที่ฉันพบว่าใช้งานได้สำหรับฉันคือเปลี่ยนกลับเป็น MySQL 5.5.x จาก MySQL 5.6.x

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