ชุดอักขระและการเปรียบเทียบหมายถึงอะไรอย่างแน่นอน


315

ฉันสามารถอ่านเอกสารMySQLและมันค่อนข้างชัดเจน แต่เราจะตัดสินใจได้อย่างไรว่าจะใช้อักขระตัวใด การเปรียบเทียบการจัดเรียงข้อมูลมีผลอย่างไร

ฉันขอคำอธิบายของทั้งสองและวิธีการเลือกพวกเขา

คำตอบ:


511

จากเอกสาร MySQL :

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

สมมติว่าเรามีตัวอักษรสี่ตัวอักษร: 'A', 'B', 'a', 'b' เราให้ตัวอักษรแต่ละตัวด้วยตัวเลข: 'A' = 0, 'B' = 1, 'a' = 2, 'b' = 3 ตัวอักษร 'A' เป็นสัญลักษณ์ตัวเลข 0 คือการเข้ารหัสสำหรับ 'A' และการรวมกันของตัวอักษรทั้งสี่และการเข้ารหัสเป็นชุดอักขระ

ทีนี้สมมติว่าเราต้องการเปรียบเทียบค่าสตริงสองค่าคือ 'A' และ 'B' วิธีที่ง่ายที่สุดในการทำเช่นนี้คือการดูการเข้ารหัส: 0 สำหรับ 'A' และ 1 สำหรับ 'B' เนื่องจาก 0 น้อยกว่า 1 เราจึงบอกว่า 'A' น้อยกว่า 'B' ตอนนี้สิ่งที่เราเพิ่งทำไปคือการเปรียบเทียบกับชุดอักขระของเรา การเรียงเป็นชุดของกฎ (หนึ่งกฎเท่านั้นในกรณีนี้): "เปรียบเทียบการเข้ารหัส" เราเรียกสิ่งนี้ว่าการเปรียบเทียบที่ง่ายที่สุดที่เป็นไปได้คือการเปรียบเทียบไบนารี

แต่ถ้าเราต้องการบอกว่าตัวอักษรตัวพิมพ์เล็กและตัวพิมพ์ใหญ่นั้นเทียบเท่ากัน จากนั้นเราจะมีกฎอย่างน้อยสองข้อ: (1) ปฏิบัติต่อตัวอักษรตัวพิมพ์เล็ก 'a' และ 'b' เทียบเท่ากับ 'A' และ 'B' (2) จากนั้นเปรียบเทียบการเข้ารหัส เราเรียกสิ่งนี้ว่าการเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ มันซับซ้อนกว่าการเปรียบเทียบแบบไบนารีเล็กน้อย

ในชีวิตจริงชุดตัวละครส่วนใหญ่มีตัวละครมากมาย: ไม่ใช่แค่ 'A' และ 'B' แต่เป็นตัวอักษรทั้งหมดบางครั้งตัวอักษรหลายตัวหรือระบบการเขียนแบบตะวันออกที่มีตัวอักษรหลายพันตัวพร้อมด้วยสัญลักษณ์พิเศษและเครื่องหมายวรรคตอนมากมาย นอกจากนี้ในชีวิตจริง collations ส่วนใหญ่มีกฎมากมาย: ไม่ใช่แค่เพียงตัวพิมพ์เล็กและตัวพิมพ์เล็ก แต่ยังเน้นความรู้สึกไม่รู้สึกตัวด้วย (เครื่องหมาย "เน้น" เป็นเครื่องหมายที่แนบมากับตัวละครเช่นเดียวกับในภาษาเยอรมัน 'ö') และการแมป ö '=' OE 'ในหนึ่งในสองการเปรียบเทียบภาษาเยอรมัน)


206

การเข้ารหัสอักขระเป็นวิธีเข้ารหัสอักขระเพื่อให้พอดีกับหน่วยความจำ นั่นคือถ้าชุดอักขระเป็น ISO-8859-15 สัญลักษณ์ยูโร€จะถูกเข้ารหัสเป็น 0xa4 และใน UTF-8 ก็จะเป็น 0xe282ac

