본문 바로가기

Data Engineering/Cloud_Azure

DP-700 (취득완료)

학습계획 : 2025/07/31 이전 취득 - 달성

교재 : Microsoft Doc + Dump

 

[학습순서]

07/20 23:00~23:30 - 목차 및 시험 준비 계획 수립

07/22 21:40~23:00 - 1) Ingest Data

             23:00~01:00 - 2) Implement a Lakehouse

             01:00~01:30 - 3) implement real-time intelligence

07/23 23:20~00:00 - 4) Implement a DW

             00:00~02:00 - 5) Management a Fabric env

 

07/26 14:30~16:30 - 덤프 1~45번

             22:45~23:30- 덤프 45~50번

07/29 14:30~18:00 - 덤프 50~60번

07/31 12:30~16:30 - 덤프 60~105번

* 덤프 파일을 Gemini에게 주고, 문제별 해석을 부탁하고, 마지막엔 틀린 문제들이나 주요 내용들을 요약하게 시켜 도움이 많이 됨.

 

07/31 17:50~20:00 - 시험 1차 응시(영어) - 합격 (700점대 후반) - 덤프와 상당 부분 유사하게 출제됨

                                           1단계 : 일반문항 43개, 2단계 : 1개 케이스에 대한 8문항 (1단계가 끝나고 2단계 돌입 시 돌아갈 수는 없음)

                                           덤프와 답이 정확히 일치하는 문제들이 있어 시간을 벌 수 있었고, 케이스도 유사하게 출제됨. 시간 여유 있었음.


[DP-700 시험 준비 방법 링크]

1) Ingest data (8h) [자료]  
2) Implement a LakeHouse(7H) [자료]
 
3) implement real-time intelligence (5.5H) [자료]
 
4) implement a DW (6H) [자료]
 
5) Management a Fabric env(3h) [자료]
 

+ KQL(https://learn.microsoft.com/ko-kr/kusto/query/?view=microsoft-fabric)


1) Ingest Data

 

[Keywords]

 

1-1) Microsoft Fabric에서 데이터 흐름 Gen2를 사용하여 데이터 수집

1-2) Microsoft Fabric을 사용하여 프로세스 및 데이터 이동 조정

1-3) Microsoft Fabric에서 Apache Spark 사용

: PySpark와 Spark SQL 조합으로 주로 작성됨.

: 작업영역에 시작 풀을 설정하면, 항상 켜진 풀을 제공하여 각 리소스의 로딩을 빠르게 만들 수 있다.

: 네이티브 엔진이라는 기본 Apache Spark와 다른 엔진을 미리보기로 사용할 수도 있다.

: 버스트 옵션을 켜면 3배까지 리소스를 당겨 사용할 수 있다. (관리자용 ELT 영역에만 설정하는 것이 좋다)

: Spark 풀과 런타임을 미리 설정하여 각 작업영역에 할당해둘 수 있다. 런타임에는 각 라이브러리와의 버전 매칭도 설정한다.        

: high concurrency for notebooks 옵션을 활성화하면 같은 유저의 노트북은 같은 세션으로 연결해 신규 실행 시간을 줄일 수 있다.

1-4) Microsoft Fabric에서 실시간 인텔리전스 시작

: 목적 = 추세 분석, 이상 감지

: 특징 = 바인딩되지 않음. 영구적으로 추가. temporal(시간 기반) 데이터, 집계는 임시 시간 윈도우 기반으로 진행

: Real-Time Intelligence는 Real-Time Hub 내에

  1) Ingest-Process(캡처, 변환, 수집)를 담당하는 Eventstream

  2) Analyze & Transform을 위해 Eventhouse(KQL DB)에 저장되고, KQL Queryset 쿼리로 분석한다.

  3) Visualize& Act를 담당하는 Real-Time Dashboard, PowerBI가 있으며,

  4) Activator를 통해 자동화된 작업을 트리거하는 경고를 구성한다. 

  5) Data Storage로는 OneLake를 사용한다.

: 지원되는 원천 = Azure Storage, Azure EventHubs, Azure IoT Hubs, Apache Kafka Hubs, CDC

: 지원되는 변환 = 필터, 필드 관리, 집계, Group By, 공용 구조체, 확장(배열 변환으로 새 행 추가), 조인

: 지원되는 타겟 = Eventhouse, Lakehouse, 파생 Stream, 패브릭 활성화기, 사용자 지정 엔드포인트

: Eventhouse에서는 KQL DB를 생성할 수 있고, 컬렉션, 함수, 뷰 바로가기 등 기능을 사용할 수 있다.

