มีเหตุผลที่ดีที่ฉันเห็น VARCHAR (255) ใช้บ่อยไหม (ตรงกันข้ามกับความยาวอื่น)?


158

ในหลายหลักสูตรหนังสือและงานฉันได้เห็นเขตข้อมูลข้อความที่กำหนดเป็น VARCHAR (255) เป็นค่าเริ่มต้นสำหรับข้อความ "shortish" มีเหตุผลที่ดีหรือไม่ที่มีการเลือกความยาว 255 บ่อยครั้งนอกเหนือจากการเป็นจำนวนรอบที่ดี ? มันเป็นสิ่งที่ค้างไว้บางครั้งในอดีตเมื่อมีเหตุผลที่ดี (ไม่ว่าวันนี้จะมีผลหรือไม่)?

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


หมายเหตุ: ฉันพบคำถามนี้ ( varchar (255) v tinyblob v tinytext ) ซึ่งบอกว่า VARCHAR ( n ) ต้องการหน่วยเก็บข้อมูล +1 nไบต์สำหรับn <= 255, n +2 ไบต์ของที่เก็บสำหรับn > 255 นี่เป็นเหตุผลเดียวหรือไม่ ดูเหมือนจะเป็นเรื่องที่ไม่มีกฎเกณฑ์เนื่องจากคุณจะประหยัดเพียงสองไบต์เมื่อเปรียบเทียบกับ VARCHAR (256) และคุณสามารถบันทึกอีกสองไบต์ได้อย่างง่ายดายโดยการประกาศ VARCHAR (253)

คำตอบ:


109

ในอดีต 255 ตัวอักษรมักจะมีความยาวสูงสุดของVARCHARใน DBMS บางตัวและบางครั้งก็ยังคงเป็นค่าสูงสุดที่มีประสิทธิภาพถ้าคุณต้องการใช้ UTF-8 และมีการทำดัชนีคอลัมน์ (เนื่องจากข้อจำกัดความยาวของดัชนี)


4
@CharlesBretana: ถ้าคุณอ่านประโยคที่เหลือที่ยกมาคุณจะพบคำอธิบายที่แน่นอนที่คุณร้องขอ
ความโกลาหล

2
@CharlesBretana: โดย "fake UTF-8" ฉันหมายถึงการเข้ารหัส "utf8" ของ MySQL ซึ่งตามที่ฉันกล่าวถึงการสงวน (และ จำกัด ไว้ที่) 3 ไบต์ต่อตัวอักษร นี่ไม่ใช่ UTF-8 รุ่นที่ดีมาก ถ้าคุณต้องการ UTF-8 ที่ดีใน MySQL คุณต้องใช้การเข้ารหัส "utf8mb4" แต่ผู้คนมีแนวโน้มที่จะไม่รู้และไปด้วย "utf8" และมีแนวโน้มที่จะต้องการ UTF-8 มากกว่าการเข้ารหัสอื่น ๆ ดังนั้น presto พวกเขาไขด้วยความยาวสูงสุดที่สามารถจัดทำดัชนีได้ 255 ตัวอักษรใน VARCHAR ความประหลาดใจของคุณแม้จะมี
ความโกลาหล

3
@CharlesBretana: ตอนนี้ฉันอธิบายแล้วสามครั้งและไม่มีอะไรเปลี่ยนแปลง ขีดจำกัดความยาวของดัชนี MySQL ยังคงเป็น 767 ไบต์จำนวนไบต์ที่จำเป็นในการเข้ารหัสอักขระ 3 ไบต์ UTF-8 ยังคงเป็น 3 และพื้น (767/3) ยังคงเป็น 255 การตัดสินใจของคุณที่จะหาสิ่งที่สับสนเกี่ยวกับความเชื่อขอทาน .
ความโกลาหล

