안녕하세요. SQLER의 코난 김대우입니다. 
이번 강좌에서는, 4-2. 데이터베이스 생성을 진행 하겠습니다.


SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록

 

이번에 진행할 강좌는 데이터베이스 생성입니다.

 

 

 

TL;DR

SQL Server 데이터베이스는 기본 파일 확장자 MDF, LDF로 구성됩니다. 파일 그룹을 이용해 데이터 저장 장소를 세분화시켜 구성 가능하고, 자동증가 등 여러 옵션을 설정할 수 있습니다.

 

이전 강좌에서 SSMS로 GUI로 이미 만든 거 아닌가요?


SSMS와 SQL 쿼리를 이용해 아주 간단한 데이터베이스를 생성했습니다. 하지만 데이터베이스 생성은 생각보다 더 복잡하고, 고려할 사항이 많습니다.

 

 

데이터베이스 파일

SQL Server 데이터베이스는 기본적으로 SQL서버가 설치된 경로의 Data 폴더에 생성됩니다. 


기본 설치 경로는 C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA 입니다.

 

52-mdf와ldf파일.png

 

지난 강좌에서 기본 설정으로 만들었던 sqler_test 데이터베이스는 이렇게 sqler_test.mdf와 sqler_test_log.ldf 파일로 구성되어 있습니다. 파일 확장자를 주의해서 확인해 주세요. mdf 확장자와 ldf 확장자가 보입니다.

 

SQL Server 데이터베이스 파일 확장자

SQL Server 데이터베이스는 3개의 파일 확장자를 사용합니다.

확장자명
설명
MDF 주 데이터 파일
NDF 보조 데이터 파일
LDF 로그 파일

 

MDF
MDF 주 데이터 파일(Primary data file)은 모든 데이터베이스가 반드시 가지는 파일입니다.


NDF
NDF 파일은 보조 데이터 파일(Secondary data file)로 파일그룹(File group)으로 데이터베이스를 생성할 때 사용됩니다.


LDF
LDF 파일은 로그 데이터 파일(Log data file)이며 데이터 변경이 기록되는 파일입니다. 

 

데이터베이스 파일과 파일그룹

데이터베이스의 데이터 파일 - MDF와 NDF 파일에 대해 조금 더 알아보겠습니다.

 

52-데이터베이스 파일.png


데이터베이스 파일은 반드시 주 파일 그룹(Primary file group)이 존재해야 하고, 주 파일 그룹은 반드시 MDF 파일을 하나 포함 해야 합니다. 아울러 LDF 파일도 반드시 존재해야 합니다. NDF 파일은 보조 데이터 파일이기 때문에 반드시 존재할 필요는 없습니다.

"지난 강좌에서 만들 때에는 이런 복잡한 거 없이 확인만 하니까 만들어지던데요?"


기본 설정으로 만들어졌기 때문입니다. 하지만, 실제 운영환경을 구성하게 되면 이렇게 파일 그룹을 활용해 데이터베이스를 구성하게 됩니다. 다음으로 파일 그룹에 대한 설명입니다.

 

파일 그룹

파일 그룹은 주 데이터 파일 그룹과 보조 데이터 파일 그룹으로 구성됩니다.

파일 그룹명
설명
주 데이터(Primary) 파일 그룹 반드시 있어야 하며 MDF파일은 
반드시 이 주데이터 파일 그룹에 있어야 한다.
보조 데이터(Secondary) 파일 그룹 주 데이터 파일 그룹을 보조하는 파일 그룹이며 추가할 수 있다. NDF 파일이 위치한다.


파일 자동증가

SQL Server에서 데이터베이스 파일의 자동 증가를 설정할 수 있습니다. 
만약 데이터베이스의 최대 크기를 최초 10M로 설정했는데 금방 데이터가 쌓여서 10M를 넘으면 어떻게 될까요? 더 이상 데이터가 추가 안되고 멈추게 됩니다. 이럴 경우를 위해 자동으로 데이터베이스 파일의 크기를 증가하는 옵션이 제공됩니다. 잠시 후에 쿼리로 설명드리겠습니다.

 

SQL 구문으로 데이터베이스 생성

그럼 가장 중요한 SQL 구문으로 데이터베이스를 생성하겠습니다. SQL 구문으로 항상 SELECT 쿼리나 이런 데이터베이스 생성도 연습하면 이후 코드만 가지고 있으면 재활용이 가능합니다. 항상 UI를 이용하는 방법보다 이렇게 SQL 쿼리 코드로 수행하는 방법을 잘 숙지해 두시면 큰 도움이 됩니다.


데이터베이스 생성 구문 패턴

