Latin1_General_BIN ส่งผลกระทบต่อประสิทธิภาพเมื่อเปลี่ยนการเปรียบเทียบค่าเริ่มต้นของฐานข้อมูล


16

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

คำตอบ:


24

การเรียงใน SQL Serverกำหนดกฎสำหรับการจับคู่และการเรียงลำดับข้อมูลอักขระ โดยปกติคุณจะต้องเลือกการเรียงลำดับแรกตามความหมายของการเปรียบเทียบและเรียงลำดับตามที่ผู้บริโภคต้องการข้อมูล

โดยทั่วไปแล้วมนุษย์ไม่พบว่าการเปรียบเทียบไบนารีจะสร้างพฤติกรรมการเรียงลำดับและการเปรียบเทียบที่พวกเขาคาดหวัง ดังนั้นแม้ว่าสิ่งเหล่านี้จะให้ประสิทธิภาพที่ดีที่สุด (โดยเฉพาะอย่างยิ่งเวอร์ชัน BIN2 จุดรหัสบริสุทธิ์) การใช้งานส่วนใหญ่ไม่ได้ใช้

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

โดยทั่วไป Windows collations นั้นช้าที่สุดเนื่องจากการเปรียบเทียบ Unicode ที่ซับซ้อนและกฎการเรียงลำดับ อย่างไรก็ตามข้อเสนอเหล่านี้เข้ากันได้อย่างสมบูรณ์กับ Windows ใน SQL Server และได้รับการปรับปรุงอย่างสม่ำเสมอเพื่อให้ทันกับการเปลี่ยนแปลงในมาตรฐาน Unicode สำหรับการใช้งานที่ทันสมัยซึ่งมีข้อมูล Unicode แนะนำให้ใช้การเปรียบเทียบ Windows

TL; DR

หากสิ่งที่คุณต้องการคือการเปรียบเทียบและการเรียงลำดับความหมายแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่คุณควรเลือกรูปแบบ_CS_(สำหรับกรณีที่ละเอียดอ่อน) ของการเปรียบเทียบฐานใดก็ตามให้ลักษณะการทำงานที่คาดไว้สำหรับภาษาและวัฒนธรรมของผู้ใช้ ตัวอย่างเช่นทั้งสองแบบนี้เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่:

-- Latin1-General, case-sensitive, accent-sensitive
Latin1_General_CS_AS 

-- Latin1-General, case-sensitive, accent-sensitive for Unicode Data, 
-- SQL Server Sort Order 51 on Code Page 1252 for non-Unicode Data
SQL_Latin1_General_CP1_CS_AS

คุณสามารถดูคำจำกัดความเหล่านี้ได้โดยใช้sys.fn_helpcollations

ตัวอย่าง

สี่ตารางที่เหมือนกันยกเว้นการเปรียบเทียบ; หนึ่งไบนารีหนึ่งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่หนึ่งตัว

CREATE TABLE #Example_BIN
(
    string nvarchar(50) 
        COLLATE Latin1_General_BIN
        NOT NULL
);

CREATE TABLE #Example_CS
(
    string nvarchar(50) 
        COLLATE Latin1_General_CS_AI
        NOT NULL
);

CREATE TABLE #Example_CI
(
    string nvarchar(50) 
        COLLATE Latin1_General_CI_AI
        NOT NULL
);

CREATE TABLE #Example_SQL
(
    string varchar(50) -- Note varchar
        COLLATE SQL_Latin1_General_CP1_CS_AS
        NOT NULL
);

ข้อมูลตัวอย่างเดียวกันสำหรับแต่ละตาราง:

INSERT #Example_BIN
    (string)
VALUES
    (N'A'),
    (N'a'),
    (N'B'),
    (N'b'),
    (N'C'),
    (N'c');

INSERT #Example_CS
SELECT EB.string 
FROM #Example_BIN AS EB;

