ทำไมผู้คนถึงใช้ 255 ไม่ใช่ 256 สำหรับขนาดเขตข้อมูลของฐานข้อมูล


190

คุณมักจะเห็นเขตข้อมูลฐานข้อมูลตั้งค่าให้มีขนาด 255 ตัวอักษรเหตุผลดั้งเดิม / ประวัติศาสตร์คืออะไร ฉันคิดว่ามันเป็นเรื่องเกี่ยวกับการ จำกัด การเพจ / หน่วยความจำและประสิทธิภาพ แต่ความแตกต่างระหว่าง 255 และ 256 ทำให้ฉันสับสนอยู่เสมอ

varchar(255)

พิจารณานี้เป็นความจุหรือขนาดไม่ได้เป็นดัชนี , ทำไม 255 ที่ต้องการมากกว่า 256? ไบต์ถูกสงวนไว้สำหรับวัตถุประสงค์บางอย่าง (terminator หรือ null หรืออะไรบางอย่าง)?

สมมุติว่า varchar (0) เป็นเรื่องไร้สาระ (มีความจุเป็นศูนย์) หรือไม่ ในกรณีใดพื้นที่ 2 ^ 8 ควรเป็น 256 แน่นอน?

มีขนาดอื่นที่ให้ประโยชน์ด้านประสิทธิภาพหรือไม่ ตัวอย่างเช่น varchar (512) มีประสิทธิภาพน้อยกว่า varchar (511) หรือ varchar (510)

ค่านี้เหมือนกันสำหรับฐานข้อมูลความสัมพันธ์ทั้งหมดเก่าและใหม่หรือไม่

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

แก้ไข:

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

หากข้อมูลเมตา (ความยาวสตริง) ถูกเก็บไว้ในหน่วยความจำ / ดิสก์ที่ต่อเนื่องกันมันจะมีเหตุผล 1 ไบต์ของข้อมูลเมตาและ 255 ไบต์ของข้อมูลสตริงจะเหมาะสมกันอย่างมากและพอดีกับ 256 ไบต์ของพื้นที่เก็บข้อมูลที่อยู่ติดกันซึ่งน่าจะเป็นระเบียบเรียบร้อย

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

ในทั้งสองกรณีดูเหมือนว่าจะมีความละเอียดอ่อนซึ่งอาจขึ้นอยู่กับการใช้งานฐานข้อมูล การฝึกฝนการใช้ 255 ดูเหมือนจะค่อนข้างแพร่หลายดังนั้นบางคนต้องเถียงเป็นกรณีที่ดีสำหรับการเริ่มต้นทุกคนสามารถจำกรณีที่เป็น / คืออะไร? โปรแกรมเมอร์จะไม่ยอมรับแนวปฏิบัติใหม่ ๆ โดยไม่มีเหตุผลและสิ่งนี้จะต้องเป็นเรื่องใหม่อีกครั้ง


3
เนื่องจากจำนวนตัวอักษรเริ่มต้นจาก 0 ถึง N-1 ดังนั้น 256 ตัวอักษรจะถูกประกาศ varchar (255) นอกจากว่าฉันเข้าใจผิด
Buhake Sindi

3
อาจเป็นเพราะคนไอทีเริ่มนับด้วย 0 ไม่ใช่ 1;)?
Romain Linsolas

ฉันคิดว่ามันเกี่ยวกับโปรแกรมเมอร์โรงเรียนเก่าไม่สามารถจำได้ว่าทำไมเราถึงทำ
พอใจ

7
@Elite Gentleman: ไม่หมายเลขในวงเล็บคือความยาวจริง ... เหมือนกับในการประกาศอาร์เรย์ C: x [256] ให้ x [0] ... x [255]
RedPandaCurios

@romaintaz - แต่ให้พิจารณาอาร์เรย์ที่สามารถเก็บ 1 รายการ คุณประกาศบางสิ่งบางอย่าง [1] และเข้าถึงบางสิ่ง [0] คำถามคือทำไมใน SQL เราจึงประกาศความสามารถในการเป็น 1 ไบต์น้อยกว่าที่ดูเหมือนว่าตรรกะในทันที
Andrew M

คำตอบ:


167

ด้วยความยาวสูงสุด 255 อักขระ DBMS สามารถเลือกใช้ไบต์เดียวเพื่อระบุความยาวของข้อมูลในฟิลด์ หากขีด จำกัด อยู่ที่ 256 หรือมากกว่านั้นจะต้องใช้สองไบต์

