JSON 열 및 인덱스 관리

완료됨

관계형 데이터베이스는 테이블의 모든 행에 동일한 열이 있는 경우에 가장 적합합니다. 구조를 한 번 정의하면 모든 레코드가 해당 구조를 따릅니다. 이 디자인은 필드가 예측 가능한 고객, 주문 또는 청구서와 같은 데이터에 적합합니다. 그러나 일부 데이터는 레코드마다 다릅니다. 저장해야 하는 특성은 항목 유형, 데이터 원본 또는 사용자가 선택한 항목에 따라 달라집니다. 기존 테이블 디자인에서는 대부분의 행에 대해 비어 있는 많은 열을 만들거나 여러 테이블에 데이터를 분할해야 합니다. JSON 열은 예측 가능한 부분을 일반 열에 유지하면서 변수 부분을 JSON으로 저장하는 또 다른 옵션을 제공합니다.

예를 들어 전자 상거래 제품 카탈로그에는 모든 항목에 적용되는 제품 이름, 가격 및 범주와 같은 공통 필드가 있습니다. 그러나 셔츠에는 크기와 색상이 필요하고, 노트북에는 프로세서 속도와 화면 크기가 필요하며, 책에는 저자 및 기타 특성이 필요합니다. JSON을 사용하면 공통 필드를 열로 저장하고 JSON 열에 범주별 특성을 배치합니다. 테이블 구조를 변경하지 않고 새 제품 유형을 추가할 수 있습니다.

JSON 열을 사용할 경우 이해

JSON 열을 사용하면 친숙한 SQL 구문을 사용하여 반구조화된 데이터를 쿼리하고 인덱싱할 수 있습니다. 유연한 데이터를 처리하기 위해 별도의 NoSQL 데이터베이스가 필요하지 않습니다. 이러한 시나리오에 대해 JSON을 고려합니다.

  • 사용자 기본 설정 - 테마, 언어 및 알림 옵션과 같은 설정은 사용자마다 다르며 기능을 추가할 때 변경됩니다.
  • API 응답 - 외부 서비스의 데이터에는 공급자가 API를 업데이트할 때 변경될 수 있는 중첩된 구조가 있습니다.
  • 감사 로그 - 테이블 스키마가 변경됨에 따라, 이전과 이후 상태를 기록하는 로그도 이에 맞게 조정되어야 합니다.
  • 다중 테넌트 애플리케이션 - 고객별로 다른 사용자 지정 필드가 필요합니다.
  • 유연한 메타데이터 - 태그, 레이블 및 속성은 레코드에 따라 다르며 고정 스키마에 맞지 않습니다.

JSON 열 만들기 및 쿼리

SQL Server 2025에는 쿼리 및 조작에 최적화된 이진 형식으로 JSON 문서를 저장하는 네이티브 json 데이터 형식 이 도입되었습니다. 네이티브 형식은 보다 효율적인 읽기(문서가 이미 구문 분석되어 있음), 보다 효율적인 쓰기(업데이트는 전체 문서를 다시 작성하지 않고 개별 값을 수정할 수 있음) 및 JSON NVARCHAR(MAX)을 저장하는 것에 비해 스토리지 압축을 향상합니다.

이전 버전의 SQL Server의 경우 열에 JSON을 저장합니다 NVARCHAR(MAX) .

JSON에서 값을 읽으려면 단일 값을 추출하거나 개체 또는 배열을 반환하는 것과 같은 JSON_VALUEJSON_QUERY를 사용합니다. JSON 속성을 자주 쿼리하는 경우 해당 속성을 추출하는 계산 열에 인덱스를 만들 수 있습니다.

다음 예제에서는 JSON 열이 있는 테이블을 만들고, 문서를 삽입하고, 특정 속성을 쿼리하고, 값을 업데이트하고, 자주 액세스하는 필드에 인덱스를 만듭니다.

-- Create table with native JSON type (SQL Server 2025+)
CREATE TABLE ConfigurationData (
    ConfigID INT PRIMARY KEY,
    ConfigSettings JSON NOT NULL
);

-- Insert JSON documents
INSERT INTO ConfigurationData (ConfigID, ConfigSettings) 
VALUES (1, '{"theme":"dark","language":"en","notifications":true}');

INSERT INTO ConfigurationData (ConfigID, ConfigSettings) 
VALUES (2, '{"theme":"light","language":"fr","notifications":false}');

