ฉันควรเพิ่มขีดจำกัดความยาวตามอำเภอใจในคอลัมน์ VARCHAR หรือไม่


35

ตามเอกสารของ PostgreSQLไม่มีความแตกต่างระหว่างประสิทธิภาพVARCHAR, และVARCHAR(n)TEXT

ฉันควรเพิ่มขีดจำกัดความยาวตามอำเภอใจในคอลัมน์ชื่อหรือที่อยู่หรือไม่?

แก้ไข:ไม่ใช่รายการที่:

ฉันรู้ว่าCHARประเภทนี้เป็นของที่ระลึกในอดีตและฉันไม่เพียง แต่สนใจในการแสดงเท่านั้น

คำตอบ:


45

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

ประสิทธิภาพเกือบจะเหมือนกัน - textจะเร็วกว่าเล็กน้อยในสถานการณ์ที่หายากและคุณบันทึกวงจรสำหรับการตรวจสอบความยาว

หากคุณต้องการบังคับใช้ความยาวสูงสุดจริง ๆยังคงใช้textและเพิ่มข้อ จำกัด การตรวจสอบสำหรับสิ่งนั้น:

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

คุณสามารถปรับเปลี่ยนหรือลดข้อ จำกัด ดังกล่าวได้ตลอดเวลาโดยไม่ต้องยุ่งกับคำจำกัดความของตารางและวัตถุที่ขึ้นกับทั้งหมด (มุมมอง, ฟังก์ชั่น, ปุ่มต่างประเทศ, ... )

ด้วยตัวดัดแปลงความยาวคุณจะพบปัญหาเช่นนี้หรือนี่หรือสิ่งนี้ ...

PostgreSQL 9.1 ได้แนะนำคุณสมบัติใหม่ในการบรรเทาอาการปวดบ้าง ฉันพูดบันทึกประจำรุ่นที่นี่ :

อนุญาตให้ALTER TABLE ... SET DATA TYPEหลีกเลี่ยงการเขียนตารางซ้ำในกรณีที่เหมาะสม (Noah Misch, Robert Haas)

ตัวอย่างเช่นการแปลงvarcharคอลัมน์เป็นข้อความไม่จำเป็นต้องเขียนตารางอีกต่อไป อย่างไรก็ตามการเพิ่มข้อจำกัดความยาวของ varcharคอลัมน์ยังคงต้องใช้การเขียนตารางใหม่


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

ใช่ทั้งหมดขึ้นอยู่กับ Postgres เวอร์ชันก่อน 9.1 - 6 ปีที่ผ่านมา ตอนนี้ฝุ่นเล็กน้อย แต่คำแนะนำพื้นฐานยังดีอยู่
Erwin Brandstetter

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

@ รหัส: มันเป็นตัวเลือกที่ทำงานได้ ถ้าคุณมีหลายคอลัมน์ที่มีข้อ จำกัด เหมือนกันพิจารณาโดเมน หรือvarchar(n)หลังจากทั้งหมดเพื่อความเรียบง่าย - หากข้อเสียมักไม่ส่งผลกระทบต่อคุณ (ขีด จำกัด ไม่ได้กำหนดในกรณีของคุณหากคุณต้องการบังคับใช้ความยาวสูงสุดจริง)
Erwin Brandstetter

12

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

ในการเปลี่ยน (เพิ่ม) การจำกัดความยาวคุณจำเป็นต้องเรียกใช้ALTER TABLEซึ่งอาจใช้เวลานานกว่าจะเสร็จ (เนื่องจากอาจมีการเขียนซ้ำของตาราง) ในระหว่างที่จำเป็นต้องล็อคตารางแบบเอกสิทธิ์เฉพาะบุคคล

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

ในระหว่างการดำเนินการไม่มีอะไรแตกต่างระหว่าง a text, a varcharหรือvarchar(5000)คอลัมน์