1
@CharlesBretana (ขออภัยที่มาสายสำหรับปาร์ตี้ทั้งหมดนี้) ฉันไม่ใช่ผู้เชี่ยวชาญ DB แต่ฉันคิดว่าสิ่งที่สับสนคือ: ใช่คอลัมน์ 'UTF-8' มีความยาวมากกว่า 255 ตัวอักษร แต่ดัชนีจะ ทำงานกับ 255 อักขระแรกของ varchar เท่านั้นทำให้คอลัมน์มีประสิทธิภาพสูงสุดหากคุณต้องการให้มีการจัดทำดัชนีแบบสมบูรณ์ ตอนนี้เป็นเพียงสิ่งที่ฉันเข้าใจในการอธิบายของเขาฉันอาจผิดฉันไม่ใช่ผู้เชี่ยวชาญในดัชนี SQL เลย
ฟรานซิสลอร์ด

2
@CharlesBretana ถ้าคุณดูคำตอบของ Chaos อย่างถูกต้องคุณจะสังเกตได้ว่ามันแยกออกเป็น 2 ส่วน: 1. เหตุผลทางประวัติศาสตร์ที่อยู่เบื้องหลัง Varchar (255) เป็นเรื่องธรรมดามาก แม้กระทั่งทุกวันนี้ก็ยังมีข้อ จำกัด สำหรับบางคนเนื่องจากข้อ จำกัด ของดัชนีที่กล่าวถึงก่อนหน้านี้ส่วนที่ 1 และ 2 ไม่ได้เชื่อมโยง ส่วนที่ 1 เป็นคำตอบที่แท้จริงของคำถามส่วนที่ 2 เป็นหมายเหตุด้านข้างซึ่งยังคงเกี่ยวข้องกับคำถามเพราะมันอธิบายว่าทำไมถึงแม้วันนี้มันอาจจะยังมีข้อ จำกัด (ต่อ ->)
ฟรานซิสลอร์ด

161

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

เมื่อใช้วิธีนี้ VarChar จะใช้จำนวนไบต์ + 1 ในการจัดเก็บข้อความของคุณเท่านั้นดังนั้นคุณอาจตั้งค่าไว้ที่ 255 ยกเว้นว่าคุณต้องการขีด จำกัด ที่ยาก (เช่น 50) กับจำนวนอักขระในฟิลด์


90
ฉันชอบวลีนั้น: "frivolously ต้องไบต์อื่นทั้งหมด" =)
MusiGenesis

7
สิ่งนี้ถือเป็นจริงสำหรับ DB ที่ varchars เป็น UTF-8 หรือไม่?
antak

1
@antak: ใน MySQL โดยใช้ InnoDB คอลัมน์สำคัญจะต้องมีขนาดไม่เกิน 767 ไบต์ หากคอลัมน์ VARCHAR คือ UTF8 (หมายถึงแต่ละอักขระอาจใช้เวลาสูงสุด 3 ไบต์) ความยาวสูงสุดที่อนุญาตคือคอลัมน์คือ floor (767/3) = 255 ฉันถือว่าสมมติว่า "767" ถูกเลือกด้วยเหตุผลนั้น
BlueRaja - Danny Pflughoeft

1
หาก charset เป็นutf8 , varchar(85)เป็นวงเงินมากกว่าที่ข้ามเคล็ดลับไบต์ความยาว 1-2 ไบต์ ถ้ามันก็utf8mb4 varchar(63)เหล่านี้มีความสำคัญเพราะพวกเขากำลังสูงสุดที่ได้มีความยาวของ VARCHAR สามารถขยายได้ผ่านการใช้เปลี่ยนแปลงตารางออนไลน์ ดังนั้นฉันได้รับตัวเลขเหล่านั้นโดยการสร้างตารางที่มีvarchar(2) charset utf8คอลัมน์และดูว่าฉันสามารถขยายได้ALGORITHM=INPLACEมากแค่ไหน
antak

