2019년 8월 4일 일요일

Difference Between ROLAP and MOLAP


Online Analytical Processing

들어가기 전 -
과거 어떤 커뮤니티에서 OLAP을 오엘에이피와 올랩을 구분지어야 한다는 댓글로 논쟁을 하는 사람을 봤는데 쓸데 없는 소모전을 하는 것 같았다. OLTP와 대비되는 개념으로 오엘에이피로 읽어야 하고, 의사결정권자가 데이터를 볼 수 있도록 개발해 놓은 서비스를 올랩으로 읽어야 한다는 것인데 필자가 보기엔 어찌됐든 (오엘에이피든, 올랩이든) 같은 모토와 같은 방향을 바라 보고 있기 때문에 굳이 어떻게 읽느냐로 논쟁의 의미가 있나 싶었다.
결론 - 비효율적이면서 소모적인 논쟁이다.


올랩이란 질문에 대한 답을 얻기 위해 설계된 시스템이다.
여기서 말하는 질문이란 "언제, 어디서, 어떤 성별이, 어떤 카테고리의 물건을 자주 구매하는가?"가 될 수 있다. 이러한 질문에 답을 하기 위해서는 작은시스템(실시간으로 다량의 트랜잭션이 발생하지 않는)이라면 DB에 바로 SELECT - JOIN - GROUP BY 쿼리를 날려 알아낼 수 있다. 하지만 거대한 트랜잭션이 실시간으로 들어오는 OLTP 환경이라면 절대 불가능 할 것이다.
이를 위해 DW가 필요한 것이고 이번 포스팅을 보기 전 아래 포스팅을 참고하면 좋을 것이다.
바로가기 - 전통적 Data WareHouse(데이터 웨어하우스) 아키텍처 및 고찰



그럼 DW를 통해 만들어낼 수 있는 OLAP에 대해 알아보도록 하자.

OLAP에는 크게 ROLAP과 MOLAP이 존재한다. 물론 이 둘을 수용한 HOLAP(하이브리드), DOLAP 등이 있지만 크게는 ROLAP과 MOLAP으로 구분할 수 있다.

picture by Doulkifli Boukraâ


Star Schema(또는 Snowflake schema)로 구성된 Sales, Time, Location, Product라는 테이블이 있다. Sales는 Fact Table이며 Time, Location, Product은 Dimension Table이다.
좌측은 MOLAP, 우측은 ROLAP이다.


질문을 하나 던졌다.
"언제, 어디서, 어떤 상품의 매출이 얼마나 되는가?"

MOLAP에서는 특정 X,Y,Z 좌표의 Cell에 해당 답이 존재할 것이고, ROLAP의 경우에는 Sales, Time, Location, Product를 선으로 잇고 따라가며 결과를 알아낼 수 있을 것이다.

둘 모두 정답을 내놓을 수 있다면 둘 중에 어떤 구조가 효율적일까?
정답은 없으며 각각의 OLAP을 만드는 방법으로 인해 장단점이 존재한다.

MOLAP의 경우에는 미리 질의된 값을 CUBE형태로 저장하고 있다. 그림처럼 다차원 배열을 저장할 수 있도록 설계된 MDBMS가 필요하며 MDX라는 Language로 구현이 된다.
반면에 ROLAP의 경우에는 다차원큐브 형태로 저장하는 것이 아닌 테이블처럼 2차원 배열형태로 저장이 된다.




다양한 유료 솔루션이 존재하기도 하고 apache kylin이나 druid같은 오픈 소스가 존재하기도 한다. 둘 모두 전통적인 ROLAP, MOLAP이라고 하기엔 무리가 있지만 어느 성질에 가까운 지는 작동 방식만 봐도 예상할 수 있다. druid는 테스트를 해보지 않아서 어떤 성질의 OLAP인지는 확실히 알지 못하지만 대략 cube를 만들지 않기 때문에 ROLAP에 가까운 것 같다.  time series이면서 데이터를 인덱싱하여 빠른 조회가 가능할 수 있도록 하는데 druid는 결국 별도의 다차원 CUBE를 만들지 않기 때문에 ROLAP과 가까운 반면 kylin의 경우에 cube를 생성하기 위해 팩트와 디멘전을 정의해주는 단계가 있고 실제 집계하는데 시간을 꽤 투자해야하기 때문에 MOALP쪽에 가까운 것 같다.