INSERT #Example_CI
SELECT EB.string 
FROM #Example_BIN AS EB;

INSERT #Example_SQL
SELECT EB.string 
FROM #Example_BIN AS EB;

ตอนนี้เราต้องการค้นหาสตริงที่มากกว่า 'a':

SELECT EB.string AS BIN
FROM #Example_BIN AS EB
WHERE EB.string > N'a'
ORDER BY EB.string;

SELECT EC.string AS CS
FROM #Example_CS AS EC
WHERE EC.string > N'a'
ORDER BY EC.string;

SELECT EC2.string AS CI
FROM #Example_CI AS EC2
WHERE EC2.string > N'a'
ORDER BY EC2.string;

SELECT ES.string AS SQL
FROM #Example_SQL AS ES
WHERE ES.string > 'a' -- not Unicode
ORDER BY ES.string;

ผล:

╔═════╗
 BIN 
╠═════╣
 b   
 c   
╚═════╝

╔════╗
 CS 
╠════╣
 A  
 b  
 B  
 c  
 C  
╚════╝

╔════╗
 CI 
╠════╣
 B  
 b  
 C  
 c  
╚════╝

╔═════╗
 SQL 
╠═════╣
 B   
 b   
 C   
 c   
╚═════╝

สุดท้าย ...

โปรดทราบว่าหากเราใช้ Unicode ตามตัวอักษรกับการเปรียบเทียบ SQL กฎการแปลงโดยนัยส่งผลให้เกิดการเปรียบเทียบการเปรียบเทียบกับ Windows:

SELECT ES.string AS SQL
FROM #Example_SQL AS ES
WHERE ES.string > N'a'
ORDER BY ES.string;

... และผลลัพธ์การเปรียบเทียบ SQL เปลี่ยนไป :

╔═════╗
 SQL 
╠═════╣
 A   
 B   
 b   
 C   
 c   
╚═════╝

10