การเรียงเป็นวิธีเปรียบเทียบอักขระใน latin9 มีตัวอักษรเป็นe é è ê fถ้าเรียงลำดับตามการแสดงฐานสองของพวกเขามันจะไปe f é ê èแต่ถ้าการเปรียบเทียบถูกตั้งค่าเป็นตัวอย่างเช่นฝรั่งเศสคุณจะมีพวกเขาตามลำดับที่คุณคิดว่าพวกเขา จะเป็นซึ่งเป็นทั้งหมดของมีค่าเท่ากันแล้วe é è êf


5
สิ่งสำคัญที่ควรทราบคืออาจมีการเปรียบเทียบที่แตกต่างกันมากมายสำหรับชุดอักขระเดียว หนึ่งที่เป็น "สิทธิ" ขึ้นอยู่กับความหมายของข้อความซึ่งจะถูกกำหนดตามปกติโดยภาษาที่มันเขียนใน.
ฟิล

20

ชุดอักขระเป็นชุดย่อยของร่ายมนตร์ที่เป็นลายลักษณ์อักษรทั้งหมด การเข้ารหัสอักขระระบุวิธีที่อักขระเหล่านั้นถูกแมปกับค่าตัวเลข การเข้ารหัสอักขระบางตัวเช่น UTF-8 และ UTF-16 สามารถเข้ารหัสอักขระใด ๆ ในชุดอักขระสากล อื่น ๆ เช่น US-ASCII หรือ ISO-8859-1 สามารถเข้ารหัสชุดย่อยขนาดเล็กเท่านั้นเนื่องจากพวกเขาใช้ 7 และ 8 บิตต่อตัวอักษรตามลำดับ เนื่องจากมาตรฐานจำนวนมากระบุทั้งชุดอักขระและการเข้ารหัสอักขระคำว่า "ชุดอักขระ" จึงมักถูกแทนที่อย่างอิสระสำหรับ "การเข้ารหัสอักขระ"

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

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

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

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


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

1
@ Mirich ไม่การเรียงเป็นข้อมูลเกี่ยวกับวิธีการเรียงลำดับอักขระ ภูมิภาคต่าง ๆ ของโลกต้องการเรียงลำดับอักขระด้วยวิธีที่ต่างกัน
erickson

3

ฉันแนะนำให้ใช้utf8mb4_unicode_ciซึ่งเป็นไปตามมาตรฐาน Unicode สำหรับการเรียงลำดับและการเปรียบเทียบซึ่งเรียงลำดับอย่างถูกต้องในภาษาที่หลากหลายมาก


3
จาก OP: "ฉันขอคำอธิบายของทั้งสองและวิธีการเลือกพวกเขา"
Dan Esparza

1
@simhumileco, ขอโทษเพื่อนฉันเพิ่งเริ่มต้นและแค่ต้องการความกระจ่างของคุณ ดังนั้นฉันสามารถเข้าใจการเรียงเช่นนี้มันเป็นสิ่งที่ทำให้แน่ใจว่าตัวละครแต่ละตัว (เป็นภาษาละตินหรือจีน) ได้รับการยอมรับอย่างถูกต้องและได้รับการเข้ารหัสตามลำดับ ถูกต้องหรือไม่ ฉันหวังว่าคุณจะตอบกลับ
Mirich

1
@Mirich ทุกอย่างขึ้นอยู่กับสิ่งที่คุณใช้การเข้ารหัสในสถานที่อื่น ๆ ถ้าคุณใช้UTF-8การเข้ารหัสในที่อยู่นอกระบบการทำงานของฐานข้อมูลแล้วทุกอย่างในฐานข้อมูลก็ควรจะเขียนอย่างถูกต้องหากคุณใช้utf8mb4ในMySQL เมื่อพูดถึงการดำเนินการจัดเรียงที่ถูกต้องการเปรียบเทียบและการแปลงข้อความสำหรับตัวอักขระเฉพาะในMySQLมันเป็นการยากที่จะหาทางออกที่สมบูรณ์แบบ แต่*_unicode_ciดีกว่าแน่นอน*_generalแต่ก็มีข้อเสีย โปรดอ่าน: dev.mysql.com/doc/refman/8.0/en/charset-unicode-sets.html
simhumileco
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.