그럼 MOLAP VS ROLAP 의 승자는?
MOLAP과 ROLAP을 고르는 기준은 쿼리의 복잡성에 달려있다.
빠른 속도를 원하면 MOLAP, 유연한 확장을 원하면 ROLAP을 택하면 될 것이다.
확실히 일반적인 상황 이상으로 수 많은 차원이 존재하고 자주 차원이 추가된다면 MOLAP은 단점일 수 있다. 왜냐하면 큐브를 새로 만드는 것 외에도 집계하는데 오래 걸리기 때문이다. 최근 몇 개월이 아닌 수년동안의 데이터에 차원 한개를 추가하여 큐브를 다시 집계하는 것은 엄청나게 소모적인 일이기 때문이다. 따라서 이러한 경우에는 ROLAP이 좋을 수 있다. ROLAP의 경우에 집계보다 조회가 오래 걸리기 때문에 아무래도 개발적인 측면에서 (난이도보다는 완성되는데까지의 소요 시간) 더 유리하기 때문이다. 하지만 분명한 것은 이미 정해진 '틀' 안에서는 확실히 MOLAP이 빠르고 다양한 분석(접근)이 가능한 것은 ROLAP인 것은 자명한 사실일 것이다.

2019년 8월 3일 토요일

How to make MSSQL Audits, Encryption ( Data-Database level)

컬럼을 암호화하면 정렬을 하나 마나이기 때문에 인덱스 설정은 무의미하다.
따라서 정렬되야 하는 컬럼을 암호화하면 성능에 문제가 생길 수 있다. 또한 암호화는 데이터 크기도 증가시키기 때문에 물리적인 공간도 더 많이 사용한다.

데이터 암호화
MSSQL이 제공하는 암호화 방법은 다음과 같다.

방법/암호화 함수/복호화 함수
1. 대칭키 사용 암호화(Encrypt using symmetric key)/EncryptByKey/DecrpytByKey
2. 비대칭키 사용 암호화(Asymmetric key usage encryption)/EncryptByAsymKey/DecrpytByAsymKey
3. 인증서를 사용한 암호화(Encryption with Certificates)/EncrpytByCert/DecrpytByCert
4. HASHBYTES 함수를 사용한 암호화(Encryption using the HASHBYTES function)/HASHBYTES/없음(none)



대칭키로 암호화하려면 우선 암호화에 사용할 대칭 키를 만들어야한다.
암호를 사용해서 대칭키를 보호할 수도 있지만 인증서로 보호되는 대칭키를 만들수도 있다.

-- 대칭키 만들기
USE TEST
GO

CREATE SYMMETRIC KEY SECKEY
WITH ALGORITHM = AES_256
ENCRYPTION BY PASSWORD = 'defensepark11@'
GO


대칭 키를 만든 직후에는 대칭 키가 열려있지만 그렇지 않을 때는 명시적으로 열어야 하며 암호가 필요하다.

-- 대칭키 열기
OPEN SYMMETRIC KEY SECKEY
DECRYPTION BY PASSWORD = 'defensepark11@'
GO


--데이터 암호화 시키기
SELECT COL_1, EncryptByKey(Key_GUID('SECKEY'),COL_1) AS SEC_COL_1
FROM TMP_TBL


-- 테스트 테이블 생성
CREATE TABLE TMP_TBL (
COL_1 VARCHAR(50) NOT NULL,
COL_2 VARCHAR(50) NOT NULL,
COL_3 VARCHAR(50) NOT NULL
)


INSERT INTO TMP_TBL VALUES('호날두','호날두','호날두')
INSERT INTO TMP_TBL VALUES('즐라탄','즐라탄','즐라탄')

INSERT INTO TMP_TBL VALUES('메시','메시','메시')

--데이터 복호화 시키기
SELECT COL_1
, EncryptByKey(Key_GUID('SECKEY'),COL_1) AS ENC_COL1
, CONVERT(VARCHAR(50),DecryptByKey(EncryptByKey(Key_GUID('SECKEY'),COL_1))) COL_1
FROM TMP_TBL


암호화&복호화 결과는 다음과 같다.






HASHBYTES 함수를 사용한 암호화
- 암호화를 위해 키나 인증서가 필요하지 않다.
복호화가 불가능하다. (단방향 암호화)
암호화한 컬럼에 인덱스를 생성해서 성능 효과를 볼 수 있다.
(조회할 때 HASHBYTES로 암호화를 해서 조회하면 되니까...)