จากความอยากรู้ธรรมดาทำไมคุณคิดว่าการตรวจสอบความยาวนี้ไม่สามารถทำได้ในแอปพลิเคชันไคลเอนต์ในขณะที่จับข้อมูล
PirateApp

4
@PirateApp: เพราะบ่อยครั้งจะมีมากกว่าหนึ่งแอปพลิเคชันหรือแหล่งข้อมูลภายนอก (คิดว่าการนำเข้าแบทช์ทุกคืน) และเกือบตลอดเวลาฐานข้อมูล (และข้อมูล) จะมีอายุการใช้งานยาวนานกว่าแอปพลิเคชันเดียว
a_horse_with_no_name

2

คำถามคือโดยเฉพาะไม่ว่าจะเป็นการเพิ่มขีดจำกัดความยาวโดยพลการในคอลัมน์ VARCHAR?

คำตอบก็คือ "ไม่" ไม่มีอะไรที่สามารถปรับเพิ่มขีด จำกัด โดยพลการอย่างที่คุณต้องการในฐานข้อมูลที่ต่ำกว่าที่สนับสนุนvarchar(max)หรือใช้การประชุมเช่นvarchar(255)นี้ อย่างไรก็ตามถ้าข้อมูลจำเพาะ จำกัด จำนวนฉันคิดว่าคำตอบนั้นซับซ้อนกว่าเดิมโดยเฉพาะอย่างยิ่งใน PostgreSQL รุ่นใหม่ และเพื่อที่ผมจะเอียงไปทางYES

ในความคิดของฉันขีด จำกัด เป็นทางเลือกที่ชาญฉลาดหากสเป็คต้องการมัน โดยเฉพาะอย่างยิ่งสำหรับปริมาณงานที่สมเหตุสมผลมากขึ้น หากไม่มีเหตุผลอื่นให้เก็บ meta-data ไว้

จากคำตอบของฉันที่นี่ประสิทธิภาพดัชนีสำหรับ CHAR เทียบกับ VARCHAR (Postgres)ซึ่งฉันจะระบุค่าของ meta-data

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


1

ดูเหมือนว่าอาจมีความแตกต่างด้านประสิทธิภาพบางอย่างหากVARCHARใช้เป็นประจำเพื่อจัดเก็บสตริงที่มีขนาดใหญ่มากเนื่องจาก "สตริงที่ยาวถูกบีบอัดโดยระบบโดยอัตโนมัติ" และ "ค่าที่ยาวมาก ๆ จะถูกเก็บไว้ในตารางพื้นหลังด้วย" ในทางทฤษฎีสิ่งนี้หมายความว่าการร้องขอปริมาณมากสำหรับฟิลด์สตริงที่ยาวมากจะช้ากว่าสำหรับฟิลด์สตริงสั้น ๆ คุณอาจไม่พบปัญหานี้เนื่องจากชื่อและที่อยู่จะไม่ยาวมาก

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


1
AFAIK นั้นไม่มีความแตกต่างในช่องว่างของ varchar และ text
dezso

VARCHARเป็นน้ำตาล syntactic ล้วนๆสำหรับTEXTใน Postgres ไม่มีความแตกต่างในการจัดการกับการจัดเก็บ; การบีบอัดการจัดเก็บตารางพื้นหลังเทียบกับที่คุณพูดถึงจะทำขึ้นอยู่กับความยาวที่แท้จริงของข้อมูลในคอลัมน์และไม่ได้อยู่ในข้อมูลเมตาของคอลัมน์ TEXT คอลัมน์จะถูกเก็บไว้ภายในเป็นvarlenaC โครงสร้าง (ซึ่งเป็นอาร์เรย์ความยาวตัวแปรที่มี 4 ไบต์แรกที่เก็บความยาวในการสร้าง / ปรับปรุง) และมันเป็นโครงสร้างที่ปรับให้เหมาะสมตามความยาวของมัน
cowbert
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.