: K(Kusto)QL 쿼리 세트는 KQL과 T-SQL 언어의 하위 집합을 활용하여 쿼리를 지원한다.

: 시각화는 KQL 쿼리 세트에서 바로 작성하거나 대시보드를 생성하여 원천으로 eventhouse를 연결한다.

: Activator는 트리거 조건에 따라 이상 알림, 후속 프로세스 실행 등을 수행하며, 이벤트/개체/속성 및 규칙 4가지로 작동

 

1-5) Microsoft Fabric에서 실시간 이벤트 스트림 활용

: 이벤트스트림은 사이즈 및 안정성, 보안을 자동으로 관리함.

: 집계 윈도우 함수는 텀블링(동일 시간으로 겹치지 않게 자름), 슬라이딩( 동일 시간으로 겹치게 자름), 세션(특정 시간 행동이 없으면 창을 나눔), 호핑(겹치지만 앞 윈도우에 포함된 것은 제외하고 받음), 스냅샷(여러 트랜젝션의 동일한 시간대 캡쳐 저장), 초 단위로 설정 가능하며, 각 윈도우 사이에 간격(오프셋)을 둘 수 있음. 그룹화가 가능하고, 윈도우별 집계도 가능함.

 

1-6) Microsoft Fabric 이벤트 하우스에서 실시간 데이터 작업

: KQL

  1) 테이블 이름이 중심이며, | 를 통해 연산자 호출

  2) 기본 호출 : project 열 나열(열 호출), where 조건나열(필터), sort by 정렬기준(정렬)

  3) 집계 : summary 열이름1 = count() by 열이름2 (열이름2로 그룹핑하여 열이름1의 건수 집계)

  4) 날짜 함수 : getmonth(temporal열이름), getyear(temporal열이름), 열이름 > ago(30min) = 30분 전부터 지금까지

  5) ingestion_time()은 날짜 열이 없더라도 event가 저장된 시간을 반환하는 열

 

지난 하루 동안 수집된 이벤트에서 각 택시 공급업체가 매 시간 수집한 평균 요금을 검색합니다.

Automotive
| where ingestion_time() > ago(1d)
| summarize average_fare = avg(fare_amount) by vendor_id, pickup_hour = hourofday(pickup_datetime)
| project pickup_hour, vendor_id, average_fare
| sort by pickup_hour

 

  6) 뷰 생성

-- 앞으로 들어올 데이터가 새로 생성되는 뷰에 저장 시작되도록 만드는 방법

.create materialized-view TripsByVendor on table Automotive
{
    Automotive
    | summarize trips = count() by vendor_id, pickup_date = format_datetime(pickup_datetime, "yyyy-MM-dd")
}

-- 과거 데이터도 포함하여 뷰를 만드는 방법

.create async materialized-view with (backfill=true)
TripsByVendor on table Automotive
{
    Automotive
    | summarize trips = count() by vendor_id, pickup_date = format_datetime(pickup_datetime, "yyyy-MM-dd")
}

-- 생성된 뷰들은 테이블처럼 쿼리 가능

 

  7) 함수 생성 및 사용

-- 함수 생성

.create-or-alter function trips_by_min_passenger_count(num_passengers:long)
{
    Automotive
    | where passenger_count >= num_passengers 
    | project trip_id, pickup_datetime
}

-- 함수 사용

trips_by_min_passenger_count (3)

2) Implement a LakeHouse(7H)

 

 

2-1) Microsoft Fabric을 사용하는 엔드투엔드 분석 소개

: DE, Data Ingestion, DW, Real-Time, DS, BI 모두 포함

: 테넌트 설정에서 Fabric 사용여부 결정, 특정 보안그룹만 사용하도록 오픈 가능

: 작업영역 단위로 OneDrive, DL Gen2, Git, Spark 워크로드 지정 가능

: 관리자/기여자/맴버/뷰어로 권한 구분됨.

 

2-2) Microsoft Fabric에서 레이크하우스 시작

: OneLake 스토리지 계층을 기반으로 빌드되고, Apache Spark 및 SQL 컴퓨팅 엔진을 사용하는 통합 플랫폼.

: Delta 형식 테이블로 ACID보장하며, 레이크 기반으로 빌드. 웨어하우스의 SQL 분석 기능과 레이크의 유연성 및 스케일링 성능을 결합

  * ACID (Atomic:원자성, Consistency:일관성, Isolation:격리, Durability:내구성)