ระบุว่านี่เป็นฐานข้อมูลที่มีอยู่แล้วซึ่งมีตารางที่กำหนดไว้แล้วมีบางอย่างที่เกี่ยวข้องกับการกระทำของการเปลี่ยนแปลงการจัดเรียงฐานข้อมูลเกินกว่าผลกระทบต่อประสิทธิภาพที่อาจเกิดขึ้นกับการดำเนินการ DML (ซึ่งจริงๆแล้วมีอยู่แล้ว) มีผลกระทบอย่างแท้จริงต่อประสิทธิภาพและการทำงานและการเปลี่ยนแปลงนี้ไม่เพียง แต่ไม่บรรลุเป้าหมายที่กำหนดไว้ (อย่างน้อยก็ไม่สม่ำเสมอ) แต่ก็น่าจะเปลี่ยนพฤติกรรม (หรือจะเปลี่ยนแปลงพฤติกรรมเมื่อสร้างตารางใหม่) ในแง่ของ วิธีการสั่งซื้อและบรรจุข้อมูล

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

  1. การเปรียบเทียบไบนารีเป็นมากกว่าตัวพิมพ์เล็กและตัวพิมพ์ใหญ่: ทุกอย่างละเอียดอ่อน! ดังนั้นโดยใช้การเปรียบเทียบไบนารี (สิ้นสุดใน_BINหรือ_BIN2) การเปรียบเทียบของคุณตอนนี้ยังเน้นสำเนียง, kana สำคัญไวไวด์ ธ และกลูเตนไว (อย่างน้อยที่ดูเหมือนจะเป็นแนวโน้มวันนี้ ;-)) นี่คือผลกระทบที่ต้องการในการเปลี่ยนแปลงนี้หรือไม่? ผู้ใช้ปลายทางคาดหวังว่าจะมีการเปลี่ยนแปลงพฤติกรรมนี้หรือไม่?

  2. การจัดเรียงมีผลต่อการเปรียบเทียบไม่เพียง แต่ยังรวมถึงการเรียงลำดับ การเปรียบเทียบไบนารีจะเรียงลำดับตามASCIIหรือUNICODEค่าไบต์ (ขึ้นอยู่กับVARCHARหรือNVARCHARตามลำดับ) ของแต่ละไบต์ ดังนั้นโดยการเลือกการเปรียบเทียบแบบไบนารีคุณกำลังละทิ้งกฎการกำหนดน้ำหนักเฉพาะภาษา / วัฒนธรรมที่สั่งตัวละครแต่ละตัว (แม้กระทั่งตัวละครในบางภาษาเช่นฮังการีซึ่งประกอบด้วย 2 ตัวอักษร) ตามตัวอักษรของวัฒนธรรมนั้น ดังนั้นถ้า "ch" ควรมาหลังจาก "k" ตามธรรมชาติแล้วนั่นจะไม่เกิดขึ้นโดยใช้การเปรียบเทียบแบบไบนารี นี่เป็นผลกระทบที่ต้องการจากการเปลี่ยนแปลงนี้อีกหรือไม่ ผู้ใช้ปลายทางคาดหวังว่าจะมีการเปลี่ยนแปลงพฤติกรรมนี้หรือไม่?

  3. หากคุณไม่มีข้อกำหนดเฉพาะด้านความเข้ากันได้แบบย้อนหลังสำหรับแอปพลิเคชันของคุณคุณควรใช้BIN2แทนการBINเปรียบเทียบโดยสมมติว่าคุณต้องการเรียงแบบไบนารีในตอนแรก การBIN2เปรียบเทียบถูกนำมาใช้ใน SQL Server 2005 และตามหน้า MSDN สำหรับแนวทางการใช้การเปรียบเทียบ BIN และ BIN2 :

    การเปรียบเทียบไบนารีก่อนหน้านี้ใน SQL Server ที่ลงท้ายด้วย "_BIN" ได้ทำการเปรียบเทียบรหัสแบบจุดต่อจุดรหัสที่ไม่สมบูรณ์สำหรับข้อมูล Unicode SQL Server ไบนารีที่เก่ากว่าเปรียบเทียบอักขระตัวแรกเป็น WCHAR ตามด้วยการเปรียบเทียบแบบไบต์ต่อไบต์

    ...

    คุณสามารถย้ายไปยัง [_BIN2] การเปรียบเทียบแบบไบนารีเพื่อใช้ประโยชน์จากการเปรียบเทียบจุดรหัสที่แท้จริงและคุณควรใช้การเปรียบเทียบแบบไบนารีใหม่สำหรับการพัฒนาแอปพลิเคชันใหม่

    ควรสังเกตว่าการ_BIN2เปรียบเทียบจะสะดวกตรงกับลักษณะการทำงานของOrdinalตัวเลือกของStringComparison Enumerationเช่นการเปรียบเทียบและการเรียงลำดับที่ทำในรหัส. NET โดยใช้ตัวเลือกนั้นจะให้ผลลัพธ์เดียวกันกับการดำเนินการเดียวกันกับ SQL Server (เมื่อใช้งาน) แน่นอนการ_BIN2เปรียบเทียบ)

  4. สำหรับเหตุผลที่คล้ายกับสิ่งที่เพิ่งได้รับการกล่าวเกี่ยวกับการ_BIN2เรียงเว้นแต่คุณจะมีความต้องการที่เฉพาะเจาะจงในการรักษาพฤติกรรมย้อนกลับเข้ากันได้คุณควรยันต่อโดยใช้การเปรียบเทียบของ Windows และไม่ SQL collations เซิร์ฟเวอร์เฉพาะ (คือคนที่เริ่มต้นด้วยการSQL_ได้รับการพิจารณาในขณะนี้ ค่อนข้าง "sucky" ;-))

  5. เมื่อใช้ข้อมูล Unicode (เช่นสตริงนำหน้าด้วยNหรือเข้ามาใน SQL Server จากรหัสแอปที่ระบุประเภทข้อมูลเป็นNCharหรือNVarChar) ฉันไม่เห็นว่าการใช้การเปรียบเทียบหนึ่งกับอื่นจะสร้างความแตกต่างสำหรับการแทรกหรือการปรับปรุงNCHARหรือNVARCHARเขตข้อมูลสตริง .

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

  6. สำคัญมาก!!! เมื่อเปลี่ยนการเปรียบเทียบค่าเริ่มต้นของฐานข้อมูลการเปรียบเทียบที่ระบุสำหรับฟิลด์สตริงที่มีอยู่ในตารางใด ๆ ที่มีอยู่จะไม่เปลี่ยนแปลง แต่ฟิลด์ใหม่ใด ๆจะมีการเปรียบเทียบค่าเริ่มต้นของฐานข้อมูล (เว้นแต่จะถูกเขียนทับผ่านส่วนCOLLATEคำสั่ง) สิ่งนี้จะส่งผลต่อข้อความค้นหาของคุณในสามวิธี:

    1)หากมีข้อสงสัยใด ๆ เข้าร่วมในเขตข้อมูลที่มีอยู่เหล่านั้นไปยังเขตข้อมูลใหม่ใด ๆ คุณจะได้รับข้อผิดพลาดการเปรียบเทียบไม่ตรงกัน:

    USE [master];
    GO
    
    IF (DB_ID(N'ChangeCollationTest') IS NOT NULL)
    BEGIN
        PRINT 'Dropping [ChangeCollationTest] DB...';
        ALTER DATABASE [ChangeCollationTest]
            SET SINGLE_USER
            WITH ROLLBACK IMMEDIATE;
    
        DROP DATABASE [ChangeCollationTest];
    END;
    GO
    
    PRINT 'Creating [ChangeCollationTest] DB...';
    CREATE DATABASE [ChangeCollationTest]
        COLLATE SQL_Latin1_General_CP1_CI_AS;
    GO
    
    USE [ChangeCollationTest];
    GO
    
    CREATE TABLE [CollateTest-SQL_Latin1_General_CP1_CI_AS]
                 (Col1 NVARCHAR(50) COLLATE DATABASE_DEFAULT, Col2 NVARCHAR(50));
    SELECT *
    FROM   sys.columns sc
    WHERE  sc.[object_id] = OBJECT_ID(N'[CollateTest-SQL_Latin1_General_CP1_CI_AS]');
    -- "collation_name" for both fields shows: SQL_Latin1_General_CP1_CI_AS
    GO
    
    USE [master];
    GO
    ALTER DATABASE [ChangeCollationTest]
        COLLATE Latin1_General_BIN2;
    GO
    USE [ChangeCollationTest];
    GO
    
    CREATE TABLE [CollateTest-Latin1_General_BIN2]
                 (Col1 NVARCHAR(50) COLLATE DATABASE_DEFAULT, Col2 NVARCHAR(50));
    SELECT *
    FROM   sys.columns sc
    WHERE  sc.[object_id] = OBJECT_ID(N'[CollateTest-Latin1_General_BIN2]');
    -- "collation_name" for both fields shows: Latin1_General_BIN2
    GO
    
    
    SELECT *
    FROM   dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] ctSQL
    INNER JOIN  dbo.[CollateTest-Latin1_General_BIN2] ctWIN
            ON  ctWIN.Col1 = ctSQL.Col1;

    ผลตอบแทน:

    Msg 468, Level 16, State 9, Line 4
    Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and
    "Latin1_General_BIN2" in the equal to operation.

    2) เพรดิเคต / ตัวกรองในฟิลด์ที่มีอยู่ของตารางที่มีอยู่ (ตั้งค่าเป็นการเปรียบเทียบค่าเริ่มต้นก่อนหน้า) ที่เปรียบเทียบกับตัวอักษรสตริงหรือตัวแปรจะไม่มีข้อผิดพลาด แต่แน่นอนว่าพวกเขาอาจได้รับผลกระทบ ทั้งสองข้างและแปลงสตริงตัวอักษรหรือตัวแปรให้เป็นการจัดเรียงของฟิลด์โดยอัตโนมัติ เปิดใช้งาน "รวมแผนการดำเนินการตามจริง" (Control-M) จากนั้นดำเนินการต่อไปนี้ (สมมติว่าคุณได้เรียกใช้แบบสอบถามที่แสดงด้านบนแล้ว):

    SELECT *
    FROM   dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] ctSQL
    WHERE  ctSQL.Col1 = N'a';
    -- Unspecified collations on string literals and variables assume the database default
    -- collation. This mismatch doesn't cause an error because SQL Server adds a
    -- "[Col1]=CONVERT_IMPLICIT(nvarchar(4000),[@1],0)" but it can hurt performance.
    
    SELECT *
    FROM   dbo.[CollateTest-Latin1_General_BIN2] ctWIN
    WHERE  ctWIN.Col1 = N'a';
    -- No CONVERT_IMPLICIT; plan shows "[Col1]=[@1]".

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

    INSERT INTO dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] (Col1)
    VALUES (N'a'), (N'A');
    
    SELECT ctSQL.Col1
    FROM   dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] ctSQL
    WHERE  ctSQL.Col1 = N'a';

    ผลตอบแทน:

    Col1
    ----
    a
    A

    D'โอ้! ไม่เพียง แต่จะมีประสิทธิภาพเล็กน้อย (หรืออาจมีนัยสำคัญมากกว่านี้) สำหรับการค้นหานี้เนื่องจากCONVERT_IMPLICIT()แต่มันไม่ได้ทำงานในลักษณะที่เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ที่ต้องการ

    ดังนั้นหากการเปรียบเทียบมีการเปลี่ยนแปลงในฐานข้อมูลที่มีตารางอยู่แล้วใช่ทั้งประสิทธิภาพและฟังก์ชั่นจะได้รับผลกระทบ

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