มันสมเหตุสมผลมากขึ้นเมื่อคุณพิจารณาว่า "ฐานข้อมูล" หลาย ๆ อย่างกลับมาในวันนั้นถูกเก็บไว้ในเทปแม่เหล็ก มันเป็นเรื่องธรรมดามากที่จะอ่านข้อมูลใน "บล็อก" ที่มีขนาดเป็นทวีคูณของสองคน ด้วยวิธีนี้ข้อมูลจะถูกจัดเก็บอย่างมีประสิทธิภาพมากที่สุด (และเมื่อคุณใช้งานบนเมนเฟรมเก่าประสิทธิภาพเล็กน้อยเช่นนั้นคือการปรับให้เหมาะสม
TMN

23

อาจเป็นเพราะทั้ง SQL Server และ Sybase (เพื่อชื่อที่สองที่ฉันคุ้นเคย) เคยมีอักขระสูงสุด 255 ตัวในจำนวนอักขระในVARCHARคอลัมน์ สำหรับ SQL Server การเปลี่ยนแปลงนี้ในเวอร์ชัน 7 ในปี 1996/1997 หรือมากกว่านั้น ... แต่บางครั้งนิสัยแบบเดิมก็ยาก


8
+1 สำหรับการอ้างอิงฐานข้อมูลและรุ่นเฉพาะ และ "นิสัยเก่าตายยาก" อาจเป็นคำตอบที่แท้จริงของทุกคน
Andrew M

17

ฉันจะตอบคำถามตามตัวอักษร: ไม่ไม่มีเหตุผลที่ดีที่คุณเห็น VARCHAR (255) ใช้บ่อย (มีเหตุผลจริง ๆตามที่กล่าวไว้ในคำตอบอื่น ๆ ไม่ใช่คำตอบที่ดี) คุณจะไม่พบตัวอย่างโครงการที่ล้มเหลวอย่างรุนแรงเนื่องจากสถาปนิกเลือก VARCHAR (300) แทนที่จะเป็น VARCHAR (255) นี่จะเป็นปัญหาของความไม่สำคัญเกือบทั้งหมดแม้ว่าคุณจะพูดถึง CHAR แทนที่จะเป็น VARCHAR


1 ไบต์จาก 255 คือ 0.4% บางครั้งคุณสนใจประมาณครึ่งเปอร์เซ็นต์หรือมากกว่านั้น บางครั้งคุณทำไม่ได้ หากคุณให้บริการโฮสติ้งและค่าใช้จ่ายในการเดินทางเป็นหมื่นดอลลาร์คุณอาจไม่สนใจ หากพวกเขาพบกับคนนับล้านพวกเขาอาจจะทำ
Edward Brey

2
@ เอ็ดเวิร์ดเบรย์: ถ้ากฎของมัวร์ยังคงเป็นจริงคำตอบของฉันที่นี่จะถูกต้องมากกว่าที่ฉันเคยเขียน 16 เท่า
MusiGenesis

หากเราไม่ค้นพบวิธีที่คอมพิวเตอร์สามารถช่วยเราได้มากขึ้น 16 เท่า ความเร็วยังคงเป็นคุณสมบัติ
Edward Brey

14

เมื่อคุณพูดว่า2^8คุณจะได้รับแต่ตัวเลขในแง่คอมพิวเตอร์จะเริ่มต้นจากจำนวน256 0ดังนั้นจากนั้นคุณจะได้รับ255คุณสามารถตรวจสอบในรูปแบบอินเทอร์เน็ตสำหรับ IP หรือในตัวเอง

255 เป็นค่าสูงสุดของจำนวนเต็ม 8 บิต: 11111111 = 255

มันช่วยได้ไหม


1
ด้วยจำนวนเต็มคุณนับเริ่มจาก 0 และคุณจบที่ 255 แต่ด้วยสถานที่ในสตริงคุณนับเริ่มจากที่ 1 ดังนั้นจึงไม่สมเหตุสมผลที่จะจบที่อันดับที่ 256 เพราะคุณเริ่มที่ 1 แทน 0? ฉันยังไม่เห็นด้วยกับ varchar (256) เพียงเพราะผล string_length () แต่ฉันไม่แน่ใจจริงๆ
HoldOffHunger

1
@HoldOffHunger สตริงในฐานข้อมูลสามารถมีความยาวเป็นศูนย์ได้ดังนั้นช่วงที่อนุญาตเมื่อความยาวถูกเก็บไว้ในแปดบิตอยู่ระหว่าง 0 ถึง 255 ถ้าคุณต้องการบอกว่าสตริงทุกตัวต้องมีอย่างน้อยหนึ่งตัว สามารถรองรับสตริง 256 อักขระที่มีความยาวแปดบิต
phoog

7

หมายเหตุ: ฉันพบคำถามนี้ ( varchar (255) v tinyblob v tinytext ) ซึ่งบอกว่า VARCHAR ( n ) ต้องการหน่วยเก็บข้อมูล +1 nไบต์สำหรับn <= 255, n +2 ไบต์ของที่เก็บสำหรับn > 255 นี่เป็นเหตุผลเดียวหรือไม่ ดูเหมือนจะเป็นเรื่องที่ไม่มีกฎเกณฑ์เนื่องจากคุณจะประหยัดเพียงสองไบต์เมื่อเปรียบเทียบกับ VARCHAR (256) และคุณสามารถบันทึกอีกสองไบต์ได้อย่างง่ายดายโดยการประกาศ VARCHAR (253)

ไม่คุณไม่ได้บันทึกสองไบต์ด้วยการประกาศ 253 การใช้งาน varchar นั้นน่าจะเป็นตัวนับความยาวและความยาวผันแปรซึ่งเป็นตัวแปรที่ไม่ได้ระบุค่า ซึ่งหมายความว่าหากคุณเก็บ "hello" ไว้ใน varchar (255) คุณจะได้ 6 ไบต์: หนึ่งไบต์สำหรับความยาว (หมายเลข 5) และ 5 ไบต์สำหรับตัวอักษรห้าตัว


3
คำสั่งนี้ไม่เป็นความจริงกับฐานข้อมูลทั้งหมด ฐานข้อมูลจำนวนมากใช้เขตข้อมูล varchar ตามขนาดที่กำหนดในตารางเพื่อไม่ต้องย้ายแถวรอบ ๆ เมื่อมีการเปลี่ยนแปลงเขตข้อมูลสำหรับแถว
SingleNegationElimination

ใช่คุณถูก. มันขึ้นอยู่กับการใช้งาน คุณต้องตรวจสอบคู่มือผู้ขายเพื่อดูว่าเกิดกรณีอะไร
Stefano Borini

2
มันอาจจะได้รับอนุญาต แต่การใช้VARCHARวิธีการที่จะเอาชนะทั้งประเด็นของการใช้แทนVARCHAR CHAR
dan04

4

หมายเลข 1 ไบต์ที่ไม่ได้ลงชื่อสามารถมีช่วง [0-255] รวม ดังนั้นเมื่อคุณเห็น 255 ส่วนใหญ่เป็นเพราะโปรแกรมเมอร์คิดในฐาน10(รับเรื่องตลก?) :)