: 자동 스케일링 및 고가용성 및 재해 복구 지원

: 미리 정의된 스키마를 사용하지 않고, 필요에 따라 스키마를 정의하는 읽기 스키마 형식으로 구성

: purview 기능을 연동하여 권한 관리

: 레이크 하우스는 분석가들을 위한 시멘틱 모델(의미 체계 모델)과 SQL 쿼리를 위한 읽기 전용 분석 엔드포인트로 이뤄짐.

: 데이터 수집 시, 업로드나 스크립트를 통해 데이터 연결이 가능하고, 여러 언어의 컴파일 이진 파일을 업로드 하면 변환 논리로 사용 가능

: 데이터 변환 및 로드에는 NoteBook(Pyspark, SQL, Scala 사용자), 데이터 흐름 Gen2(PowerQuery 사용자), 파이프라인(DE) 사용

 

2-3) Microsoft Fabric에서 Delta Lake 테이블 작업

: Delta Lake는 Iceberg, hudi보다 Spark와 호환이 좋음. 

: Spark에서 Delta Table 생성/변경이 가장 수월함.

# 관리 테이블 생성

#(방법1)
df.write.format("delta").saveAsTable("mytable")
# (방법2)
from delta.tables import *
DeltaTable.create(spark) \
  .tableName("products") \
  .addColumn("Productid", "INT") \
  .addColumn("ProductName", "STRING") \
  .addColumn("Category", "STRING") \
  .addColumn("Price", "FLOAT") \
  .execute()
  
# 외부 테이블 생성 (메타스토어 UI에서 테이블 삭제해도 테이블은 삭제되지 않음)
df.write.format("delta").saveAsTable("myexternaltable", path="Files/myexternaltable")
-- SQL로 테이블 생성하는 방법

%%sql
CREATE TABLE salesorders
(
    Orderid INT NOT NULL,
    OrderDate TIMESTAMP NOT NULL,
    CustomerName STRING,
    SalesTotal FLOAT NOT NULL
)
USING DELTA
-- 외부 테이블 필요 시 LOCATION 'Files/...' 구문 추가

 

: dataframe을 저장할 때, .write.format("delta").mode("overwrite") 혹은 .mode("append") 사용이 가능하다.

: 변경 이력이 파편화되어 속도 이슈가 발생하는 것을 방지하기 위해 OptimizeWriter 옵션을 설정할 수 있음.

# Enable Optimize Write at the Spark session level
spark.conf.set("spark.microsoft.delta.optimizeWrite.enabled", True)

: 위 옵션을 실행하면 작은 파일을 여러개 저장하지 않고, 큰 파일 하나로 모아 저장하게됨

: 이미 저장되어 있는 파일들을 최적화하려면, Lakehouse Explorer에서 테이블 이름 옆의 "유지관리"를 선택하고 Optimize 실행

  필요에 따라 V-Order 적용(Parquet에 대한 특수 정렬, 행 그룹 배포, 사전 인코딩 및 압축)

  읽기 속도는 10~50% 개선되나, 쓰기를 할 경우 15%정도 오버헤드가 생겨 손해가 있음.

: Delete 된 내용에 대해서는 보존 기간에 따라 Vacuum을 실행할 수 있다. (삭제 로그를 지워 용량을 절약하지만, 롤백할 수 없게 된다)

: 테이블에 대한 트랜젝션 로그는 아래 코드로 확인할 수 있다.

%%sql
DESCRIBE HISTORY lakehouse명.테이블명;

: 파티셔닝이 필요한 경우 컬럼을 지정하여 파일 분리 가능 (.partitionBy)

df.write.format("delta").partitionBy("Category").saveAsTable("partitioned_products", path="abfs_path/partitioned_products")

: Spark SQL로도 편집이 가능하며, %%sql 선언자를 사용한다.

: df = spark.read.format("delta").option("timestampAsOf", '2022-01-01').load(delta_path) 구문처럼

  과거 버전의 데이터를 호출할 수도 있다.

: 스트리밍 데이터를 지속해서 받아 사용하는 테이블을 만들 수도 있음. (.writeStream 옵션으로 저장도 가능)

# Load a streaming DataFrame from the Delta table
stream_df = spark.readStream.format("delta").option("ignoreChanges", "true").table("테이블명")

# Verify that the stream is streaming
stream_df.isStreaming

# Write the stream to a delta table
output_table_path = 'Tables/orders_processed'
checkpointpath = 'Files/delta/checkpoint'
deltastream = transformed_df.writeStream.format("delta").option("checkpointLocation", checkpointpath).start(output_table_path)