--암호화 시키기
SELECT COL_1, HASHBYTES('MD5',COL_1)
FROM TMP_TBL

결과는 다음과 같다.




해쉬바이트로 암호화를 시키면 복호화를 할 수는 없지만 조회할려는 데이터를 해쉬바이트로 암호화해서 이퀄조회로 찾으면 된다. 따라서 이건 인덱스를 만들 수 있다.





데이터베이스 암호화
MSSQL 2008부터는 엔터프라이즈 버전에서 새로운 데이터 암호화 방법을 제공한다.
응용프로그램 레벨에서 안건들이고 데이터를 암호화 할 수 있어서 투명한 데이터 암호화(TDE)라 불린다.

단 컬럼 단위의 암호화가 아닌 데이터베이스 전체를 암호화한다.
데이터베이스 암호화는 암호화 함수를 사용하지 않고 MSSQL이 자동으로 암호화한다.
데이터 페이지를 암호화하고 디스크에 기록하고, 데이터를 디스크에서 메모리로 읽어들일 때 복호화한다.
그리고 암호화된 데이터베이스는 다른 서버에 연결(Attach)하거나 복원(Restore)이 불가능하다.


암호화 설정 단계
1. 마스터키 생성
2. 마스터키로 보호되는 인증서 만들기
3. 인증서로 보호되는 DEK(데이터베이스 암호화 키) 만들기
4. 암호화를 사용하도록 데이터베이스 설정



1, 2번은 master DB에서 수행해야하고 3, 4번은 해당 DB에서 수행해야 한다.


1. 마스터키 생성
USE master
GO
CREATE MASTER KEY
 ENCRYPTION BY PASSWORD = 'defensepark11@'




2. 마스터키로 보호되는 인증서 만들기
인증서는 DB 암호화 키를 보호하는데 사용되고 master db에 만들어야 한다.
CREATE CERTIFICATE TDECertificate
 WITH SUBJECT = 'server level certificate for TDE'




3. 인증서로 보호되는 DEK(데이터베이스 암호화 키) 만들기
암호화하려고 하는 대상 DB에서 만들어야하고 DB 암호화 키를 보호하는데 사용된 인증서를 백업받아야한다고 경고메세지가 표시된다. 암호화된 DB를 백업한 후 나중에 복원할 때 인증서가 꼭 필요하기 때문이다.


USE TESTDB
GO
CREATE DATABASE ENCRYPTION KEY
 WITH ALGORITHM = AES_256
 ENCRYPTION BY SERVER CERTIFICATE TDECertificate
GO
쿼리를 날리면 다음과 같이 뜬다.

경고: 데이터베이스 암호화 키를 암호화하는 데 사용된 인증서가 백업되지 않았습니다. 인증서와 인증서에 연결된 개인 키를 즉시 백업해야 합니다. 인증서를 사용할 수 없게 되거나 다른 서버에서 데이터베이스를 복원하거나 연결해야 할 경우 인증서와 개인 키의 백업본이 있어야 합니다. 그렇지 않으면 데이터베이스를 열 수 없습니다.
WARNING : The certificate used to encrypt the database encryption key was not backed up. You should back up the certificate and the private key associated with it immediately. If the certificate becomes unavailable or you need to restore or connect the database from another server, you must have a backup of the certificate and private key. Otherwise, you can not open the database.



4. 암호화를 사용하도록 데이터베이스 설정
ALTER DATABASE TESTDB
 SET ENCRYPTION ON
GO



인증서 백업과 복원
암호화한 데이터베이스는 백업 파일도 암호화된다. 따라서 복원하려면 암호화 키를 보호하는 인증서가 있어야한다. 인증서가 없으면 데이터베이스를 복원할 수도 없고 데이터베이스를 분리해서 다른 서버에 연결할 수도 없다.


인증서 백업 
BACKUP CERTIFICATE 문을 사용해서 인증서를 백업한다. 이때 개인 키도 같이 백업해야 이후에 인증서를 복원할 수 있다.



BACKUP CERTIFICATE TDECertificate
 TO FILE = 'C:\SQLBACKUP\TDECertificate.cer'
 WITH PRIVATE KEY (FILE = 'C:\SQLBACKUP\TDECertificate.pvk' ,
 ENCRYPTION BY PASSWORD = 'defensepark11@')