ควรสังเกตว่าคุณสามารถระบุการเปรียบเทียบตามเงื่อนไขได้ตลอดเวลา ส่วนคำสั่งCOLLATEสามารถเพิ่มWHEREเงื่อนไขORDER BYและสถานที่ส่วนใหญ่ที่ยอมรับสตริง

ตัวอย่างที่ 1 (เงื่อนไข WHERE):

SELECT tmp.col AS [SQL-CaseSensitive]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
WHERE tmp.col > 'a' COLLATE SQL_Latin1_General_CP1_CS_AS;

SELECT tmp.col AS [Windows-CaseSensitive]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
WHERE tmp.col > 'a' COLLATE Latin1_General_CS_AI;

ผลตอบแทน:

SQL-CaseSensitive
-----------------
b
B

Windows-CaseSensitive
-----------------
A
b
B

ตัวอย่างที่ 2 (เรียงตาม):

SELECT tmp.col AS [Windows-CaseSensitive]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
ORDER BY tmp.col COLLATE Latin1_General_CS_AI;

SELECT tmp.col AS [Windows-Binary]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
ORDER BY tmp.col COLLATE Latin1_General_BIN2;

ผลตอบแทน:

Windows-CaseSensitive
-----------------
a
A
b
B

Windows-Binary
-----------------
A
B
a
b

