ฉันสามารถอ่านเอกสารMySQLและมันค่อนข้างชัดเจน แต่เราจะตัดสินใจได้อย่างไรว่าจะใช้อักขระตัวใด การเปรียบเทียบการจัดเรียงข้อมูลมีผลอย่างไร
ฉันขอคำอธิบายของทั้งสองและวิธีการเลือกพวกเขา
ฉันสามารถอ่านเอกสารMySQLและมันค่อนข้างชัดเจน แต่เราจะตัดสินใจได้อย่างไรว่าจะใช้อักขระตัวใด การเปรียบเทียบการจัดเรียงข้อมูลมีผลอย่างไร
ฉันขอคำอธิบายของทั้งสองและวิธีการเลือกพวกเขา
คำตอบ:
จากเอกสาร 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 'ในหนึ่งในสองการเปรียบเทียบภาษาเยอรมัน)
การเข้ารหัสอักขระเป็นวิธีเข้ารหัสอักขระเพื่อให้พอดีกับหน่วยความจำ นั่นคือถ้าชุดอักขระเป็น ISO-8859-15 สัญลักษณ์ยูโร€จะถูกเข้ารหัสเป็น 0xa4 และใน UTF-8 ก็จะเป็น 0xe282ac
การเรียงเป็นวิธีเปรียบเทียบอักขระใน latin9 มีตัวอักษรเป็นe é è ê f
ถ้าเรียงลำดับตามการแสดงฐานสองของพวกเขามันจะไปe f é ê è
แต่ถ้าการเปรียบเทียบถูกตั้งค่าเป็นตัวอย่างเช่นฝรั่งเศสคุณจะมีพวกเขาตามลำดับที่คุณคิดว่าพวกเขา จะเป็นซึ่งเป็นทั้งหมดของมีค่าเท่ากันแล้วe é è ê
f
ชุดอักขระเป็นชุดย่อยของร่ายมนตร์ที่เป็นลายลักษณ์อักษรทั้งหมด การเข้ารหัสอักขระระบุวิธีที่อักขระเหล่านั้นถูกแมปกับค่าตัวเลข การเข้ารหัสอักขระบางตัวเช่น UTF-8 และ UTF-16 สามารถเข้ารหัสอักขระใด ๆ ในชุดอักขระสากล อื่น ๆ เช่น US-ASCII หรือ ISO-8859-1 สามารถเข้ารหัสชุดย่อยขนาดเล็กเท่านั้นเนื่องจากพวกเขาใช้ 7 และ 8 บิตต่อตัวอักษรตามลำดับ เนื่องจากมาตรฐานจำนวนมากระบุทั้งชุดอักขระและการเข้ารหัสอักขระคำว่า "ชุดอักขระ" จึงมักถูกแทนที่อย่างอิสระสำหรับ "การเข้ารหัสอักขระ"
การเปรียบเทียบประกอบด้วยกฎที่ระบุวิธีการเปรียบเทียบอักขระสำหรับการเรียงลำดับ กฎการจัดเรียงอาจเป็นภาษาเฉพาะ: ลำดับที่เหมาะสมของอักขระสองตัวนั้นแตกต่างกันไปในแต่ละภาษา
การเลือกชุดอักขระและการเปรียบเทียบจะขึ้นอยู่กับว่าแอปพลิเคชันของคุณเป็นสากลหรือไม่ หากไม่คุณกำหนดเป้าหมายสถานที่ใด
ในการเลือกชุดอักขระที่คุณต้องการสนับสนุนคุณต้องพิจารณาใบสมัครของคุณ หากคุณเก็บข้อมูลที่ผู้ใช้ป้อนมาอาจเป็นเรื่องยากที่จะคาดการณ์ตำแหน่งที่ตั้งทั้งหมดที่จะใช้ซอฟต์แวร์ของคุณในที่สุด เพื่อสนับสนุนพวกเขาทั้งหมดมันอาจเป็นการดีที่สุดที่จะสนับสนุน UCS (Unicode) ตั้งแต่เริ่มต้น อย่างไรก็ตามมีค่าใช้จ่ายสำหรับสิ่งนี้ อักขระยุโรปตะวันตกจำนวนมากจะต้องใช้ที่เก็บข้อมูลสองไบต์ต่ออักขระแทนที่จะเป็นหนึ่งตัว
การเลือกการเรียงที่ถูกต้องสามารถช่วยเพิ่มประสิทธิภาพได้หากฐานข้อมูลของคุณใช้การเปรียบเทียบเพื่อสร้างดัชนีและใช้ดัชนีนั้นเพื่อจัดเรียงผลลัพธ์ อย่างไรก็ตามเนื่องจากกฎการเรียงมักจะเฉพาะสถานที่เกิดเหตุดัชนีนั้นจะไร้ค่าถ้าคุณต้องการเรียงลำดับผลลัพธ์ตามกฎของสถานที่อื่น
ฉันแนะนำให้ใช้utf8mb4_unicode_ci
ซึ่งเป็นไปตามมาตรฐาน Unicode สำหรับการเรียงลำดับและการเปรียบเทียบซึ่งเรียงลำดับอย่างถูกต้องในภาษาที่หลากหลายมาก
UTF-8
การเข้ารหัสในที่อยู่นอกระบบการทำงานของฐานข้อมูลแล้วทุกอย่างในฐานข้อมูลก็ควรจะเขียนอย่างถูกต้องหากคุณใช้utf8mb4
ในMySQL เมื่อพูดถึงการดำเนินการจัดเรียงที่ถูกต้องการเปรียบเทียบและการแปลงข้อความสำหรับตัวอักขระเฉพาะในMySQLมันเป็นการยากที่จะหาทางออกที่สมบูรณ์แบบ แต่*_unicode_ci
ดีกว่าแน่นอน*_general
แต่ก็มีข้อเสีย โปรดอ่าน: dev.mysql.com/doc/refman/8.0/en/charset-unicode-sets.html