GO

백업이 되면 폴더에 가서 확인할 수 있다.




인증서 복원
암호화된 데이터베이스를 복원할 새로운 서버에 백업한 인증서와 개인 키를 복사하고 그 백업 파일로부터 인증서를 만든다. master 데이터베이스에 마스터 키가 없으면 만들어야한다. CREATE MASTER KEY 문을 사용해서 대상 서버에서 마스터 키를 만들고, CREATE CERTIFICATE...FROM 문을 사용해서 복사한 인증서 파일로부터 인증서를 복원한다.



USE master

CREATE MASTER KEY
 ENCRYPTION BY PASSWORD = 'defensepark11@'
GO


CREATE CERTIFICATE TDECertificate
 FROM FILE = 'C:\SQLBACKUP\TDECertificate.cer'
 WITH PRIVATE KEY (FILE = 'C:\SQLBACKUP\TDECertificate.pvk',
 DECRYPTION BY PASSWORD = 'defensepark11@')
GO



데이터베이스 암호화 제거

-- 암호화 OFF
ALTER DATABASE TESTDB
 SET ENCRYPTION OFF
GO

-- 데이터베이스 암호화 키 제거
USE TESTDB
GO

DROP DATABASE ENCRYPTION KEY
GO

-- 인증서 제거
USE master
GO

DROP CERTIFICATE TDECertificate
GO

-- 마스터 키 제거
DROP MASTER KEY
GO

-- 복구모델단순으로 변경
ALTER DATABASE TESTDB
 SET RECOVERY SIMPLE
GO

-- 체크포인트 명령어를 몇번 실행시켜서 로그를 완전히 없앤다. 
CHECKPOINT -- 여러번 수행
GO

-- 복구모델 원래대로 변경
ALTER DATABASE TESTDB
 SET RECOVERY FULL
GO



MSSQL 감사(SQL SERVER Audits)

mssql 2008부터 제공되는 mssql 감사 기능은 트리거나 프로파일러와 같은 기능들의 단점을 극복해주는 가장 적절한 감사 기능이다. sql server 감사를 구성해 서버와 데이터베이스에서 발생하는 모든 동작을 추적하여 그 내역을 기록(감사 로그)할 수 있다. 무엇보다도 테이블이나 뷰에 대한 select와 프로시저에 대한 exec 동작도 감사 대상인 것이 장점이다.
보통 실시간 실행 배치를 만들어서 떠다니는 쿼리를 잡아서 로깅하거나 어플리케이션 단에서 로깅을 하도록 하는데 이건 좋은 것 같다.


-- 감사 만들기
USE master
GO

-- 디폴트로 만들기
CREATE SERVER AUDIT [Audit_test]
 TO FILE (FILEPATH = 'C:\SQLLOG\Audit')
GO


/* 옵션 주기
USE master
GO

CREATE SERVER AUDIT Audit_test
TO FILE ( FILEPATH = 'C:\SQLLOG\Audit',
 MAXSIZE = 512MB,
 MAX_ROLLOVER_FILES = 100,
 RESERVE_DISK_SPACE = OFF
) WITH (
 QUEUE_DELAY = 1000,
 ON_FAILURE = CONTINUE
)
GO
*/
-- 감사 활성화 하기
ALTER SERVER AUDIT Audit_test
 WITH (STATE = ON)
GO


감사 사양(Audit Specifications) 만들기
실제 감사 정보를 남기려면 감사 사양을 만들어야 한다.
감사 사양은 서버 감사 사양과 데이터베이스 감사 사양으로 구분되고 서버 감사 사양은 서버 범위에서 발생하는 동작을, 데이터베이스 감사 사양은 데이터베이스 범위에서 발생하는 동작을 기록한다.


--데이터베이스 감사 사양 만들기
USE TESTDB
CREATE DATABASE AUDIT SPECIFICATION Audit_test_spec
 FOR SERVER AUDIT Audit_test
 ADD (SELECT ON OBJECT::dbo.TMP_TBL BY public)
GO


--감사 사양 활성화
ALTER DATABASE AUDIT SPECIFICATION Audit_test_spec
 FOR SERVER AUDIT Audit_test
 WITH (STATE = ON)
GO


