다음을 통해 공유


정렬 방식 및 코드 페이지

In-Memory OLTP에는 메모리 최적화 테이블의 (var)char 열에 대해 지원되는 코드 페이지와 인덱스 및 네이티브로 컴파일된 저장 프로시저에 사용되는 지원되는 데이터 정렬에 제한이 있습니다.

(var)char 값의 코드 페이지에서는 테이블에 저장된 문자와 바이트 표현 간의 매핑을 결정합니다. 예를 들어 Windows Latin 1 코드 페이지(1252, SQL Server 기본값)를 사용하는 경우 문자 'a'는 바이트 0x61 해당합니다.

(var)char 값의 코드 페이지는 값과 연결된 데이터 정렬에 의해 결정됩니다. 예를 들어, 데이터 정렬 방식인 SQL_Latin1_General_CP1_CI_AS는 연결된 코드 페이지 1252를 갖고 있습니다.

값의 데이터 정렬은 데이터베이스 데이터 정렬에서 상속되거나 COLLATE 키워드를 사용하여 명시적으로 지정할 수 있습니다. 데이터베이스에 메모리 최적화 테이블 또는 고유하게 컴파일된 저장 프로시저가 포함된 경우 데이터베이스 데이터 정렬을 변경할 수 없습니다. 다음 예제에서는 데이터베이스 데이터 정렬을 설정하고 다른 데이터 정렬이 있는 열이 있는 테이블을 만듭니다. 데이터베이스는 라틴어 대/소문자를 구분하지 않는 데이터 정렬을 사용합니다.

인덱스는 BIN2 데이터 정렬을 사용하는 경우에만 문자열 열에 만들 수 있습니다. LastName 변수는 BIN2 데이터 정렬을 사용합니다. FirstName은 대소문자를 구분하지 않고 악센트를 민감하게 인식하는, CI_AS 데이터베이스 기본값을 사용합니다.

중요합니다

BIN2 데이터 정렬을 사용하지 않는 인덱스 문자열 열에서는 순서를 기준으로 또는 그룹화하여 사용할 수 없습니다.

CREATE DATABASE IMOLTP  
  
ALTER DATABASE IMOLTP ADD FILEGROUP IMOLTP_mod CONTAINS MEMORY_OPTIMIZED_DATA  
ALTER DATABASE IMOLTP ADD FILE( NAME = 'IMOLTP_mod' , FILENAME = 'c:\data\IMOLTP_mod') TO FILEGROUP IMOLTP_mod;  
--GO  
  
--  set the database collations  
ALTER DATABASE IMOLTP COLLATE Latin1_General_100_CI_AS  
GO  
  
--  
USE IMOLTP   
GO  
  
-- create a table with collation  
CREATE TABLE Employees (  
  EmployeeID int NOT NULL ,   
  LastName nvarchar(20) COLLATE Latin1_General_100_BIN2 NOT NULL INDEX IX_LastName NONCLUSTERED,   
  FirstName nvarchar(10) NOT NULL ,  
  CONSTRAINT PK_Employees PRIMARY KEY NONCLUSTERED HASH(EmployeeID)  WITH (BUCKET_COUNT=1024)  
) WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_AND_DATA)  
GO  