ตัวอย่างที่ 3 (คำสั่ง IF):

IF ('A' = 'a') SELECT 1 AS [DatabaseDefault-CaseInsensitive?];
-- if the DB is not case-sensitive or binary, returns 1

IF ('A' = 'a' COLLATE Latin1_General_BIN2) SELECT 2 AS [Windows-Binary];

ผลตอบแทน:

DatabaseDefault-CaseInsensitive?
--------------------------------
1

{nothing}

ตัวอย่างที่ 4 (เชื่อมโยงกับพารามิเตอร์อินพุตของฟังก์ชัน):

SELECT  UNICODE(N'🂡') AS [UCS-2],
        UNICODE(N'🂡' COLLATE Latin1_General_100_CI_AS_SC) AS [UTF-16];
-- This character is a Unicode supplemental character and is not part of the
-- default UCS-2 encoding. In order for built-in functions to handle these
-- characters correctly, either the DB default collation needs to end in
-- "_SC" (available as of SQL Server 2012), or use as shown here.
-- See the character in more detail here: http://unicode-table.com/en/1F0A1/

ผลตอบแทน:

UCS-2    UTF-16
------   -------
55356    127137

ค่า UCS-2 ที่ 55,356 นั้นถูกต้องบางส่วนซึ่งเป็นค่าแรกของสองค่าใน "คู่ตัวแทน" แต่หากไม่ได้รับการ_SCเปรียบเทียบอย่างชัดเจนUNICODE()ฟังก์ชันสามารถดูอักขระแต่ละตัวเป็นค่าไบต์คู่เท่านั้นและไม่ทราบวิธีจัดการคู่ตัวแทนดับเบิลไบต์คู่อย่างถูกต้อง