print("Streaming to orders_processed...")

# Stop the streaming data to avoid excessive processing costs
deltastream.stop()

 

2-4) 레이크하우스 메달리온 아키텍처 디자인 구성

: 브론즈(원시), 실버(검증됨), 골드(보강)으로 "멀티홉" 아키텍처라 부르기도 함. 데이터 정리를 위한 프레임워크

: 브론즈는 정형/비정형/반정형 등 모든 데이터의 렌딩존이라 할 수 있음. 브론즈 앞에 원시 레이어를 더 둘 수도 있음.

: 실버는 결합 및 병합, Null 및 중복 제거, 유효성 검사 후의 데이터가 해당함. 품질에 집중

: 골드는 구체화되고 특정 비즈니스에 특화되는 것으로 집계되거나, 의미 강화. 다운스트림 팀에서 사용. 주로 스타 스키마로 구성

: 데이터의 량, 수행 복잡도, 변환 및 이전 빈도, 사용도구 등을 고려하여 레이어 간 이동 정책을 구성.

: 대체로 파이프라인으로 이동됨.

: 작업영역 단위로 권한을 제어하며, 항목별로는 타 조직 인원에게 권한을 줄 때 주로 사용

: 데이터 품질 검사, 버전 제어, 자동화된 배포, 모니터링 및 보안 측정값 구현, 확장성 확보, 재해복구, 협업 등을 위해 CI/CD 구축(Git 통합)

 


3) implement real-time intelligence (5.5H)

 

 

3-1) Microsoft Fabric을 사용하여 실시간 대시보드 만들기

: 타일 기반의 실시간 지원, KQL DB를 포함하는 Eventhouse를 원본으로 함.

: 타일을 생성할 때, KQL 쿼리를 지정함. 기본적인 표가 있는데 이를 수정하여 차트로 구성함.

: 필터도 만들 수 있다. 필터에도 KQL 쿼리를 통해 리스트를 넣어줘야 하고, 선택된 값을 의미하는 파라미터가 생성되면

  이를 각 차트의 where조건 절에 추가해준다.

: 화면의 새로고침 주기를 정할 수 있다.


4) implement a DW (6H)

 

 

4-1) Microsoft Fabric에서 데이터 웨어하우스 시작

: CREATE TABLE AS CLONE OF T-SQL을 통해 복제본을 만들어 테스트하는 역할로 사용

: 보고 도구에 연결이 용이하며, 다차원 분석을 위한 스타 스키마 혹은 스노우플레이크 스키마로 구축

 

4-2) Microsoft Fabric 데이터 웨어하우스에 데이터 로드

: 수집은 중앙 스토리지로의 통합을 의미하고, 로딩은 분석을 위한 최종 목표로의 이동을 의미한다.

: 로딩 작업이 성능에 영향을 주는 상황을 막고 싶을 때 스테이징 레이어를 사용할 수 있다.

: 초기 적재 후에는 증분 로드한다.

: surrogate key, business key

: SCD(Slow Change Data) - 차원 데이터의 느린 변경에 대응하는 방식

  참고로 디멘젼 테이블들은 변경이 일어나지 않도록 관리가 필요하다.

  [유형 6가지]

  1) 기존 데이터를 덮어쓰고 기록을 유지하지 않는 경우 (Update)

  2) 변경에 대한 새 레코드를 추가하고 지정된 자연 키에 대한 전체 기록을 유지하는 경우 (데이터의 유효기간을 관리)

       validFrom, validTo, IsActive 열 등으로 관리

IF EXISTS (SELECT 1 FROM Dim_Products WHERE SourceKey = @ProductID AND IsActive = 'True')
BEGIN
    -- Existing product record
    UPDATE Dim_Products
    SET ValidTo = GETDATE(), IsActive = 'False'
    WHERE SourceKey = @ProductID 
        AND IsActive = 'True';
END
ELSE
BEGIN
    -- New product record
    INSERT INTO Dim_Products (SourceKey, ProductName, StartDate, EndDate, IsActive)
    VALUES (@ProductID, @ProductName, GETDATE(), '9999-12-31', 'True');
END

  3) 새 열로 기록이 추가되는 경우

  4) 새 차원이 추가되는 경우

  5) 큰 차원의 특정 속성이 시간이 지남에 따라 변경되지만 차원의 크기가 커서 유형 2를 사용할 수 없는 경우

  6) 유형 2와 3의 조합