ค่าความยาวเป็นศูนย์แน่นอนสำหรับvarcharข้อมูล (เว้นแต่มีข้อ จำกัด เป็นอย่างอื่น) ระบบส่วนใหญ่ถือว่าสตริงว่างนั้นแตกต่างจาก NULL แต่บางระบบ (โดยเฉพาะ Oracle) ถือว่าสตริงว่างเหมือนกับ NULL สำหรับระบบที่สตริงว่างไม่ใช่ NULL จะต้องมีบิตเพิ่มเติมในแถวเพื่อระบุว่าควรพิจารณาค่าเป็น NULL หรือไม่

ดังที่คุณทราบนี่เป็นการเพิ่มประสิทธิภาพในอดีตและอาจไม่เกี่ยวข้องกับระบบส่วนใหญ่ในปัจจุบัน


การสำรองไบต์สำหรับความยาวนั้นสมเหตุสมผล แต่ WRT paragrph ตัวที่สองของคุณสมมุติว่า a / value / of length zero ถูกต้อง แต่ a / ความจุ / ความยาวเป็นศูนย์ที่ถูกต้องหรือไม่
Andrew M

1
@Andrew: varchar(0)ผมแค่พยายามและปฏิเสธ อาจไม่เป็นประโยชน์เพราะค่าอาจเป็นสองสิ่งเท่านั้นสตริงว่างหรือ NULL และคุณอาจใช้เพียงแค่bitนั้น
Greg Hewgill

ดังนั้นจึงเป็นความจริงที่จะสมมติว่าข้อมูลเมตาของความจุถูกเก็บไว้ในบล็อกที่ต่อเนื่องกันกับข้อมูลและดังนั้นจึงมีความได้เปรียบที่ DB จะเก็บผลรวมของสองสิ่งเหล่านั้น (ข้อมูลและข้อมูลเมตา) ภายในหน้าเดียว bytes)?
Andrew M

@Andrew: นั่นเป็นข้อสันนิษฐานที่อาจหรืออาจไม่จริงขึ้นอยู่กับรายละเอียดการใช้งานของ DBMS ที่เป็นปัญหา ขนาดหน้าโดยทั่วไปจะมีขนาดใหญ่กว่า 256 ไบต์ ดังที่ฉันได้กล่าวมาการเพิ่มประสิทธิภาพประเภทนี้บางครั้งสำคัญ (เช่นหากคุณเก็บพันล้านแถวเล็ก ๆ ) แต่ส่วนใหญ่แล้วมันไม่คุ้มค่าที่จะกังวล
Greg Hewgill

3
ความสำคัญในพื้นที่ดิสก์ (และพื้นที่ดัชนี) ไม่ใช่เพราะ 256 อาจพอดีกับหน้า แต่เนื่องจาก 1 ไบต์เทียบกับ 2 ไบต์ (สำหรับแถวนับล้าน / พันล้าน / ล้านล้านล้านแถว) สร้างความแตกต่างอย่างมาก
ypercubeᵀᴹ

35

255 คือขีด จำกัด varchar ใน mySQL4 และก่อนหน้านี้

นอกจากนี้ 255 chars + Null terminator = 256

หรือตัวบอกความยาว 1 ไบต์ให้ช่วงที่เป็นไปได้ 0-255 ตัวอักษร


และการอ่านchar foo[256]เป็นสิ่งสำคัญเนื่องจากการจัดการหน่วยความจำชอบพลังของ 2 ดู: stackoverflow.com/questions/3190146/… การจัดสรรchar foo[257]หน่วยความจำจะแยกส่วนหรือใช้ 512 ไบต์
ebyrob

4
varchar ไม่เก็บความยาวของสตริงและดังนั้นจึงไม่จำเป็นต้องมี terminator แบบ null?
Cruncher

19

255 เป็นค่าตัวเลขที่ใหญ่ที่สุดที่สามารถเก็บไว้ในจำนวนเต็มแบบไบต์เดียว (สมมติว่า 8 บิตไบต์) - ดังนั้นแอปพลิเคชันที่เก็บความยาวของสตริงสำหรับวัตถุประสงค์บางอย่างจะชอบ 255 มากกว่า 256 เพราะมันหมายความว่าพวกเขาจะต้อง จัดสรร 1 ไบต์สำหรับตัวแปร "size"


17

จากคู่มือ MySQL:

ชนิดข้อมูล:
VARCHAR (M), VARBINARY (M)

จำเป็นต้องมีที่เก็บข้อมูล:
L + 1 ไบต์หากค่าคอลัมน์ต้องการ 0 - 255 ไบต์, L + 2 ไบต์หากค่าอาจต้องการมากกว่า 255 ไบต์

