SQL Server 2008

새로운 데이터 형식

Kelly Wilson

 

한 눈에 보기:

  • 새 날짜 및 시간 데이터 형식
  • 계층 구조의 위치 표현
  • 공간 데이터를 사용하는 두 가지 모델

오늘날의 전 세계 경제 환경에서 비즈니스를 수행하는 기업이 새로운 형식의 데이터와 응용 프로그램을 사용하고 복잡한 계산을 수행해야 할 필요성은 점차 증가하고 있습니다. SQL Server 2008에서 기본으로 제공하는 7가지 새로운 데이터 형식에 대해 알아보십시오.

새로운 데이터 형식을 사용하면 복잡한 데이터를 간편하게 사용하고 관리할 수 있습니다.

날짜 및 시간

이전의 datetime 데이터 형식에는 SQL Server® 사용자가 날짜와 시간 정보를 개별적으로 처리할 수 있는 기능이 없습니다. 이제 date, time, datetime2 및 datetimeoffset이라는 4가지 새로운 데이터 형식이 제공되므로 상황이 바뀌었습니다. 날짜 및 시간 데이터 작업이 훨씬 간단해지고 날짜 범위, 초 소수 부분 자릿수 및 표준 시간대 지원이 향상되었습니다. 새 데이터베이스 응용 프로그램에서는 기존 datetime 대신 이러한 새 데이터 형식을 사용해야 합니다. 새 데이터 형식에 대해 보다 자세히 살펴보겠습니다.

date 데이터 형식은 시간 구성 요소 없이 날짜를 저장합니다. 이 데이터 형식의 범위는 1000년 1월 1일부터 9999년 12월 31일까지입니다(0001-01-01에서 9999-12-31까지). 각 date 변수는 저장소로 3바이트를 사용하며 전체 자릿수는 10자리입니다. date 형식의 정확도는 1일로 제한됩니다.

그림 1에서는 T-SQL 스크립트에서 Date 변수를 만들고 초기화하는 방법을 보여 줍니다. @myDate1 변수는 'MM/DD/YYYY' 형식의 문자열로 초기화됩니다. @myDate2 변수는 초기화되지 않고 NULL 값을 가지게 됩니다. @myDate3 변수는 로컬 컴퓨터 시스템의 날짜로 초기화됩니다. 이 예에서 @myDate2 값을 변경하는 것처럼, 언제든지 SELECT 또는 SET 문을 사용하여 변수 값을 변경할 수 있습니다. 테이블에 date 열을 만들 수도 있습니다. 그림 2에서는 세 개의 date 열이 있는 테이블을 만드는 방법을 보여 줍니다.

Figure 2 세 개의 date 열이 있는 테이블 만들기

USE TempDB
GO

CREATE TABLE myTable
(
    myDate1 date,myDate2 date,myDate3 date
)
GO

INSERT INTO myTable
VALUES('01/22/2005',
       '2007-05-08 12:35:29.1234567 +12:15',
       GetDate())

SELECT * FROM myTable

--결과
--myDate1    myDate2    myDate3
------------ ---------- ----------
--2005-01-22 2007-05-08 2007-11-20

Figure 1 T-SQL 스크립트에서 date 변수 만들기 및 초기화

DECLARE @myDate1 date = '01/22/2005'
DECLARE @myDate2 date
DECLARE @myDate3 date = GetDate()

SELECT @myDate2 = '2007-05-08 12:35:29.1234567 +12:15'

SELECT @myDate1 AS '@myDate1',
       @myDate2 AS '@myDate2',
       @myDate3 AS '@myDate3'

--결과
--@myDate1   @myDate2   @myDate3
------------ ---------- ----------
--2005-01-22 2007-05-08 2007-11-20

time 데이터 형식은 날짜 구성 요소 없이 시간을 저장합니다. 이 데이터 형식은 24시간 형식에 기반을 두므로 지원되는 범위는 00:00:00.0000000부터 23:59:59.9999999까지입니다(시, 분, 초 및 초 소수). 초 소수 부분 자릿수는 데이터 형식을 만들 때 지정할 수 있습니다. 기본 전체 자릿수는 7자리이며 정확도는 100ns입니다. 전체 자릿수는 필요한 저장소 공간 크기에 영향을 미칩니다. 필요한 저장소 공간은 2자리까지는 3바이트, 3 또는 4자리에는 4바이트, 5에서 7자리까지는 5바이트입니다.