UPDATE

แม้จะมีตัวอย่างทั้งหมดข้างต้นแง่มุมหนึ่งของการเปรียบเทียบ Case Sensitive ที่มักถูกมองข้ามและถูกทำให้ไร้ผลโดยการเปรียบเทียบ / การเปรียบเทียบแบบไบนารีเป็นการทำให้เป็นมาตรฐาน (องค์ประกอบและการสลายตัว) ซึ่งเป็นส่วนหนึ่งของ Unicode

ตัวอย่างที่ 5 (เมื่อการเปรียบเทียบแบบไบนารีไม่ใช่คำนึงถึงขนาดตัวพิมพ์):

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

SELECT 'Equal' AS [Binary],
       NCHAR(0x00FC) AS [ü],
       N'u' + NCHAR(0x0308) AS [u + combining diaeresis]
WHERE  NCHAR(0x00FC) COLLATE Latin1_General_100_BIN2
    =  N'u' + NCHAR(0x0308) COLLATE Latin1_General_100_BIN2
-- No result as they are a different number of code points,
-- as well as being different code points.

SELECT 'Equal' AS [Case-Sensitive],
       NCHAR(0x00FC) AS [ü],
       N'u' + NCHAR(0x0308) AS [u + combining diaeresis]
WHERE  NCHAR(0x00FC) COLLATE Latin1_General_100_CS_AS -- ü
    =  N'u' + NCHAR(0x0308) COLLATE Latin1_General_100_CS_AS -- u + combining diaeresis
-- Result set returned, even being a different number of code points AND Accent Sensitive,
-- due to normalization

ผลตอบแทน:

Binary            ü     u + combining diaeresis
-------          ---   -------------------------
{nothing}

Case-Sensitive    ü     u + combining diaeresis
---------------  ---   -------------------------
Equal             ü     ü

การเปรียบเทียบแบบตัวพิมพ์เล็กและใหญ่ให้ตัวอักษรแบบกว้างเพื่อให้เทียบเท่ากับการเทียบเท่าแบบไม่กว้าง

IF (N'sofia' = N'sofia' COLLATE Latin1_General_100_BIN2)
  SELECT 'Values are the same' AS [Binary]
ELSE
  SELECT 'Values are different' AS [Binary];


IF (N'sofia' = N'sofia' COLLATE Latin1_General_100_CS_AS)
  SELECT 'Values are the same' AS [Case-Sensitive]
ELSE
  SELECT 'Values are different' AS [Case-Sensitive];

ผลตอบแทน:

Binary
---------------
Values are different


Case-Sensitive
---------------
Values are the same

Ergo:

การเปรียบเทียบแบบไบนารี ( _BINและ_BIN2) ไม่ได้เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่!

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