sql >> Database >  >> RDS >> Sqlserver

UCS-2 en SQL Server

In tegenstelling tot sommige andere RDBMS's die het kiezen van een codering mogelijk maken, slaat SQL Server Unicode-gegevens alleen op in UTF-16 (Little Endian), en niet-Unicode-gegevens in een 8-bits codering (Extended ASCII, DBCS of EBCDIC) voor elke codepagina die wordt geïmpliceerd door de sortering van het veld.

Hun beslissing om te kiezen UCS-2 is logisch genoeg aangezien UTF-16 medio 1996 werd geïntroduceerd en in 2000 volledig werd gespecificeerd. Veel andere systemen gebruiken (of gebruikten) het ook (zie:https://en.wikipedia.org/wiki/UTF-16#Gebruik ). Hun beslissing om door te gaan met het is misschien meer twijfelachtig, hoewel het waarschijnlijk te wijten is aan het feit dat Windows en .NET UTF-16 zijn. De fysieke lay-out van de bytes is hetzelfde tussen UCS-2 en UTF-16, dus het upgraden van systemen van UCS-2 om UTF-16 te ondersteunen, zou puur functioneel moeten zijn zonder dat bestaande gegevens hoeven te worden gewijzigd.

Um Nee. Het maken van een aangepast door de gebruiker gedefinieerd type via SQLCLR is niet , op wat voor manier dan ook, om u een vervanging van elk native type te bezorgen. Het is erg handig om iets te maken om gespecialiseerde gegevens te verwerken. Maar strings, zelfs met een andere codering, zijn verre van gespecialiseerd. Als u deze route volgt voor uw stringgegevens, zou elke mate van bruikbaarheid van uw systeem worden vernietigd, om nog maar te zwijgen van de prestaties, aangezien u geen zou kunnen gebruiken ingebouwde tekenreeksfuncties. Als u iets op schijfruimte zou kunnen besparen, zou die winst teniet worden gedaan door wat u zou verliezen aan algehele prestaties. Het opslaan van een UDT gebeurt door het te serialiseren naar een VARBINARY . Dus om elke . te doen tekenreeksvergelijking OF sortering, buiten een "binaire" / "ordinale" vergelijking, zou u alle andere waarden één voor één terug moeten converteren naar UTF-8 om vervolgens de tekenreeksvergelijking uit te voeren die rekening kan houden met taalkundige verschillen.

Ook is die "documentatie" eigenlijk slechts voorbeeldcode / proof of concept-dingen. De code is geschreven in 2003 ( http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/CS/UTF8String/Utf8String.cs ) voor SQL Server 2005. Ik zag een script om de functionaliteit te testen, maar niets met prestaties.

Ja, heel erg waar. Standaard is de afhandeling van de ingebouwde functies alleen voor UCS-2. Maar vanaf SQL Server 2012 kunt u ze de volledige UTF-16-tekenset laten verwerken (nou ja, vanaf Unicode Versie 5 of 6, afhankelijk van uw besturingssysteem en versie van .NET Framework) door een van de sorteringen te gebruiken die heeft een naam die eindigt op _SC (d.w.z. aanvullende tekens).

Juist. UTF-16 en UCS-2 gebruiken beide 2-byte codepunten. Maar UTF-16 gebruikt sommige ervan in paren (d.w.z. surrogaatparen) om extra karakters toe te wijzen. De codepunten die voor deze paren worden gebruikt, zijn voor dit doel gereserveerd in UCS-2 en worden daarom niet gebruikt om naar bruikbare symbolen te verwijzen. Dit is de reden waarom u elk Unicode-teken in SQL Server kunt opslaan en het zal correct worden opgeslagen en opgehaald.

Correct, maar misleidend. Ja, UTF-8 heeft een variabele breedte, maar UTF-16 is ook enigszins variabel, aangezien alle aanvullende tekens zijn samengesteld uit twee dubbelbyte-codepunten. Daarom gebruikt UTF-16 2 of 4 bytes per symbool, hoewel UCS-2 altijd 2 bytes is. Maar dat is niet het misleidende deel. Wat misleidend is, is de implicatie dat elke andere Unicode-codering niet in staat is om alle andere codepunten te coderen. Terwijl UCS-2 ze kan vasthouden maar niet interpreteren, kunnen zowel UTF-16 als UTF-32 beide alle Unicode-codepunten toewijzen, net als UTF-8.

Dit kan waar zijn, maar het is volledig irrelevant vanuit een operationeel perspectief.

Nogmaals, waar, maar volledig irrelevant aangezien UTF-16 en UTF-32 ook alle Unicode-codepunten toewijzen.

Afhankelijk van de omstandigheden kan dit heel goed waar zijn, en je hebt gelijk als je je zorgen maakt over dergelijk verspillend gebruik. Zoals ik echter al zei in de vraag die tot deze leidde ( UTF-8-ondersteuning, SQL Server 2012 en de UTF8String UDT ), heb je een paar opties om de hoeveelheid verspilde ruimte te beperken als de meeste rijen in VARCHAR passen maar sommige moeten NVARCHAR . zijn . De beste optie is om RIJCOMPRESSIE of PAGINACOMPRESSIE in te schakelen (alleen Enterprise Editon!). Vanaf SQL Server 2008 R2 staan ​​ze niet-MAX NVARCHAR . toe velden om het "Standard Compression Scheme for Unicode" te gebruiken dat minstens zo goed is als UTF-8, en in sommige gevallen zelfs beter dan UTF-8. NVARCHAR(MAX) velden kunnen deze fraaie compressie niet gebruiken , maar hun IN ROW-gegevens kunnen baat hebben bij reguliere ROW- en/of PAGE-compressie. Zie het volgende voor een beschrijving van deze compressie en een grafiek waarin gegevensgroottes worden vergeleken voor:onbewerkte UCS-2 / UTF-16, UTF-8 en UCS-2 / UTF-16 met ingeschakelde gegevenscompressie.

SQL Server 2008 R2 - UCS2-compressie wat is het - Impact op SAP-systemen

Zie ook de MSDN-pagina voor Gegevenscompressie voor meer details, aangezien er enkele beperkingen zijn (buiten het feit dat deze alleen beschikbaar zijn in de Enterprise-editie -- MAAR beschikbaar gesteld voor allen edities die beginnen met SQL Server 2016, SP1 !!) en sommige omstandigheden waarin compressie de zaken erger kan maken.

De juistheid van die verklaring hangt af van hoe men "schijf" definieert. Als u het hebt over standaardonderdelen die u in een winkel uit de winkel kunt kopen voor gebruik in uw desktop / laptop, dan zeker. Maar als u het hebt over opslag op bedrijfsniveau die voor uw productiesystemen zal worden gebruikt, veel plezier met het uitleggen aan wie het budget beheert dat ze het SAN van meer dan een miljoen dollar dat u wilt niet moeten afwijzen omdat het "goedkoop is". ";-).

Geen die ik kan bedenken. Nou, zolang je geen vreselijk advies opvolgt om zoiets te doen, zoals het implementeren van die UDT, of het converteren van alle strings naar VARBINARY , of met behulp van NVARCHAR(MAX) voor alle stringvelden;-). Maar van alle dingen waar u zich zorgen over kunt maken, zou SQL Server met UCS-2 / UTF-16 daar niet een van moeten zijn.

Maar als om de een of andere reden dit probleem van geen native ondersteuning voor UTF-8 super belangrijk is, dan moet je misschien een ander RDBMS vinden om te gebruiken dat wel UTF-8 toestaat.

UPDATE 02-10-2018

Hoewel dit nog geen haalbare optie is, introduceert SQL Server 2019 native ondersteuning voor UTF-8 in VARCHAR / CHAR gegevenstypen. Er zijn momenteel te veel bugs om het te gebruiken, maar als ze zijn opgelost, dan is dit een optie voor sommige scenario's. Zie mijn bericht, "Native UTF-8-ondersteuning in SQL Server 2019:redder of valse profeet? ", voor een gedetailleerde analyse van deze nieuwe functie.



  1. Kan ik in MySQL referentiële integriteitscontroles uitstellen tot commit?

  2. Tools om in teamverband te werken met opgeslagen procedures in Oracle?

  3. dbms_scheduler Taak maken Niet actief Taak

  4. Kan geen verbinding maken van Intellij naar mySql die wordt uitgevoerd in docker-container - opgegeven combinatie van databasegebruiker en wachtwoord wordt afgewezen