Kolace a citlivost malých a malých písmen

Poznámka

Tato funkce byla zavedena v EF Core 5.0.

Zpracování textu v databázích může být složité a vyžaduje více pozornosti uživatelů, než by bylo podezřelé. Pro jednu věc se databáze výrazně liší v tom, jak zpracovávají text; Zatímco některé databáze ve výchozím nastavení rozlišují malá a velká písmena (např. Sqlite, PostgreSQL), jiné nerozlišují malá a velká písmena (SQL Server, MySQL). Vzhledem k použití indexů může mít navíc dalekosáhlý dopad na výkon dotazů citlivost na malá a velká písmena a podobné aspekty: i když může být vhodné použít string.ToLower k vynucení porovnání s rozlišováním velkých a malých písmen v databázi, může to zabránit tomu, aby aplikace používala indexy. Tato stránka podrobně popisuje, jak nakonfigurovat citlivost malých a malých písmen nebo obecnější kolace a jak to provést efektivním způsobem bez ohrožení výkonu dotazů.

Úvod do kolací

Základním konceptem při zpracování textu je kolace, což je sada pravidel určující, jak jsou textové hodnoty seřazeny a porovnávány pro rovnost. Když například kolace nerozlišuje malá a velká písmena rozdíly mezi velkými a malých písmeny pro účely porovnání rovnosti, kolace s rozlišováním velkých a malých písmen nerozlišuje malá a velká písmena, kolace nerozlišuje malá a velká písmena. Vzhledem k tomu, že citlivost malých a malých písmen je citlivá na jazykovou verzi (např. i a I představují různá písmena v turečtině), existuje několik kolací bez rozlišování malých a malých písmen, přičemž každá z nich má vlastní sadu pravidel. Rozsah kolací se také rozšiřuje nad rámec citlivosti malých a malých písmen na další aspekty dat znaků; v němčině je například někdy (ale ne vždy) žádoucí zacházet ä s nimi a ae jako shodný. Kolace také definují, jak jsou textové hodnoty seřazeny: zatímco německé místa ä za a, švédština je umístí na konec abecedy.

Všechny textové operace v databázi používají kolaci (bez ohledu na to, jestli explicitně nebo implicitně) určují, jak operace porovnává a objednává řetězce. Skutečný seznam dostupných kolací a jejich schémat pojmenování je specifický pro databázi; Odkazy na relevantní stránky dokumentace různých databází najdete v následující části . Naštěstí databáze obecně umožňují definovat výchozí kolaci na úrovni databáze nebo sloupce a explicitně určit, která kolace se má použít pro konkrétní operace v dotazu.

Kolace databáze

Ve většině databázových systémů je výchozí kolace definována na úrovni databáze; pokud není přepsáno, tato kolace se implicitně vztahuje na všechny textové operace, ke kterým dochází v této databázi. Kolace databáze je obvykle nastavena při vytváření databáze (prostřednictvím CREATE DATABASE příkazu DDL) a pokud není zadána, výchozí hodnota je nastavená na hodnotu na úrovni serveru určenou v době instalace. Například výchozí kolace na úrovni serveru v SQL Server pro národní prostředí počítače "Angličtina (USA)" je SQL_Latin1_General_CP1_CI_AS, což je kolace citlivá na malá a malá písmena. Ačkoli databázové systémy obvykle umožňují měnit kolaci existující databáze, může to vést k komplikacím; Před vytvořením databáze se doporučuje vybrat kolaci.

Při použití migrací EF Core ke správě schématu databáze nakonfiguruje následující postup v metodě modelu OnModelCreating SQL Server databázi tak, aby používala kolaci s rozlišováním velkých a malých písmen:

modelBuilder.UseCollation("SQL_Latin1_General_CP1_CS_AS");

Kolace sloupců

Kolace lze také definovat u textových sloupců a přepíše výchozí nastavení databáze. To může být užitečné, pokud některé sloupce potřebují nerozlišovat malá a velká písmena, zatímco zbytek databáze musí být citlivý na malá a velká písmena.

Při použití migrací EF Core ke správě schématu databáze nakonfiguruje následující sloupec pro Name vlastnost nerozlišující malá a velká písmena v databázi, která je jinak nakonfigurována tak, aby byla citlivá na malá a velká písmena:

modelBuilder.Entity<Customer>().Property(c => c.Name)
    .UseCollation("SQL_Latin1_General_CP1_CI_AS");

Explicitní kolace v dotazu

V některých případech musí být stejný sloupec dotazován pomocí různých kolací podle různých dotazů. Jeden dotaz může například potřebovat provést porovnání s rozlišováním velkých a malých písmen ve sloupci, zatímco jiný může potřebovat provést porovnání bez rozlišování velkých a malých písmen ve stejném sloupci. Toho lze dosáhnout explicitním zadáním kolace v rámci samotného dotazu:

var customers = context.Customers
    .Where(c => EF.Functions.Collate(c.Name, "SQL_Latin1_General_CP1_CS_AS") == "John")
    .ToList();

Tím se vygeneruje COLLATE klauzule v dotazu SQL, která používá kolaci s rozlišováním velkých a malých písmen bez ohledu na kolaci definovanou na úrovni sloupce nebo databáze:

SELECT [c].[Id], [c].[Name]
FROM [Customers] AS [c]
WHERE [c].[Name] COLLATE SQL_Latin1_General_CP1_CS_AS = N'John'

Explicitní kolace a indexy

Indexy jsou jedním z nejdůležitějších faktorů výkonu databáze – dotaz, který funguje efektivně s indexem, může zastavit bez tohoto indexu. Indexy implicitně dědí kolaci sloupce; to znamená, že všechny dotazy ve sloupci mají automaticky nárok na použití indexů definovaných v daném sloupci za předpokladu, že dotaz nezadává jinou kolaci. Určení explicitní kolace v dotazu obecně zabrání tomu, aby tento dotaz používal index definovaný v daném sloupci, protože kolace se už neshodují; Proto se doporučuje při používání této funkce postupovat opatrně. Vždy je vhodnější definovat kolaci na úrovni sloupce (nebo databáze), což všem dotazům umožňuje implicitně používat kolaci a využívat výhod libovolného indexu.

Upozorňujeme, že některé databáze umožňují definovat kolaci při vytváření indexu (např. PostgreSQL, Sqlite). To umožňuje definovat více indexů ve stejném sloupci a zrychlit operace s různými kolacemi (například rozlišování velkých a malých a malých písmen). Další podrobnosti najdete v dokumentaci poskytovatele databáze.

Upozornění

Vždy zkontrolujte plány dotazů vašich dotazů a ujistěte se, že se správné indexy používají v důležitých dotazech s výkonem, které spouští velké objemy dat. Přepsání citlivosti malých a malých písmen v dotazu prostřednictvím EF.Functions.Collate (nebo voláním string.ToLower) může mít velmi významný vliv na výkon vaší aplikace.

Překlad předdefinovaných operací řetězců .NET

V rozhraní .NET se ve výchozím nastavení rozlišují velká a malá písmena: s1 == s2 provádí pořadové porovnání, které vyžaduje, aby řetězce byly identické. Vzhledem k tomu, že se výchozí kolace databází liší a protože je žádoucí, aby jednoduché rovnosti používaly indexy, EF Core se nepokouší přeložit jednoduchou operaci s rozlišováním malých a malých písmen na operaci databáze: Rovnost jazyka C# se přeloží přímo na SQL rovnost, která může nebo nemusí být citlivá na malá a malá písmena v závislosti na konkrétní používané databázi a konfiguraci kolace.

.NET navíc poskytuje přetížení string.Equals přijetí StringComparison výčtu, což umožňuje určit citlivost malých a malých a malých písmen a jazykovou verzi pro porovnání. EF Core se záměrně zdrží překladu těchto přetížení do SQL a pokus o jejich použití způsobí výjimku. Ef Core pro jednu věc neví, která kolace nerozlišují malá a velká a malá písmena, která by se měla použít. Důležitější je, že použití kolace by ve většině případů zabránilo použití indexu, výrazně ovlivňuje výkon pro velmi základní a běžně používaný konstruktor .NET. Pokud chcete vynutit, aby dotaz používal porovnání s rozlišováním velkých a malých a malých písmen, zadejte kolaci explicitně podle EF.Functions.Collatevýše uvedených podrobností.

Další materiály

Informace specifické pro databázi

Další prostředky