: 파이프라인을 통해 로딩을 진행하며, 보통 데이터 복사를 사용하나, 파이프라인 활동 추가, 시작할 작업 선택 옵션도 있다.

: 기타 데이터 로드 방법

  [Copy문 사용 - Storage에 메타가 같은 파일이 여러개 존재하는 경우 사용]

-- csv 경우
COPY INTO my_table
FROM 'https://myaccount.blob.core.windows.net/myblobcontainer/folder0/*.csv, https://myaccount.blob.core.windows.net/myblobcontainer/folder1/'
WITH (
    FILE_TYPE = 'CSV',
    CREDENTIAL=(IDENTITY= 'Shared Access Signature', SECRET='<Your_SAS_Token>')
    FIELDTERMINATOR = '|'
)

-- parquet 경우
COPY INTO test_parquet
FROM 'https://myaccount.blob.core.windows.net/myblobcontainer/folder1/*.parquet'
WITH (
    CREDENTIAL=(IDENTITY= 'Shared Access Signature', SECRET='<Your_SAS_Token>')
)

 

 [CTAS, INSERT 구문 사용 - 다른 웨어하우스나 레이크하우스에서 로드]

  1) CREATE TABLE AS SELECT ~ : 새 테이블을 생성하고 옮길 때

  2) INSERT ... SELECT ~ : 이미 존재하는 테이블에 데이터를 추가할 때

: Data Flow Gen2는 비 엔지니어들에게 좋은 도구가 될 수 있다. Copilot도 함께 사용한다.

: 부하 볼륨 및 빈도, 거버넌스, 데이터 매핑, 종속성, 스크립트 디자인 

 

4-3) Microsoft Fabric에서 데이터 웨어하우스 쿼리

: 분석을 위한 쿼리 예시

SELECT  ProductCategory,
        ProductName,
        ListPrice,
        ROW_NUMBER() OVER
            (PARTITION BY ProductCategory ORDER BY ListPrice DESC) AS RowNumber,
        RANK() OVER
            (PARTITION BY ProductCategory ORDER BY ListPrice DESC) AS Rank,
        DENSE_RANK() OVER
            (PARTITION BY ProductCategory ORDER BY ListPrice DESC) AS DenseRank,
        NTILE(4) OVER
            (PARTITION BY ProductCategory ORDER BY ListPrice DESC) AS Quartile
FROM dbo.DimProduct
ORDER BY ProductCategory;

: 쿼리 편집을 위해 SSMS를 사용할 수 있고, Entra ID로 로그인이 가능하다.

 

4-4) Microsoft Fabric 데이터 웨어하우스 모니터링

: DMV를 활용하여 연결/세션 및 요청 상태를 모니터하여 라이브 SQL 쿼리 수명 주기 인사이트 보기 가능

  활성 쿼리 수와 장기간 수행되는 쿼리 등을 알 수 있음.

  sys.dm_exec_connections(DW와 엔진 간 연결) / sessions(항목과 엔진간 인증 세션) / requests(세션 별 활성 요청)

  Connection 테이블을 중심으로 session은 session_id 컬럼으로 조인되고, request는 session_id, connection_id로 조인한다.

SELECT sessions.session_id, sessions.login_name,
    connections.client_net_address,
    requests.command, requests.start_time, requests.total_elapsed_time
FROM sys.dm_exec_connections AS connections
INNER JOIN sys.dm_exec_sessions AS sessions
    ON connections.session_id=sessions.session_id
INNER JOIN sys.dm_exec_requests AS requests
    ON requests.session_id = sessions.session_id
WHERE requests.status = 'running'
    AND requests.database_id = DB_ID()
ORDER BY requests.total_elapsed_time DESC

: 실행 쿼리 분석

  queryinsights.exec_requests_history: 완료된 각 SQL 쿼리의 세부 정보입니다

SELECT start_time, login_name, command
FROM queryinsights.exec_requests_history 
WHERE start_time >= DATEADD(MINUTE, -60, GETUTCDATE())

  queryinsights.long_running_queries: 쿼리 실행 시간의 세부 정보입니다.

SELECT last_run_command, number_of_runs, median_total_elapsed_time_ms, last_run_start_time
FROM queryinsights.long_running_queries
WHERE number_of_runs > 1
ORDER BY median_total_elapsed_time_ms DESC;

  queryinsights.frequently_run_queries: 자주 실행되는 쿼리에 대한 세부 정보입니다.

SELECT last_run_command, number_of_runs, number_of_successful_runs, number_of_failed_runs
FROM queryinsights.frequently_run_queries
ORDER BY number_of_runs DESC;