ที่จริงแล้วในขณะที่ 255 เป็นขนาดที่ใหญ่ที่สุดที่คุณสามารถให้ VARCHAR ใน MySQL และมีข้อได้เปรียบในการใช้ VARCHAR บน TEXT ด้วยการทำดัชนีและปัญหาอื่น ๆ


4

ในหลาย ๆ แอปพลิเคชั่นเช่น MsOffice (จนถึงรุ่น 2000 หรือ 2002) จำนวนอักขระสูงสุดต่อเซลล์คือ 255 การย้ายข้อมูลจากโปรแกรมที่สามารถจัดการมากกว่า 255 ตัวอักษรต่อหนึ่งฟิลด์ไปยัง / จากแอปพลิเคชันเหล่านั้นเป็นฝันร้าย ปัจจุบันขีด จำกัด นั้นมีน้อยลงเรื่อย ๆ


2

0000 0000 -> นี่คือเลขฐานสอง 8 บิต ตัวเลขแสดงถึงบิต

คุณนับว่าเป็นเช่นนั้น:

0000 0000 → (0)

0000 0001 → (1)

0000 0010 → (2)

0000 0011 → (3)

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

2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 - 1 = 255

หรือ

2^8 - 1. 

เราลบหนึ่งเพราะตัวเลขแรกคือ 0

255 สามารถเก็บค่าได้ไม่มากนัก

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


1

อีกเหตุผลหนึ่งอาจเป็นเพราะในไลบรารีการเข้าถึงข้อมูลที่เก่ามากบน Windows เช่น RDO และ ADO (รุ่น COM ไม่ใช่ ADO.NET) คุณต้องเรียกใช้วิธีพิเศษคือ GetChunk เพื่อรับข้อมูลจากคอลัมน์ที่มี 255 255 chars หากคุณ จำกัด คอลัมน์ varchar เป็น 255 รหัสเพิ่มเติมนี้ไม่จำเป็น

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