--하나 셀렉트 해주고
SELECT TOP 1 *
FROM TMP_TBL

--기록된 감사 확인
SELECT *
FROM sys.fn_get_audit_file('C:\SQLLOG\Audit\Audit_test*',DEFAULT,DEFAULT);




--감사와 감사 사양 제거
USE TESTDB
GO


-- 감사 사양 비활성화
ALTER DATABASE AUDIT SPECIFICATION Audit_test_spec
 WITH (STATE = OFF)
GO


-- 감사 사양 제거
DROP DATABASE AUDIT SPECIFICATION Audit_test_spec
GO

USE master
GO


-- 서버 감사 비활성화
ALTER SERVER AUDIT Audit_test
 WITH (STATE = OFF)
GO


-- 서버 감사 제거
DROP SERVER AUDIT Audit_test
GO



감사 설정은 서버에 무리가 없다고 하는데 트래픽이 있는 곳에서는 무리가 있을 것으로 보이고.. 그래도 필요한 곳에만 감사를 걸어서 문제 발생 여지를 남기지 말자.


2019년 8월 1일 목요일

전통적 Data WareHouse(데이터 웨어하우스) 아키텍처 및 고찰

이번 포스팅에서는 전통적 데이터 웨어하우스 아키텍처 및 고찰을 해보고자 한다.

개인적인 생각으로는 이미 DW는 수십년 전에 기술적, 논리적인 발전이 정점에 올랐기 때문에 아키텍처라던지 데이터 설계면에서 새로운 이론이 나올 가능성은 적어보인다. 또한 클라우드라는 기술이 새로 나타나긴 했지만 큰 틀에 변화를 주기에는 기존의 구성이 너무 잘 되어있어 큰 틀에 영향을 주기에는 미미해보인다.

그래도 DW 자체만 보면 얼마 전 빅데이터의 유행과 더불어 갈 수록 커지는 데이터의 잠재력(AI, ML/DL)으로 인해 DW는 필수가 되어가고 있다.

전통적인 아키텍처를 설계하기 전 OLAP과 OLTP에 대해서 간단하게 짚고 넘어가도록 하자.

OLTP는 Online transaction processing의 약자로 실제 운영중인 환경이다. 실제 운영중이라 함은 SELECT, INSERT, DELETE, UPDATE 등의 트랜잭션이 계속해서 발생한다는 뜻이다. 과연 이렇게 트랜잭션이 몰리는 환경에서 전체 데이터에 대한 GROUP BY 쿼리를 수행할 수 있을까? 아마 불가능할 것이다.

OLAP는 Online Analytical Processing의 약자로 데이터 분석용 환경이다. 가령 "어떤 물품은 어느 요일에 어디서 누구에게 팔아야 매출이 오를 것이다"라는 가설을 세워보자. 그럼 의사결정권자는 분명히 "언제, 누가, 어디서, 무엇을 많이 주문했는가?"라는 질문을 떠올릴 것이다. 이러한 질문을 쿼리로 보면 ( GROUP BY 언제, 누가, 어디서, 무엇 )이 될 것이고 이러한 쿼리는 OLTP에서는 상상도 못할 무지막지한 쿼리가 될 것이기 때문에 별도의 환경, 즉 OLAP 환경이 필요한 것이라고 할 수 있다. 그리고 OLAP을 위해 DW가 필요하다.


DW 아키텍처



위의 그림은 전통적인 DW 아키텍처이다.
간단하게 도색했지만 대부분의 설계에서 큰 틀은 비슷하다.



먼저 운영계(기간계) 설명을 하면 여러 곳에 퍼져있는 데이터 소스들의 집합이라고 볼 수 있다. 이는 오라클, mssql, mysql, postgrel 등의 RDBMS로 되어있을 수도 있고, HADOOP 같은 파일 시스템으로 존재할 수도 있고, CSV/TXT 등의 파일형식, JSON/XML 등 웹 형식으로 존재할 수 있다. 다시 말하면 이 영역은 원천 데이터 소스 영역이다.