: MS Fabric Capacity Metrics 앱 - 각 쿼리

  

 

4-5) Microsoft Fabric 데이터 웨어하우스 보호

: 데이터 보호를 위해 네트워크는 TLS 암호화 진행, 전송 중 및 미사용 데이터를 보호하기 위한 Azure Storage 서비스 암호화 진행

: Monitor와 Log Analytics로 엑세스 감사, MFA, Entra ID 기반 엑세스 RBAC 관리

: 항목 권한의 ReadData는 테이블/뷰 스키마에 한하여 읽을 수 있고, ReadAll은 OneLake의 Parquet까지 보는 것

: DDM (동적 데이터 마스킹) - 웨어하우스의 테이블에 대하여 컬럼 특성 정의

  default() = 전체 마스킹, email() = 메일주소, partial(prefix_padding, padding_string, suffix_padding) = 특정 텍스트,

  random(low,high) = 임의 난수화 

-- For Email
ALTER TABLE Customers
ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()');

-- For PhoneNumber
ALTER TABLE Customers
ALTER COLUMN PhoneNumber ADD MASKED WITH (FUNCTION = 'partial(0,"XXX-XXX-",4)');

-- For CreditCardNumber
ALTER TABLE Customers
ALTER COLUMN CreditCardNumber ADD MASKED WITH (FUNCTION = 'partial(0,"XXXX-XXXX-XXXX-",4)');

 

: Row-Level Security(RLS) - 

--Create a schema
CREATE SCHEMA [Sec];  
GO  

--Create the filter predicate
CREATE FUNCTION sec.tvf_SecurityPredicatebyTenant(@TenantName AS NVARCHAR(10))  
    RETURNS TABLE  
WITH SCHEMABINDING  
AS  
    RETURN	SELECT 1 AS result
			WHERE @TenantName = USER_NAME() OR USER_NAME() = 'tenantAdmin@contoso.com';  
GO

--Create security policy and add the filter predicate
CREATE SECURITY POLICY sec.SalesPolicy  
ADD FILTER PREDICATE sec.tvf_SecurityPredicatebyTenant(TenantName) ON [dbo].[Sales]
WITH (STATE = ON);  
GO
더보기

1단계: 스키마 생성 (CREATE SCHEMA)

SQL
 
CREATE SCHEMA [Sec];
GO
  • 설명: Sec라는 이름의 새로운 스키마(Schema)를 만듭니다. 스키마는 데이터베이스 객체(테이블, 함수, 정책 등)를 논리적으로 그룹화하는 폴더와 같은 역할을 합니다. 여기서는 보안과 관련된 함수나 정책을 별도로 관리하기 위해 Sec라는 이름의 스키마를 생성한 것입니다.

2단계: 필터 함수(Predicate Function) 정의

SQL
 
CREATE FUNCTION sec.tvf_SecurityPredicatebyTenant(@TenantName AS NVARCHAR(10))
    RETURNS TABLE
WITH SCHEMABINDING
AS
    RETURN	SELECT 1 AS result
			WHERE @TenantName = USER_NAME() OR USER_NAME() = 'tenantAdmin@contoso.com';
GO

이 코드가 RLS의 핵심 로직입니다.

  • CREATE FUNCTION sec.tvf_SecurityPredicatebyTenant(...): Sec 스키마 안에 tvf_SecurityPredicatebyTenant라는 이름의 함수를 만듭니다. 이 함수는 테이블처럼 결과를 반환하는 '테이블 반환 함수(Table-Valued Function)'입니다.
  • @TenantName AS NVARCHAR(10): 이 함수는 TenantName이라는 파라미터를 입력받습니다. 이 값은 나중에 Sales 테이블의 TenantName 컬럼에서 오게 됩니다.
  • RETURNS TABLE: 이 함수가 테이블 형태의 결과를 반환함을 의미합니다.
  • WITH SCHEMABINDING: 이 함수가 참조하는 테이블의 스키마를 변경하지 못하도록 잠그는 중요한 옵션입니다. 보안 정책의 무결성을 지켜줍니다.
  • RETURN SELECT 1 AS result WHERE ...: 이 함수의 핵심 필터링 조건입니다.
    • @TenantName = USER_NAME(): Sales 테이블의 TenantName 컬럼 값이 현재 로그인한 사용자의 이름(USER_NAME())과 같은 경우에만 result로 1을 반환합니다. 즉, 사용자는 자신의 테넌트 데이터만 볼 수 있습니다.
    • OR USER_NAME() = 'tenantAdmin@contoso.com': 만약 로그인한 사용자가 tenantAdmin@contoso.com이라면, 위 조건과 상관없이 무조건 result로 1을 반환합니다. 이 사용자는 모든 테넌트의 데이터를 볼 수 있는 관리자 역할을 합니다.