-- Query JSON properties
SELECT ConfigID,
       JSON_VALUE(ConfigSettings, '$.theme') AS Theme,
       JSON_VALUE(ConfigSettings, '$.language') AS Language,
       JSON_QUERY(ConfigSettings, '$') AS FullConfig
FROM ConfigurationData;

-- Update a single property using the modify method (SQL Server 2025+ preview)
UPDATE ConfigurationData
SET ConfigSettings.modify('$.theme', 'light')
WHERE ConfigID = 1;

-- Alternative: JSON_MODIFY works with both JSON and NVARCHAR(MAX) columns
UPDATE ConfigurationData
SET ConfigSettings = JSON_MODIFY(CAST(ConfigSettings AS NVARCHAR(MAX)), '$.notifications', CAST(0 AS BIT))
WHERE ConfigID = 1;

-- Create index on frequently queried JSON property
ALTER TABLE ConfigurationData
ADD ThemeValue AS JSON_VALUE(ConfigSettings, '$.theme');

CREATE INDEX IX_Theme ON ConfigurationData(ThemeValue);

이 예제에서는 사용자 구성 설정을 저장하는 열이 있는 테이블을 JSON 만듭니다. INSERT 구문은 JSON 문서를 문자열 리터럴로 추가합니다. 특정 값을 JSON_VALUE 읽으려면 테마 및 언어와 같은 스칼라 값을 추출하고 JSON_QUERY 전체 JSON 개체를 반환합니다. .modify() 메서드(현재 미리 보기 상태)는 전체 문서를 다시 작성하지 않고 단일 속성을 업데이트합니다. 이 예제에서는 형식을 json 인덱스 키 열로 사용할 수 없으므로 테마 값을 추출하는 계산 열을 만든 다음 계산 열을 인덱싱합니다.

관계형 및 JSON 구조 결합

JSON 열은 레코드에 따라 달라지는 데이터에 가장 적합합니다. 모든 행에 일관된 데이터 형식의 동일한 필드가 있는 경우 일반 열이 더 적합합니다. 네이티브 데이터 형식 유효성 검사, JSON 경로 구문이 없는 간단한 쿼리 및 열에 대한 직접 인덱싱을 가져옵니다. 유연성이 필요한 데이터 부분에 JSON을 사용하고 예측 가능한 부분을 형식화된 열에 유지합니다.

관계형 구조와 변수 메타데이터가 필요한 제품의 JSON 유연성을 결합할 수 있습니다. 예제는 다음과 같습니다.

-- Product with flexible metadata (SQL Server 2025+)
CREATE TABLE ProductMetadata (
    ProductID INT PRIMARY KEY,
    AdditionalAttributes JSON NOT NULL
        CHECK (JSON_PATH_EXISTS(AdditionalAttributes, '$.weight') = 1),
    FOREIGN KEY (ProductID) REFERENCES Product(ProductID)
);

-- Store flexible product attributes
INSERT INTO ProductMetadata (ProductID, AdditionalAttributes) 
VALUES (1, '{"dimensions":{"length":10,"width":5,"height":8},"weight":2.5,"color":"blue"}');

-- Query nested JSON properties
SELECT ProductID,
       JSON_VALUE(AdditionalAttributes, '$.weight') AS Weight,
       JSON_VALUE(AdditionalAttributes, '$.dimensions.length') AS Length
FROM ProductMetadata;

JSON 디자인 원칙 고려

JSON 열을 구현할 때 다음 원칙을 적용합니다.

  • 반구조화된 데이터에 JSON 사용 - 일관된 스키마가 있는 데이터가 아니라 레코드에 따라 달라지는 유연한 데이터 구조를 저장합니다.
  • 자주 쿼리되는 경로 인덱스 - 자주 쿼리하는 JSON 속성에 대한 인덱스를 사용하여 계산 열을 만듭니다.
  • 필수 속성 유효성 검사 - 제약 조건을 사용하여 CHECK 필수 필드가 있는지 확인합니다 JSON_PATH_EXISTS .
  • 구조와 유연성 균형 조정 - 예측 가능한 데이터를 일반 열에 유지하고 변수 부분에만 JSON을 사용합니다.

JSON 열은 SQL 쿼리 기능을 유지하면서 변수 데이터에 대한 스키마 유연성을 제공하지만 구조화된 데이터에 대한 관계형 디자인을 대체하는 대신 보완해야 합니다.