CREATE DATABASE database_name
[ ON
    [ < filespec > [ ,...n ] ]
    [ , < filegroup > [ ,...n ] ]
]
[ LOG ON { < filespec > [ ,...n ] } ]
[ COLLATE collation_name ]
[ FOR LOAD | FOR ATTACH ]

< filespec > ::=

[ PRIMARY ]
( [ NAME = logical_file_name , ]
    FILENAME = 'os_file_name'
    [ , SIZE = size ]
    [ , MAXSIZE = { max_size | UNLIMITED } ]
    [ , FILEGROWTH = growth_increment ] ) [ ,...n ]

< filegroup > ::=

FILEGROUP filegroup_name < filespec > [ ,...n ]


역시나 샘플 쿼리로 진행하겠습니다. 저와 같이 AdventureWorks 데이터베이스를 생성하셨다면 C:\sql_data 폴더가 있을 겁니다. 만약에 없다면 생성하고 다음 SQL 구문을 진행하세요.

USE master;
GO

-- Sales 예제 데이터베이스 생성
CREATE DATABASE Sales ON
(NAME = Sales_dat,
    FILENAME = 'C:\sql_data\saledat.mdf',
    SIZE = 10,
    MAXSIZE = 50,
    FILEGROWTH = 5)
LOG ON
(NAME = Sales_log,
    FILENAME = 'C:\sql_data\salelog.ldf',
    SIZE = 5 MB,
    MAXSIZE = 25 MB,
    FILEGROWTH = 5 MB);
GO

 

SQL 쿼리를 살펴보겠습니다. 최소한의 Primary 파일 그룹과 MDF, LDF 파일만 사용해 구성했습니다. SIZE로 기본 10M 데이터 파일 크기를 지정했고, 5M 단위로 파일 크기를 증가시켜 최대 50M까지 증가시키는 설정으로 데이터베이스 파일을 생성합니다.
SSMS에서 데이터베이스를 “새로고침” 하시고 확인하면 이런 정보를 볼 수 있습니다.

 

52-sales데이터베이스_2.png


추가적으로 아래 SQL 쿼리를 이용해 데이터베이스 정보를 볼 수도 있습니다.

-- 데이터베이스 목록과 정보 표시
EXEC sp_databases;
GO

-- 데이터베이스 정보 리스트 - 시스템 카탈로그
SELECT * FROM sys.databases WHERE name like 'Sales';
GO

 

이번에는 파일그룹을 이용해 데이터베이스를 생성하는 예제를 수행합니다.

-- MyDB 데이터베이스 생성
CREATE DATABASE MyDB
ON PRIMARY  -- 주 파일 그룹
  ( NAME='MyDB_Primary',
    FILENAME=
       'c:\sql_data\MyDB_Prm.mdf',
    SIZE=4MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB),
FILEGROUP MyDB_FG1  -- 보조 파일 그룹 MyDB_FG1
  ( NAME = 'MyDB_FG1_Dat1',
    FILENAME =
       'c:\sql_data\MyDB_FG1_1.ndf',
    SIZE = 1MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB),
  ( NAME = 'MyDB_FG1_Dat2',
    FILENAME =
       'c:\sql_data\MyDB_FG1_2.ndf',
    SIZE = 1MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB)
LOG ON
  ( NAME='MyDB_log',  -- 로그파일 설정
    FILENAME =
       'c:\sql_data\MyDB.ldf',
    SIZE=1MB,
    MAXSIZE=10MB,
    FILEGROWTH=1MB);
GO

-- 기본 파일 그룹을 MyDB_FG1으로 변경.
ALTER DATABASE MyDB 
  MODIFY FILEGROUP MyDB_FG1 DEFAULT;
GO

USE MyDB;
GO
-- MyDB_FG1 파일 그룹에 테이블을 생성
CREATE TABLE MyTable
  ( cola int PRIMARY KEY,
    colb char(8) )
ON MyDB_FG1;
GO

-- 테이블을 생성할 때 파일 그룹을 지정하지 않으면, 기본 파일 그룹인 MyDB_FG1에 테이블을 생성
CREATE TABLE MyTable2
  ( cola int PRIMARY KEY,
    colb char(8) );
GO

 

이렇게 파일 그룹을 이용하면 원하는 위치에 데이터 파일을 위치시킬 수 있습니다. 물리적으로 다른 디스크를 이용해 테이블이나 인덱스 데이터 입출력 속도를 높일 수 있습니다.


sp_helpdb를 이용하면, 데이터베이스 파일 그룹과 파일 정보를 볼 수 있습니다.

sp_helpdb 'MyDB';

 

(옵션) 테이블이 위치한 파일그룹을 확이고 싶다면 아래 쿼리를 수행하세요.

USE MyDB;
GO

-- 참조링크: https://learn.microsoft.com/en-us/answers/questions/497385/tables-in-a-particular-sql-server-filegroup