3단계: 보안 정책 생성 및 적용

SQL
 
CREATE SECURITY POLICY sec.SalesPolicy
ADD FILTER PREDICATE sec.tvf_SecurityPredicatebyTenant(TenantName) ON [dbo].[Sales]
WITH (STATE = ON);
GO
  • CREATE SECURITY POLICY sec.SalesPolicy: SalesPolicy라는 이름의 보안 정책을 만듭니다.
  • ADD FILTER PREDICATE ... ON [dbo].[Sales]: dbo.Sales 테이블에 필터 규칙을 추가하겠다는 의미입니다.
  • sec.tvf_SecurityPredicatebyTenant(TenantName): 위에서 만든 tvf_SecurityPredicatebyTenant 함수를 필터로 사용합니다. Sales 테이블의 TenantName 컬럼 값을 함수의 @TenantName 파라미터로 전달하여 각 행마다 함수를 실행합니다.
  • WITH (STATE = ON): 이 보안 정책을 즉시 활성화합니다.

종합적인 작동 시나리오

  1. 어떤 사용자가 SELECT * FROM dbo.Sales 쿼리를 실행합니다.
  2. Azure Fabric은 SalesPolicy 보안 정책이 활성화된 것을 확인합니다.
  3. Sales 테이블의 모든 행을 하나씩 스캔하면서, 각 행의 TenantName 컬럼 값을 tvf_SecurityPredicatebyTenant 함수에 넘겨줍니다.
  4. 함수는 해당 행의 TenantName 값이 현재 사용자 이름과 같거나, 혹은 현재 사용자가 'tenantAdmin@contoso.com'인지를 검사합니다.
  5. 함수가 1을 반환하는 행들만 최종적으로 사용자에게 보여줍니다.

예시:

  • 사용자 'userA'가 로그인하면 Sales 테이블에서 TenantName이 'userA'인 행들만 보게 됩니다.
  • 사용자 'tenantAdmin@contoso.com'이 로그인하면 Sales 테이블의 모든 행을 볼 수 있습니다.

: Column-level Security(CLS) - 열 단위 보안

-- Create roles
CREATE ROLE Doctor AUTHORIZATION dbo;
CREATE ROLE Nurse AUTHORIZATION dbo;
CREATE ROLE Receptionist AUTHORIZATION dbo;
CREATE ROLE Patient AUTHORIZATION dbo;
GO

-- Grant SELECT on all columns to all roles
GRANT SELECT ON dbo.Patients TO Doctor;
GRANT SELECT ON dbo.Patients TO Nurse;
GRANT SELECT ON dbo.Patients TO Receptionist;
GRANT SELECT ON dbo.Patients TO Patient;
GO

-- Deny SELECT on the MedicalHistory column to the Receptionist and Patient roles
DENY SELECT ON dbo.Patients (MedicalHistory) TO Receptionist;
DENY SELECT ON dbo.Patients (MedicalHistory) TO Patient;
GO

5) Management a Fabric env(3h)

 

 

5-1) Microsoft Fabric에서 CI/CD(연속 통합 및 지속적인 업데이트) 구현

: 배포 옵션은 구조와 메타데이터만 옮길 뿐, 데이터 및 새로고침 설정 같은 것들을 옮기지 않는다.

: Gen2 Flow는 옮겨지지만, Gen1 Flow는 옮기지 않는다.

5-2) Microsoft Fabric에서 활동 모니터링

5-3) Microsoft Fabric에서 안전한 데이터 액세스

: 작업영역, 항목, 컴퓨팅 및 세분화 권한, OneLake 접속 제어

: 권한 관리 시 추가 권한을 통해 SQL Endpoint나 Spark 접속 권한을 부여하면 데이터 원본에 대한 엑세스 권한이 부여됨.

5-4) Microsoft Fabric 환경 관리

: 패브릭 아키텍처

  도메인, 작업영역, 항목으로 구성

  각 항목은 고유 기능을 가지며, 모두 SaaS로 OneLake 위에서 동작