그림 3의 T-SQL 스크립트에서는 문자열 초기화 값의 암시적 변환이 변수 자릿수에 어떤 영향을 미치는지 보여 줍니다. T-SQL 코드에서는 먼저 time 변수 8개를 만들고 동일한 값으로 초기화합니다. 각 변수의 소수 부분 자릿수는 이름과 동일합니다. 예를 들어 @myTime3의 소수 부분 자릿수는 3자리입니다. 결과는 각 time 데이터 형식의 전체 자릿수가 해당 데이터 형식이 선언된 소수 부분 자릿수와 동일하다는 것을 보여 줍니다. 범위를 벗어나는 자릿수는 잘립니다.

Figure 3 time 데이터 형식의 변수 자릿수 표시

DECLARE @myTime  time = '01:01:01.1234567 +01:01'
DECLARE @myTime1 time(1) = '01:01:01.1234567 +01:01'
DECLARE @myTime2 time(2) = '01:01:01.1234567 +01:01'
DECLARE @myTime3 time(3) = '01:01:01.1234567 +01:01'
DECLARE @myTime4 time(4) = '01:01:01.1234567 +01:01'
DECLARE @myTime5 time(5) = '01:01:01.1234567 +01:01'
DECLARE @myTime6 time(6) = '01:01:01.1234567 +01:01'
DECLARE @myTime7 time(7) = '01:01:01.1234567 +01:01'

SELECT @myTime  AS '@myTime',
       @myTime1 AS '@myTime1',
       @myTime2 AS '@myTime2',
       @myTime3 AS '@myTime3',
       @myTime4 AS '@myTime4',
       @myTime5 AS '@myTime5',
       @myTime6 AS '@myTime6',
       @myTime7 AS '@myTime7'

--결과
--@myTime          @myTime1   @myTime2    @myTime3     @myTime4      
------------------ ---------- ----------- ------------ -------------
--01:01:01.1234567 01:01:01.1 01:01:01.12 01:01:01.123 01:01:01.1235
--
--@myTime5       @myTime6        @myTime7
---------------- --------------- ----------------
--01:01:01.12346 01:01:01.123457 01:01:01.1234567

DROP TABLE myTable

time 데이터 형식을 테이블의 열로 만들 수 있습니다. 그림 4의 DROP TABLE myTable T-SQL 스크립트는 myTable1이라는 테이블을 만들고 time 열 세 개를 추가합니다. 그런 다음 테이블에 레코드를 삽입하고 SELECT 문을 사용하여 테이블의 내용을 표시합니다.

Figure 4 myTable1 만들기

USE TempDB
GO

CREATE TABLE myTable1
(
    myTime1 time(1),
    myTime2 time(2),
    myTime3 time(3)
)
GO

INSERT INTO myTable1
VALUES('01:30:01.1234567',
       '02:34:01.1234567',
       '03:01:59.1234567')

SELECT * from myTable1

--결과
--myTime1    myTime2     myTime3
------------ ----------- ------------
--01:30:01.1000000 02:34:15.1200000 03:01:59.1230000

DROP TABLE myTable1

Datetimeoffset 및 Datetime2

datetimeoffset 데이터 형식은 표준 시간대 인식 기능을 제공합니다. time 데이터 형식은 표준 시간대 정보를 포함하지 않으므로 현지 시간으로만 작동합니다. 하지만 전 세계를 대상으로 경제 활동을 하는 경우에는 한 지역의 시간이 다른 지역의 시간과 어떤 관계에 있는지 알아야 하는 경우가 많습니다. 표준 시간대 오프셋은 +/- hh:mm으로 표시됩니다.

다음 코드에서는 datetimeoffset 변수를 만들고 태평양 표준시인 오전 8:52 값으로 변수를 초기화합니다.