SELECT distinct o.[name], o.[type], f.[name]
FROM sys.indexes i
  INNER JOIN sys.filegroups f
    ON i.data_space_id = f.data_space_id
  INNER JOIN sys.all_objects o
    ON i.[object_id] = o.[object_id] 
      AND o.type = 'U'; -- User Created Tables
GO

 

파일 그룹의 장점 - 백업

여러 성능적인 장점 외에 백업에서도 파일 그룹이 유용합니다. 백업을 파일 그룹 단위로 받을 수 있어서 SQL Server 실행 중에 부하를 줄이면서 백업할 수 있습니다.

 

 

MDF와 LDF만 남았을 경우 데이터베이스 연결(Database Attach) 복원

가장 많이 받는 질문이기도 합니다. 시스템을 이전하거나, SQL Server를 종료하고 잠시 데이터 파일과 로그 파일을 복사해 두었다가 다시 연결하고 싶을 경우 등입니다.
다음 SQL 구문으로 데이터베이스를 분리하고 연결할 수 있으며, 몇 가지 주의사항도 말씀드립니다.

 

데이터베이스 분리 - detach

USE master;
GO

EXEC sp_detach_db 'sqler_test', 'true';
GO

 

오류 1. 데이터베이스가 사용 중이므로 분리할 수 없습니다.
메시지 3703, 수준 16, 상태 3, 줄 1074
데이터베이스 'sqler_test'은(는) 현재 사용 중이므로 분리할 수 없습니다.


이럴 경우에는 현재 해당 데이터베이스를 사용 중인 사용자 세션을 kill 하고 detach 합니다.

use master;
GO

-- 어느 프로세스가 해당 DB를 사용 중인지 확인하고 kill
EXEC sp_who;
GO

kill SPID번호;
GO

 

운영이나 중요 개발 시스템이라면, 해당 SPID가 중요 작업 중인지 미리 체크하고 kill 하세요.

 

오류 2. 애플리케이션이나 자동화 툴이 계속 해당 DB에 접근, 사용 중으로 설정되어 detach가 어렵습니다.

 

아래 SQL 구문은 데이터베이스의 모든 사용자를 일괄적으로 KILL 하는 쿼리입니다.

-- 데이터베이스의 세션을 모두 자동 kill 하는 SQL 쿼리
-- 수행 전에 중요 작업 프로세스가 있는지 미리 체크하고 실행
USE master;
GO

DECLARE @kill varchar(max) = '';
SELECT @kill = @kill + 'KILL ' + CONVERT(varchar(10), spid) + '; '
FROM master..sysprocesses 
WHERE spid > 50 AND dbid = DB_ID('Your_DB_Name');  -- 데이터베이스 이름으로 변경
EXEC(@kill);
GO

-- 실행하면 SINGLE_USER 설정. 이후 detach 수행.
ALTER DATABASE Your_DB_Name SET SINGLE_USER WITH ROLLBACK IMMEDIATE;

--detach 수행
EXEC sp_detach_db 'Your_DB_Name', 'true';
GO

 

데이터베이스 연결 - attach

같은 SQL Server에서 분리한 다음, 다시 연결(attach)할 경우에는 후처리 작업이 없습니다.
Attach 쿼리 템플릿

CREATE DATABASE 데이터베이스이름  
    ON (FILENAME = 'mdf파일경로'),   
    (FILENAME = 'ldf파일경로')   
    FOR ATTACH;
GO
-- 기본 multi user mode로 연결됨.

-- 만약 Single user mode를 일반 multi user로 재활성화하려면 아래 쿼리 수행
ALTER DATABASE [<Your_DB_Name>] SET MULTI_USER WITH NO_WAIT;

--sp_attach_db는 차기 버전에서 제거될 예정이니, 위의 CREATE DATABASE - ATTACH를 사용하세요.


실제 Attach 쿼리