: 관리자의 역할 

  관리센터, Purview 및 보안, Entra ID, PowerShell, 관리API 등에 익숙해야 하며, M365, PowerPlatform과 협력한다.

  데이터 게이트웨이, RBAC 등을 통해 보안 관리하며, 모니터링을 통해 데이터 권한 정책을 수립, 리소스 최적화, 용량 조절

  보증 항목의 지정, 데이터 계보 추적, 감사 로그, 카탈로그 관리, 정보보호 정책 수립, 

  https://learn.microsoft.com/ko-kr/fabric/governance/metadata-scanning-run API 검사를 통해 항목 컨디션 관리

: 보안 및 거버넌스 기능

: 분석 기능

: 배포 및 라이선스 옵션

  


덤프 풀이 중 개념 정리

 

[ShortCut Cache]

40번 문제 : Fabric의 Shortcut 캐시는 24시간동안만 지속된다.

                   원천으로의 마지막 접근이 24시간 이상되면 새로 읽는다.

50번 문제 : 캐시는 1GB 미만 데이터에만 적용된다.

 

[Delta Lake의 spark 구문]

48번 문제 : Delata Lake의 조건부 머지 구문

(targeyDF
   .merge(sourceDF,"sourceDF.Key","targetDF.Key")
   	  .whenMatchedUpdate(
        set = {"targetDF.LastModified":"sourceDF.LastModified"}
      )
      .whenNotMatchedInsert(
      	values = {"targetDF.Key":"sourceDF.Key",
        		  "targetDF.LastModified":"sourceDF.LastModified",
                  "targetDF.Status":"sourceDF.Status"
                  }
      )
      .whenNotMatchedBySourceUpdate(
        condition="targetDF.LastModified > (current_date() - INTERVAL '7' DAY)",
        set = {"targetDF.Status":"'inactive'"}
      )
      .execute()
)

'''
whenMatchedUpdate (데이터 업데이트)
조건: 소스(sourceDF)와 타겟(targetDF) 테이블에 동일한 Key가 존재할 경우.
동작: 타겟 테이블의 LastModified 컬럼 값을 소스 테이블의 값으로 덮어씁니다. 즉, 기존 데이터의 특정 필드를 최신 정보로 업데이트합니다.

whenNotMatchedInsert (신규 데이터 추가)
조건: 소스 테이블에는 Key가 있지만 타겟 테이블에는 없을 경우.
동작: 소스 테이블의 Key, LastModified, Status 값을 타겟 테이블에 새로운 레코드로 추가(Insert)합니다.

whenNotMatchedBySourceUpdate (소프트 삭제)
조건: 타겟 테이블에는 Key가 있지만 소스 테이블에는 없을 경우. 단, 타겟 레코드의 LastModified 값이 현재 날짜로부터 7일 이내인 경우에만 이 조건이 적용됩니다.
동작: 해당 타겟 레코드의 Status 컬럼을 'inactive'로 업데이트합니다. 이는 데이터를 물리적으로 삭제하는 대신 비활성 상태로 표시하는 소프트 삭제(Soft Delete) 방식입니다. 소스에서 제거된 지 얼마 안 된 데이터만 처리하려는 의도입니다.
'''

                   

[KQL 쿼리]

54번 문제 : window 함수, extend 절 구문 질의

 

[DW의 SQL 쿼리]

RLS, CLS 등을 적용하는 순서

1) 스키마 생성, 2) 펑션생성(WITH SCHEMABINDING), 3) SECURITY POLICY 생성, 4) ADD Filter PREDICATE

 

[DevOps 관리]

69번 문제 - CI/CD 권한 인증 방식 (Entra ID를 사용하지 않고, 별도 서비스 주체로 인증함)

  • CI/CD 파이프라인에서 API를 호출하는 것과 같은 자동화된 서버 간 상호 작용의 경우, 사용자 자격 증명(사용자 이름/암호)을 사용하는 것은 안전하지 않으며 나쁜 관행입니다.
  • 서비스 주체는 애플리케이션이나 서비스를 나타내는 Microsoft Entra ID의 비인간 보안 ID입니다. 서비스 주체에 Fabric API에 액세스할 수 있는 특정하고 제한된 권한을 부여할 수 있습니다. 그러면 Azure DevOps 파이프라인은 사용자 암호 없이 서비스 주체의 ID와 비밀 키(또는 인증서)를 사용하여 안전하게 인증할 수 있습니다.

 

'Data Engineering > Cloud_Azure' 카테고리의 다른 글

DataBricks - Data Engineer Associate (취득완료)  (0) 2025.08.01
AZ-104 (준비중)  (0) 2025.05.02
AZ-900 (취득완료)  (1) 2025.03.13