DECLARE @date DATETIMEOFFSET = '2007-11-26T08:52:00.1234567-08:00'
PRINT @date
--결과
--2007-11-26 08:52:00.1234567 -08:00

datetimeoffset 변수(스크립트의 @date)를 초기화하는 문자열은 중요한 요소가 먼저 배치되는 특별한 형식을 가지고 있습니다. 단일 대문자 T는 날짜와 시간 요소를 분리합니다. 빼기(-) 기호는 시간 요소와 표준 시간대를 분리합니다. 빼기(-) 기호와 시간 또는 표준 시간대 요소 사이에는 공백이 없습니다. 이 형식은 datetimeoffset 데이터 형식에서 지원되는 두 가지 ISO 8601 형식 중 하나입니다. ISO 8601은 날짜 및 시간 값 표현에 대한 국제 표준입니다.

시간 구성 요소의 전체 자릿수는 time 데이터 형식과 마찬가지로 지정되며, 전체 자릿수가 지정되지 않은 경우 기본값은 7자리로 동일합니다. 지원되는 범위도 같습니다.

datetime2 데이터 형식은 원래 datetime 형식의 확장입니다. datetime2 데이터 형식은 더 넓은 날짜 범위와 더 많은 초 소수 부분 자릿수를 지원하며, 전체 자릿수는 사용자 지정할 수 있습니다. 원래 datetime의 날짜 범위가 1753년 1월 1일부터 9999년 12월 31일까지인 것에 비해 datetime2 형식의 날짜 범위는 0001년 1월 1일부터 9999년 12월 31일까지입니다. time 형식과 마찬가지로 7자리의 초 소수 부분 자릿수가 제공됩니다. 원래 datetime 형식은 3자리 전체 자릿수와 00:00:00부터 23:59:59.999까지의 시간 범위를 제공했습니다. 다음은 datetime2 변수를 만들고 로컬 서버 날짜 및 시간으로 초기화하는 방법을 보여 줍니다.

DECLARE @datetime2 DATETIME2 = GetDate();
PRINT @datetime2

--결과
--2007-11-26 09:39:04.1370000

다음으로 새 hierarchyid 데이터 형식을 살펴보겠습니다. 이 데이터 형식은 특정 날짜나 시간 데이터가 아니라 테이블의 데이터 요소 간 관계에 사용합니다.

Hierarchyid 데이터 형식

hierarchyid 데이터 형식을 사용하면 테이블의 데이터 요소 간에서 계층적인 위치를 나타내는 관계를 구성할 수 있습니다. 이 데이터 형식을 탐색하려면 그림 5의 스크립트를 사용하여 MyCompany 데이터베이스를 만들고 직원 데이터로 데이터베이스를 채웁니다.

Figure 5 MyCompany 데이터베이스 만들기 및 채우기

USE MASTER
GO

CREATE DATABASE MyCompany
GO
USE MyCompany
GO

--MyCompany의 직원 데이터를 저장할
--직원 테이블을 만듭니다.
    
CREATE TABLE employee
(
    EmployeeID int NOT NULL,
    EmpName    varchar(20) NOT NULL,
    Title      varchar(20) NULL,
    Salary     decimal(18, 2) NOT NULL,
    hireDate   datetimeoffset(0) NOT NULL,
)
GO

--이 문은 MyCompany 직원의 데이터를 삽입합니다.

INSERT INTO employee
VALUES(6,   'David',  'CEO', 35900.00, '2000-05-23T08:30:00-08:00')