메모리 최적화 테이블 및 고유하게 컴파일된 저장 프로시저에는 다음과 같은 제한 사항이 적용됩니다.

  • 메모리 최적화 테이블의 (var)char 열은 코드 페이지 1252 데이터 정렬 설정을 사용해야 합니다. 이 제한은 n(var)char 열에는 적용되지 않습니다. 다음 코드는 1252개의 데이터 정렬을 모두 검색합니다.

    -- all supported collations for (var)char columns in memory-optimized tables  
    select * from sys.fn_helpcollations()  
    where collationproperty(name, 'codepage') = 1252;  
    

    라틴 문자가 아닌 문자를 저장해야 하는 경우 n(var)char 열을 사용합니다.

  • (n)(var)char 열의 인덱스는 BIN2 데이터 정렬로만 지정할 수 있습니다(첫 번째 예제 참조). 다음 쿼리는 지원되는 모든 BIN2 데이터 정렬을 검색합니다.

    -- all supported collations for indexes on memory-optimized tables and   
    -- comparison/sorting in natively compiled stored procedures  
    select * from sys.fn_helpcollations() where name like '%BIN2'  
    

    해석된 Transact-SQL을 통해 테이블에 액세스하는 경우 키워드를 COLLATE 사용하여 식 또는 정렬 작업으로 데이터 정렬을 변경할 수 있습니다. 이 샘플은 마지막 예제를 참조하세요.

  • 데이터베이스 데이터 정렬이 코드 페이지 1252 데이터 정렬이 아닌 경우 고유하게 컴파일된 저장 프로시저는 (var)char 형식의 매개 변수, 지역 변수 또는 문자열 상수를 사용할 수 없습니다.

  • 고유하게 컴파일된 저장 프로시저 내의 모든 식 및 정렬 작업은 BIN2 데이터 정렬을 사용해야 합니다. 모든 비교 및 정렬 작업은 문자의 유니코드 코드 포인트(이진 표현)를 기반으로 한다는 의미입니다. 예를 들어 모든 정렬은 대/소문자를 구분합니다('Z'는 'a' 앞에 옵니다). 필요한 경우 대/소문자를 구분하지 않는 정렬 및 비교에 해석된 Transact-SQL 사용합니다.

  • UTF-16 데이터의 잘림은 고유하게 컴파일된 저장 프로시저 내에서 지원되지 않습니다. 데이터 정렬에 _SC 속성이 있는 경우, n(var)char(n) 값을 n(var)char(i) 형식으로 변환할 수 없습니다. 예를 들어 다음이 지원되지 않습니다.

    -- column definition using an _SC collation  
     c2 nvarchar(200) collate Latin1_General_100_CS_AS_SC not null   
    -- assignment to a smaller variable, requiring truncation  
     declare @c2 nvarchar(100) = '';  
     select @c2 = c2  
    

    UTF-16 데이터가 있는 LEN, SUBSTRING, LTRIM 및 RTRIM과 같은 문자열 조작 함수는 고유하게 컴파일된 저장 프로시저 내에서 지원되지 않습니다. _SC 데이터 정렬이 있는 n(var)char 값에는 이러한 문자열 조작 함수를 사용할 수 없습니다.

    잘림을 방지할 수 있을 만큼 큰 형식을 사용하여 변수를 선언합니다.

다음 예제에서는 In-Memory OLTP의 데이터 정렬 제한에 대한 몇 가지 의미와 해결 방법을 보여 줍니다. 이 예제에서는 위에서 지정한 Employees 테이블을 사용합니다. 이 샘플은 모든 직원을 나열합니다. LastName의 경우 이진 데이터 정렬로 인해 대문자 이름이 소문자보다 앞에 정렬됩니다. 따라서 대문자 문자의 코드 포인트가 낮기 때문에 'Thomas'는 'nolan' 앞에 옵니다. FirstName에는 대/소문자를 구분하지 않는 데이터 정렬이 있습니다. 따라서 정렬은 문자의 코드 포인트가 아니라 알파벳 문자를 기준으로 합니다.

-- insert a number of values  
INSERT Employees VALUES (1,'thomas', 'john')  
INSERT Employees VALUES (2,'Thomas', 'rupert')  
INSERT Employees VALUES (3,'Thomas', 'Jack')  
INSERT Employees VALUES (4,'Thomas', 'annie')  
INSERT Employees VALUES (5,'nolan', 'John')  
GO  
  
-- ===========  
SELECT EmployeeID, LastName, FirstName FROM Employees  
ORDER BY LastName, FirstName  
GO  
  
-- ===========  
-- specify collation: sorting uses case-insensitive collation, thus 'nolan' comes before 'Thomas'  
SELECT * FROM Employees  
ORDER BY LastName COLLATE Latin1_General_100_CI_AS, FirstName  
GO  
  
-- ===========  
-- retrieve employee by Name  
-- must use BIN2 collation for comparison in natively compiled stored procedures  
CREATE PROCEDURE usp_EmployeeByName @LastName nvarchar(20), @FirstName nvarchar(10)  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS BEGIN ATOMIC WITH   
(  TRANSACTION ISOLATION LEVEL = SNAPSHOT,  
  LANGUAGE = N'us_english'  
)  
  SELECT EmployeeID, LastName, FirstName FROM dbo.Employees  
  WHERE   
    LastName = @LastName AND  
    FirstName COLLATE Latin1_General_100_BIN2 = @FirstName  
  
END  
GO  
  
-- this does not return any rows, as EmployeeID 1 has first name 'john', which is not equal to 'John' in a binary collation  
EXEC usp_EmployeeByName 'thomas', 'John'  
  
-- this retrieves EmployeeID 1  
EXEC usp_EmployeeByName 'thomas', 'john'  

또한 참조하십시오

메모리 내 OLTP(메모리 내 최적화)