다음은 운영계 데이터를 DW영역으로 가져가기 위한 ETL 작업이다. ETL은 Extract, Transform, Load의 합성어이며 말 그대로 추출, 변형, 로드가 가능하지만 큰 의미에서는 소스에서 타겟으로 데이터를 옮기는 작업이라고 생각하면 쉽다. ETL을 위한 Tool이 따로 존재하며 Informatica, SSIS,  DataStage 등이 있다. 또한 오픈소스로는 하둡의 Sqoop이 존재한다.
추가로 ETL 용으로 사용할 수 있는 기술인 CDC(change data capture)라는 것도 있으며 소스 데이터베이스의 LOG를 읽어서 타겟에 동기화를 시켜주는게 있다. 이는 실시간 처리가 가능하다는 장점이 있지만 좋은 솔루션은 가격이 부담스럽다. 솔루션으로는 Oracle GoldenGate 등이 존재한다.



다음은 실제 DW영역이라고 할 수 있는 STG->ODS->DW->DM 영역이다.
STG는 임시 데이터 영역이며, ODS는 원천(소스)과 일치하는(가공안한) 데이터 영역, 그리고 DW는 ODS를 가공해서 만들어내는 데이터 영역, DM도 마찬가지로 ODS나 DW를 가공해서 만들어내는 데이터 영역이다. 사실 DW와 DM은 큰 구분이 없으며 DW가 모든 것을 수용하고 있다면 DM은 뒤에서 서비스용도로 사용하기 위해 미리 계산된, 즉 집계해놓은 데이터라고 생각하자.
이 부분은 일반적인 SMP 구조의 DB 보다는 MPP 구조의 DB가 좋은 성능을 발휘할 수 있다. 예를 들어서 PDW(Parallel Data Warehouse), Teradata, Greenplum 등이 존재하는데 MPP구조의 경우 SMP보다 성능, 확장성이 좋으며 노드(용량)를 추가할 때 마다 성능이 선형으로 증가되기 때문이다. (하둡의 데이터 노드와 비슷하다고 생각하면 좋겠다.)



마지막으로 BI 및 서비스 영역이다.
여기서는 DW에서 미리 집계해놓은 데이터를 바탕으로 화면에서 차트 및 그리드 형식으로  화면에 보여줄 수 있을 뿐만 아니라 DW에서 계산된 데이터를 바탕으로 고객에게 상품을 추천한다던지 등의 활용을 하는 영역이다.
BI 솔루션으로는 Power BI, Spotfire 등이 있으며 오픈소스나 highchart, highmap 등을 통해 직접 구현해도 충분히 좋은 그림을 만들어낼 수 있다.




여기까지가 전통적인 DW 아키텍처에 대해서 이야기를 적어봤다.
100% 그런 것만은 아니지만 정형 데이터(관계형 데이터) 기준으로 현재 DW를 구축했다고 볼 수 있다.



하지만 앞으로는 DataLake, 즉 데이터 호수의 개념으로 확장 될 것이다. DataLake라 함은 모든 데이터를 대상으로 하는 곳이며 DW보다 더 큰 의미이자, 빅데이터 웨어 하우스(?)라고 이해해도 좋을 것 같다.

또한 수년 전부터 데이터 저장을 하둡으로 하여 하둡으로 DW를 구축한 곳이 늘어나고 있다. 물론 하둡으로 RDBMS를 100% 대체하는 것은 불가능하지만 분명히 하둡의 특성상 RDBMS의 상호 보완재로는 적합해보인다. 또한 하둡+스파크 조합은 싸고 확장성이 좋다.

클라우드 역시 요즘 엄청난 기세로 뜨고 있지만 비용이 만만치않아서 도입하기가 어려운 단점이 있다. 하지만 뛰어난 성능을 자랑하고 only 클라우드가 아닌 On-premise와 함께 하이브리드로 구축할 수도 있다. 예를 들어 대용량 집계만 클라우드에서 하고 쿼리는 On-premise에서 하는 구조가 있겠다.


마무리 글
원래는 ROLAP, MOLAP, Fact/Dimension 개념에 대해서도 설명하려고 했는데 글이 너무 길어져서 다음 포스팅으로 넘기려고 한다.
개인적인 생각이지만 앞으로 데이터의 발생량 및 수집량, 중요도가 커지면 커질수록 DW, DataLake, Bigdata의 가치도 커질 것이고 각각의 고유한 영역이 허물어져 어느 순간 OverLap되어 하나의 덩어리(?)가 될 것 같다.
그때를 위해서 각각의 영역을 모두 경험하면 더 좋은 설계를 할 수 있지 않을까 생각해본다.