CREATE DATABASE sqler_test 
    ON (FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\sqler_test.mdf'),   
    (FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\sqler_test_log.ldf')   
    FOR ATTACH;
GO
-- 기본 multi user mode로 연결됨.

-- 만약 Single user mode를 일반 multi user로 재활성화하려면 아래 쿼리 수행
ALTER DATABASE sqler_test SET MULTI_USER WITH NO_WAIT;

 

만약, 다른 SQL Server에서 MDF와 LDF 파일을 연결(attach)할 경우에는, cross db ownership chaining 처리가 필요합니다.
- 데이터베이스 분리 및 연결(SQL Server)

- db 간 소유권 체인(서버 구성 옵션) - SQL Server

 

Cross db ownership chaining(소유권 체인) 처리

다른 시스템에서 MDF와 LDF 파일을 복사해 연결(attach)할 경우, 연결하는 데이터베이스 사용자는 새로운 SQL Server에 존재하지 않습니다. SQL Server 로그인, 역할, 사용자의 데이터베이스 개체 소유권(ownership) 일부 정보는 이전 SQL Server의 master 데이터베이스에 존재하기 때문입니다. 대부분의 경우 mdf와 ldf만 복사했기 때문에 새로운 SQL Server에 연결할 경우 ownership 연결 고리가 끊어지는 문제가 발생합니다. 이 경우 위의 가이드대로 수행합니다.

 

여러 데이터 파일(NDF)로 구성된 파일 그룹 데이터베이스를 연결(attach) 할 경우

같은 SQL 서버에서는 위의 CREATE DATABASE - ATTACH를 이용해 mdf와 ldf만 붙이면 자동으로 ndf와 파일 그룹들이 데이터베이스에 연결됩니다.


다른 SQL Server에서는 파일이 위치한 디스크 등의 구성 정보가 다를 수 있습니다. 만약 다른 디스크 등에 위치한 NDF 파일을 연결할 경우 이렇게 ALTER DATABASE 구문을 사용할 수도 있습니다.
- Move LDF, MDF or NDF file in SQL Server 2016 using Alter Database

 
여러개의 NDF가 있는 경우, attach 하는 방법보다 전체 백업(Full backup)을 받고 RESTORE DATABASE를 이용하시길 권장합니다. 시스템 데이터베이스도 함께 백업하고 같이 복구하는 방법입니다. 
이 방법은 이후 백업과 복구 강좌에서 진행하겠습니다.
 

 

SQL 강좌 책 구매

강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다. 

 

책구매 링크: 챗GPT와 함께하는 마이크로소프트 SQL Server 2022 

책구매링크.png

No. Subject Author Date Views
Notice SQL강좌: 챗GPT와 함께 배우는 SQL Server 무료 강좌 목차와 소개 (2023년 9월 업데이트) 코난(김대우) 2023.08.18 21815
Notice Python 무료 강좌 - 기초, 중급, 머신러닝(2023년 6월 업데이트) 코난(김대우) 2021.01.01 12242
2254 SQL강좌: 6-2. 데이터 무결성 - 테이블 컬럼과 NULL 제약 코난(김대우) 2023.08.18 35
2253 SQL강좌: 6-1. 데이터 무결성 - 데이터 무결성 이해 file 코난(김대우) 2023.08.18 43
2252 SQL강좌: 5-4. 테이블 수정 file 코난(김대우) 2023.08.18 61
2251 SQL강좌: 5-3. 테이블 생성 file 코난(김대우) 2023.08.18 43
2250 SQL강좌: 5-2. 테이블 생성과 데이터형 선택 [1] 코난(김대우) 2023.08.18 25
2249 SQL강좌: 5-1. SQL Server 테이블 file 코난(김대우) 2023.08.18 36
2248 SQL강좌: 4-8. 시스템 카탈로그 엿보기 file 코난(김대우) 2023.08.18 51
2247 SQL강좌: 4-7. 최적의 데이터베이스 구성 file 코난(김대우) 2023.08.18 50
2246 SQL강좌: 4-6. 데이터베이스의 데이터와 로그 코난(김대우) 2023.08.18 22
2245 SQL강좌: 4-5. 데이터베이스 삭제 file 코난(김대우) 2023.08.18 29
2244 SQL강좌: 4-4. 데이터베이스 옵션 file 코난(김대우) 2023.08.18 64
2243 SQL강좌: 4-3. 데이터베이스 크기조절 file 코난(김대우) 2023.08.18 37
» SQL강좌: 4-2. 데이터베이스 생성 file 코난(김대우) 2023.08.18 55
2241 SQL강좌: 4-1. SQL Server 데이터베이스와 데이터베이스 개체의 이해 file 코난(김대우) 2023.08.18 76
2240 SQL강좌: 3-4. TRUNCATE TABLE / 트랜잭션 수행 [1] 코난(김대우) 2023.08.18 44
2239 SQL강좌: 3-3. DELETE를 이용한 로우 삭제 코난(김대우) 2023.08.18 34
2238 SQL강좌: 3-2. UPDATE - 데이터 수정 코난(김대우) 2023.08.18 36
2237 SQL강좌: 3-1. 데이터 삽입, 삭제, 수정 - INSERT를 이용한 행 삽입 코난(김대우) 2023.08.18 52
2236 SQL강좌: 2-14. SQL 쿼리 자동생성 - 쿼리 디자이너 file 코난(김대우) 2023.08.18 65
2235 SQL강좌: 2-13. SELECT 결과셋을 XML, JSON 형식으로 출력 코난(김대우) 2023.08.18 56





XE Login