ทำความเข้าใจและตัดสินใจเลือก


ใช่ แต่M represents the declared column length in characters for nonbinary string types and bytes for binary string types. L represents the actual length in bytes of a given string value. dev.mysql.com/doc/refman/5.7/en/storage-requirements.html
DLight


7

ความยาวสูงสุด 255 อนุญาตให้เอ็นจิ้นฐานข้อมูลใช้เพียง 1 ไบต์เพื่อเก็บความยาวของแต่ละฟิลด์ คุณถูกต้องที่ 1 ไบต์ของพื้นที่อนุญาตให้คุณเก็บ 2 ^ 8 = 256 ค่าที่แตกต่างสำหรับความยาวของสตริง

แต่ถ้าคุณอนุญาตให้เขตข้อมูลเก็บสตริงข้อความที่มีความยาวเป็นศูนย์ได้คุณจะต้องสามารถเก็บศูนย์ไว้ในความยาวได้ ดังนั้นคุณสามารถอนุญาต 256 ค่าความยาวที่แตกต่างเริ่มต้นที่ศูนย์: 0-255


6

บ่อยครั้งที่มีการใช้งาน varchars เป็นสตริงปาสคาล: ถือความยาวจริงในไบต์ # 0 ความยาวจึงถูกผูกไว้กับ 255 (ค่าของไบต์จะแตกต่างกันตั้งแต่ 0 ถึง 255)


5

<<

จำความรู้พื้นฐานของการจัดเก็บบิต / ไบต์มันต้องมีหนึ่งไบต์เพื่อเก็บจำนวนเต็มต่ำกว่า 256 และสองไบต์สำหรับจำนวนเต็มใด ๆ ระหว่าง 256 และ 65536 ดังนั้นมันต้องมีพื้นที่เดียวกัน (สองไบต์) เพื่อเก็บ 511 หรือ 512 หรือเรื่องที่ 65535 .... ดังนั้นจึงเป็นที่ชัดเจนว่าอาร์กิวเมนต์นี้ที่กล่าวถึงในการสนทนาข้างต้นคือ N / A สำหรับ varchar (512) หรือ varchar (511)


4

8 บิตที่ไม่ได้ลงชื่อ = 256 ไบต์

ความยาว 255 อักขระ + ไบต์ 0 สำหรับความยาว


3

มันเคยเป็นว่าสตริงทั้งหมดต้องใช้ NUL terminator หรือ "backslash-zero" ฐานข้อมูลที่อัปเดตไม่มีสิ่งนั้น มันคือ "255 ตัวอักษรของข้อความ" โดยมีการเพิ่ม "\ 0" โดยอัตโนมัติในตอนท้ายเพื่อให้ระบบทราบว่าสตริงสิ้นสุดลงที่ใด หากคุณพูดว่า VARCHAR (256) มันจะจบลงที่ 257 แล้วคุณจะอยู่ในการลงทะเบียนครั้งต่อไปสำหรับตัวละครตัวหนึ่ง เปลือง นั่นเป็นเหตุผลที่ทุกอย่างเป็น VARCHAR (255) และ VARCHAR (31) นิสัยที่ 255 ดูเหมือนจะติดอยู่รอบ ๆ แต่ 31 กลายเป็น 32 และ 511 กลายเป็น 512 ส่วนนั้นแปลก มันยากที่จะทำให้ตัวเองเขียน VARCHAR (256)


0

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

มันยากที่จะรู้ว่าที่อยู่ไปรษณีย์ที่ยาวที่สุดคืออะไรซึ่งเป็นเหตุผลว่าทำไมหลาย ๆ คนเลือก VARCHAR ที่ยาวกว่าที่อยู่ใด ๆ และ 255 เป็นธรรมเนียมเนื่องจากอาจเป็นความยาวสูงสุดของ VARCHAR ในบางฐานข้อมูลในช่วงเช้า (รวมถึง PostgreSQL จนกระทั่งเมื่อไม่นานมานี้)

มีข้อเสียในการใช้ varchar ทั่วไป (255) สำหรับเขตข้อมูลที่เป็นข้อความทั้งหมดหรือไม่


0

ข้อมูลถูกบันทึกในหน่วยความจำในระบบเลขฐานสองและ 0 และ 1 เป็นเลขฐานสอง เลขฐานสองที่ใหญ่ที่สุดที่สามารถใส่ได้ 1 ไบต์ (8 บิต) คือ 11111111 ซึ่งแปลงเป็นทศนิยม 255

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