INSERT INTO employee
VALUES(46,  'Sariya', 'Specialist', 14000.00, '2002-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(271, 'John',   'Specialist', 14000.00, '2002-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(119, 'Jill',   'Specialist', 14000.00, '2007-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(269, 'Wanida', 'Assistant', 8000.00, '2003-05-23T09:00:00-08:00')

INSERT INTO employee
VALUES(272, 'Mary',   'Assistant', 8000.00, '2004-05-23T09:00:00-08:00')
GO
--결과
--EmployeeID  EmpName Title      Salary   hireDate
------------- ------- ---------- -------- --------------------------
--6           David   CEO        35900.00 2000-05-23 08:30:00 -08:00
--46          Sariya  Specialist 14000.00 2002-05-23 09:00:00 -08:00
--271         John    Specialist 14000.00 2002-05-23 09:00:00 -08:00
--119         Jill    Specialist 14000.00 2007-05-23 09:00:00 -08:00
--269         Wanida  Assistant  8000.00  2003-05-23 09:00:00 -08:00
--272         Mary    Assistant  8000.00  2004-05-23 09:00:00 -08:00

그림 6에서는 그 결과로 만들어진 단일 직원 테이블로 구성된 간단한 데이터베이스를 보여 줍니다. MyCompany 데이터베이스에서 이 직원 테이블에는 적용된 구조가 없습니다. 관계형 데이터베이스의 경우 응용 프로그램의 쿼리와 처리 코드를 통해 구조가 동적으로 적용되므로, 이것은 자연스러운 것입니다.

그림 6 MyCompany 직원 테이블

그림 6** MyCompany 직원 테이블 **

하지만 비즈니스 데이터는 일반적으로 기본 구조를 가지고 있습니다. 예를 들어 모든 비즈니스에는 보고 구조가 있습니다. 그림 7에서는 MyCompany의 보고 구조를 보여 줍니다. MyCompany의 모든 직원은 CEO인 David에게 보고합니다. Jill의 경우처럼 일부 직원은 직접 보고하지만 Mary와 같은 다른 직원은 중간 단계를 거쳐 보고합니다. 프로그래밍 용어로 MyCompany의 보고 구조는 나무와 같은 형태로 인해 트리 구조라고 합니다. 맨 위에 있는 David는 누구에게도 보고하지 않습니다. 즉, 부모 또는 상위 노드가 됩니다. David에게 보고하는 직원은 아래에 있습니다. 이러한 노드는 자식 또는 하위 노드라고 표현합니다. David는 자신에게 직접 보고하는 직원을 나타내는 하위 노드를 필요한 만큼 가질 수 있습니다.

그림 7 MyCompany의 조직 구조

그림 7** MyCompany의 조직 구조 **(더 크게 보려면 이미지를 클릭하십시오.)

그림 8의 스크립트는 hierarchyid 데이터 형식을 사용하여 MyCompany의 보고 구조와 일치하는 관계를 구성하여 MyCompany 데이터베이스를 다시 작성합니다. 먼저 ALTER TABLE 문을 사용하여 hierarchyid 형식의 열을 추가합니다. 그런 다음 hierarchyid의 GetRoot 메서드를 사용하여 David의 노드를 삽입합니다. 계속해서 GetDescendant 메서드를 사용하여 David에게 직접 보고하는 직원들을 트리에 추가합니다.

Figure 8 hierarchyid를 사용하여 데이터베이스 다시 작성

DELETE employee
GO
ALTER TABLE employee ADD OrgNode hierarchyid NOT NULL
GO

DECLARE @child hierarchyid,
@Manager hierarchyid = hierarchyid::GetRoot()

--첫 번째 단계로 트리의 맨 위에
--노드를 추가합니다. David는 CEO이므로 그의 노드는
--루트 노드가 됩니다.

INSERT INTO employee
VALUES(6,   'David',  'CEO', 35900.00,
       '2000-05-23T08:30:00-08:00', @Manager)

--다음으로 David에게 직접 보고하는 직원의
--레코드를 삽입합니다.

SELECT @child = @Manager.GetDescendant(NULL, NULL)

INSERT INTO employee
VALUES(46,  'Sariya', 'Specialist', 14000.00,
       '2002-05-23T09:00:00-08:00', @child)

SELECT @child = @Manager.GetDescendant(@child, NULL)
INSERT INTO employee
VALUES(271, ‚John',   ‚Specialist', 14000.00,
       '2002-05-23T09:00:00-08:00', @child)

SELECT @child = @Manager.GetDescendant(@child, NULL)
INSERT INTO employee
VALUES(119, ‚Jill',   ‚Specialist', 14000.00,
       ‚2007-05-23T09:00:00-08:00', @child)

--이제 Sariya에게 보고하는 직원을 삽입할 수
--있습니다.
SELECT @manager = OrgNode.GetDescendant(NULL, NULL)
FROM employee WHERE EmployeeID = 46

INSERT INTO employee
VALUES(269, ‚Wanida', ‚Assistant', 8000.00,
       ‚2003-05-23T09:00:00-08:00', @manager)

--그런 다음 John에게 보고하는 직원을 삽입합니다.
SELECT @manager = OrgNode.GetDescendant(NULL, NULL)
FROM employee WHERE EmployeeID = 271

INSERT INTO employee
VALUES(272, ‚Mary',   ‚Assistant', 8000.00,
       ‚2004-05-23T09:00:00-08:00', @manager)
GO

데이터베이스 레코드를 추가하고 계층 구조를 구성한 후에는 다음과 같은 쿼리를 사용하여 직원 테이블의 내용을 표시할 수 있습니다.

SELECT EmpName, Title, Salary, OrgNode.ToString() AS OrgNode
FROM employee ORDER BY OrgNode
GO
--결과
--EmpName  Title      Salary    OrgNode
---------- ---------- --------- -------
--David    CEO        35900.00  /
--Sariya   Specialist 14000.00  /1/
--Wanida   Assistant  8000.00   /1/1/
--John     Specialist 14000.00  /2/
--Mary     Assistant  8000.00   /2/1/
--Jill     Specialist 14000.00  /3/

OrgNode가 hierarchyid 열입니다. 결과에서 각 슬래시(/) 문자는 계층 구조 트리의 노드를 나타냅니다. David는 루트이므로 슬래시 하나로 표시되고, David에게 직접 보고하는 Sariya, John 및 Jill은 슬래시 표시가 두 개이므로 계층 구조에서 두 번째 노드임을 알 수 있습니다. 숫자 1, 2 또는 3은 해당 자식 노드의 순서를 나타냅니다. 이 시스템은 매우 유연하여 자식 노드를 필요에 따라 제거하거나 삽입하거나 추가할 수 있습니다. 예를 들어 John과 Jill 사이에 직원을 추가하면 해당 직원은 결과 집합에 /2.1/로 표시됩니다.

"Sariya에게 보고하는 직원은 누구입니까?"라는 질문에 답하려면 다음 T-SQL 코드와 같은 쿼리를 만들면 됩니다.

DECLARE @Sariya hierarchyid

SELECT @Sariya = OrgNode
FROM employee WHERE EmployeeID = 46

SELECT EmpName, Title, Salary, OrgNode.ToString() AS 'OrgNode'
FROM employee
WHERE OrgNode.GetAncestor(1) = @Sariya
GO
--결과
--EmpName Title     Salary  OrgNode
--------- --------- ------- -------
--Wanida  Assistant 8000.00 /1/1/

이 쿼리에서는 hierarchyid의 GetAncestor 메서드를 사용합니다. 이 메서드는 현재 hierarchyid 노드의 부모를 반환합니다. 이전 코드에서 @Sariya 변수는 Sariya에 대한 계층 구조 노드로 설정됩니다. 이것은 Sariya가 그녀에게 보고하는 모든 직원들의 직계 상위 노드이기 때문입니다. 따라서 Sariya에게 직접 보고하는 직원들을 반환하는 쿼리를 작성하려면 트리에서 Sariya의 노드를 검색한 후 상위 노드가 Sariya의 노드인 모든 직원을 선택합니다.

트리에서 노드를 나타내는 데 필요한 비트 수는 노드의 평균 자식 수(일반적으로 노드의 팬아웃이라고 함)에 따라 달라지므로 hierarchyid 열은 대개 매우 간결합니다. 예를 들어 100,000명의 직원이 있는 조직 계층 구조의 새 노드는 6단계의 평균 팬아웃(fanout)을 가지며 저장소에서 약 5바이트를 사용합니다.

hierarchyid 데이터 형식은 계층적 데이터를 쉽게 처리할 수 있는 몇 가지 메서드를 제공합니다. 이러한 메서드에 대한 요약이 그림 9에 나와 있습니다. 모든 메서드에 대한 자세한 내용은 SQL Server 온라인 설명서(msdn2.microsoft.com/ms130214)에서 확인할 수 있습니다.

Figure 9 hierarchyid 데이터 형식으로 제공되는 메서드

메서드 설명
GetAncestor 해당 hierarchyid 노드의 n번째 상위 노드를 나타내는 hierarchyid를 반환합니다.
GetDescendant 해당 hierarchyid 노드의 자식 노드를 반환합니다.
GetLevel 전체 계층 구조에서 해당 hierarchyid 노드의 깊이를 나타내는 정수를 반환합니다.
GetRoot 해당 계층 구조 트리에서 루트 hierarchyid 노드를 반환합니다. 정적입니다.
IsDescendant 전달된 자식 노드가 해당 hierarchyid 노드의 하위 노드이면 true를 반환합니다.
Parse 계층 구조를 나타내는 문자열을 hierarchyid 값으로 변환합니다. 정적입니다.
Reparent 계층 구조 노드를 계층 구조 내의 새 위치로 이동합니다.
ToString 해당 hierarchyid의 논리적 표현을 포함하는 문자열을 반환합니다.

공간 데이터 형식

공간 데이터는 주로 지구상의 지리적 위치와 형태를 식별하는 데이터입니다. 예를 들어 상징적인 건축물, 도로, 회사의 위치 등이 공간 데이터가 될 수 있습니다. SQL Server 2008은 이러한 형식의 데이터를 처리할 수 있는 geography 및 geometry 데이터 형식을 제공합니다.

geography 데이터 형식은 둥근 지구 정보를 사용하여 동작합니다. 둥근 지구 모델은 계산 시 지구의 굽은 표면을 고려합니다. 위치 정보는 경도와 위도로 지정됩니다. 이 모델은 지구 표면을 참조하는 대양 횡단 항해, 군사 계획 및 근거리 응용 분야와 같은 응용 프로그램에 적합합니다. 데이터를 위도와 경도로 저장하는 경우 사용하는 모델이 이 모델입니다.

geometry 데이터 형식은 평평한 지구 또는 평면 모델을 사용하여 동작합니다. 이 모델에서는 지구를 특정 지점에서 시작하는 평면 투영도로 취급합니다. 평평한 지구 모델은 지구의 곡률을 고려하지 않으므로 짧은 거리를 기술하는 데 주로 사용됩니다. 예를 들어 건물 내부를 측량하는 데이터베이스 응용 프로그램에 이 모델이 사용됩니다.

geography 및 geometry 형식은 WKT(Well-Known Text) 또는 WKB(Well-Known Binary) 형식으로 지정된 벡터 개체로 구성됩니다. 이러한 개체는 공간 데이터를 위한 전송 형식으로, OGC(Open Geospatial Consortium)의 Simple Features for SQL Specification에 설명되어 있습니다. 그림 10에서는 SQL Server 2008이 지원하는 7가지 벡터 개체 형식을 보여 줍니다.

Figure 10 SQL Server 2008에서 지원되는 벡터 개체

개체 설명
Point 위치
MultiPoint 일련의 점
LineString 선으로 연결된 0개 이상의 일련의 점
MultiLineString 일련의 linestring
Polygon 일련의 닫혀진 linestring으로 기술되는 연속적인 영역
MultiPolygon 일련의 다각형
GeometryCollection geometry 형식의 컬렉션

하나 이상의 벡터 개체가 있는 geography 형식을 구성하려면 그림 11에서 볼 수 있는 것처럼 먼저 T-SQL 스크립트에서 geography 형식을 선언합니다. 그런 다음 그림 12에 나열된 메서드 중 하나를 호출하여 벡터 개체에 대한 문자열과 SRID(Spatial Reference ID)를 전달합니다. SRID는 European Petroleum Survey Group에서 정의한 공간 참조 식별 시스템으로, 지도 제작, 측량 및 측지 데이터 저장용으로 개발된 표준의 일부입니다. 각 SRID는 지리 계산에 사용할 특정 유형의 타원면을 식별합니다. 이것은 지구가 완전한 구가 아니기 때문에 필요합니다. SQL Server 2008은 SRID가 동일한 경우에만 계산을 수행할 수 있습니다.

Figure 12 geography 및 geometry에 대한 개체 구성

메서드 설명
STGeomFromText 입력 텍스트에서 geography 인스턴스 형식을 구성합니다.
STPointFromText 입력 텍스트에서 geography Point 인스턴스를 구성합니다.
STMPointFromText 입력 텍스트에서 geography MultiPoint 인스턴스를 구성합니다.
STLineFromText 입력 텍스트에서 geography LineString 인스턴스를 구성합니다.
STMLineFromText 입력 텍스트에서 geography MultiLineString 인스턴스를 구성합니다.
STPolyFromText 입력 텍스트에서 geography Polygon 인스턴스를 구성합니다.
STMPolyFromText 입력 텍스트에서 geography MultiPolygon 인스턴스를 구성합니다.
STGeomCollFromText 입력 텍스트에서 geography GeometryCollection 인스턴스를 구성합니다.

Figure 11 점, 선 및 다각형 geometry 만들기

DECLARE @geo1 geometry
SELECT @geo1 = geometry::STGeomFromText('POINT (3 4)', 0)
PRINT @geo1.ToString()

DECLARE @geo2 geometry
SELECT @geo2 = geometry::Parse('POINT(3 4 7 2.5)')
PRINT @geo2.STX;
PRINT @geo2.STY;
PRINT @geo2.Z;
PRINT @geo2.M;

DECLARE @geo3 geography;
SELECT @geo3 = geography::STGeomFromText(
    'LINESTRING(47.656 -122.360, 47.656 -122.343)', 4326);
SELECT @geo3.ToString();

--결과
--POINT (3 4)
--3
--4
--7
--2.5

DECLARE @gx geometry; 
SET @gx = geometry::STPolyFromText(
    'POLYGON ((5 5, 10 5, 10 10, 5 5))', 0);
PRINT @gx.ToString();
--결과
--POLYGON ((5 5, 10 5, 10 10, 5 5))

Geography와 Geometry의 차이점

geography와 geometry 데이터 형식은 서로 다른 형식의 데이터를 처리하도록 설계되었으므로 몇 가지 주요한 차이점을 알고 있어야 합니다. geometry 데이터 형식에서는 거리와 면적이 인스턴스의 좌표와 동일한 측정 단위로 지정됩니다. 예를 들어 점 (0,0) 및 (6,8) 사이의 거리는 항상 10단위입니다. 하지만 위도와 경도로 표현되는 타원 좌표를 사용하는 geography 형식에서는 이와 다릅니다.

GEOMETRY 데이터 형식은 좌표를 위도와 경도의 쌍으로 표현할 경우 모순된 결과를 반환합니다. 다음 T-SQL 코드는 점 (90 0)과 (90 180) 사이의 거리를 계산합니다. 이 두 점 모두 북극을 나타내므로 두 점 사이의 거리는 0이어야 합니다. 하지만 GEOMETRY 형식에서는 거리가 180으로 계산됩니다.

DECLARE @g1 GEOMETRY, @g2 GEOMETRY, @g3 GEOGRAPHY, @g4 GEOGRAPHY
SELECT @g1 = GEOMETRY::STGeomFromText('POINT (90 0)', 0)
SELECT @g2 = GEOMETRY::STGeomFromText('POINT (90 180)', 0)

SELECT @g3 = GEOGRAPHY::STGeomFromText('POINT (90 0)', 4326)
SELECT @g4 = GEOGRAPHY::STGeomFromText('POINT (90 180)', 4326)
SELECT @g2.STDistance(@g1) AS 'GEOMETRY',
       @g4.STDistance(@g3) AS 'GEOGRAPHY';

--결과
--GEOMETRY               GEOGRAPHY
------------------------ ----------------------
--180                    0

공간 데이터의 방향 역시 두 데이터 형식에서 서로 다릅니다. geometry 데이터 형식에 사용되는 평면 시스템에서는 다각형 방향이 중요한 요소가 아닙니다. 예를 들어 좌표가 (0, 0), (10, 0), (0, 20), (0, 0)인 다각형은 좌표가 (0, 0), (0, 20), (10, 0), (0, 0)인 다각형과 동일한 것으로 간주됩니다. 하지만 geography 데이터 형식에 사용되는 데이터 모델에서는 지정된 방향이 없으면 다각형이 분명하지 않게 됩니다. 예를 들어 적도를 감싼 둥근 고리를 생각해보십시오. 이 고리로 기술되는 다각형은 남반구를 나타낼까요, 북반구를 나타낼까요? 요점은 geography 데이터를 사용할 때에는 방향과 위치를 정확하게 기술해야 한다는 것입니다.

SQL Server 2008에는 geography 데이터 형식에 대한 몇 가지 제한이 있습니다. 예를 들어 각 geography 인스턴스는 단일 반구 내에 들어가야 합니다. 반구보다 큰 공간 개체는 허용되지 않으며 ArgumentException이 발생하게 됩니다. 두 가지 입력이 필요한 geography 데이터 형식은 메서드의 결과가 단일 반구 내에 들어가지 않으면 NULL을 반환합니다.

SQL Server는 geography 및 geometry 인스턴스에 대한 작업을 수행할 수 있는 다양한 메서드를 제공합니다. 그림 13에서는 SQL Server 2008이 제공하는 메서드를 사용하여 공간 데이터를 처리하는 몇 가지 예를 보여 줍니다. 지면의 제약 때문에 이 항목에 대해 더 자세히 설명할 수 없지만 SQL Server 온라인 설명서에서 자세한 내용을 확인할 수 있습니다.

Figure 13 공간 데이터 사용

DECLARE @gm geometry;
DECLARE @gg geography;
DECLARE @h geography;

SET @gm = geometry::STGeomFromText('POLYGON((0 0, 13 0, 3 3, 0 13, 0 0),(2 2, 2 1, 1 1, 1 2, 2 2))', 0);
SELECT @gm.STArea();

--결과
--38

SET @gg = geography::STGeomFromText('LINESTRING(0 0, 5 5)', 4326);
--LINESTRING에서 약간 벗어난 점까지의 거리를 계산합니다.
SET @h = geography::STGeomFromText('POINT(4 4)', 4326);
SELECT @gg.STDistance(@h);

--결과
-- 430.182777043046

--LINESTRING의 점까지의 거리를 계산합니다.
SET @h = geography::STGeomFromText('POINT(5 5)', 4326);
SELECT @gg.STDistance(@h);

--결과
-- 0

DECLARE @temp table ([name] varchar(10), [geom] geography);

INSERT INTO @temp values ('Point', geography::STGeomFromText('POINT(
5 10)', 4326));
INSERT INTO @temp values ('LineString', geography::STGeomFromText(
'LINESTRING(13 5, 50 25)', 4326));
--LINESTRING의 점까지의 거리를 계산합니다.
--테이블 변수에 저장된 geography 개체에 대한 차원 수를 표시합니다.
INSERT INTO @temp values ('Polygon', geography::STGeomFromText(
'POLYGON((47.653 -122.358, 47.649 -122.348, 47.658 -122.348, 47.658 -122.358, 47.653 -122.358))', 4326));

SELECT [name], [geom].STDimension() as [dim]
FROM @temp;

--결과
--name       dim
------------ -----------
--Point      0
--LineString 1
--Polygon    2

여기서 다룬 SQL Server 2008의 새로운 7가지 데이터 형식에 대한 정보가 도움이 되기를 바랍니다.

Kelly Wilson은 소프트웨어 엔지니어링 분야에서 20년 이상 일했으며 SQL Server, 3D 그래픽, 게임 및 색채 연구 분야에서도 경력이 있습니다. Kelly는 현재 Microsoft의 SQL Server 그룹에서 프로그래밍 저술가로 근무하고 있습니다.

© 2008 Microsoft Corporation 및 CMP Media, LLC. All rights reserved. 이 문서의 전부 또는 일부를 무단으로 복제하는 행위는 금지됩니다..