본문 바로가기

CDS View(Core Data Service)/Core Data Service 기초

CDS View Association

ABAP Data Dictionary에서는 다양한 데이터베이스 테이블 간의 연결을 외래 키(Foreign Key) 관계를 사용하여 정의합니다. 이러한 테이블들은 또한 응용 프로그래밍의 주요 데이터 원본 역할을 합니다. 따라서 외래 키 관계를 사용하여 연결된 여러 데이터베이스 테이블을 쿼리하는 것은 종종 복잡한 조인 조건을 작성해야 하는 작업을 의미합니다.

그러나 특정 비즈니스 시나리오에서는 이러한 조인 조건 작성이 복잡한 SQL 쿼리를 생성하므로 응용 프로그램 개발자가 비즈니스 작업을 수행하는 데 어렵고 오류가 발생할 수 있습니다. 또한 이러한 조인 조건의 재사용도 어려워 개발 노력이 상당히 필요합니다. 이러한 제한 사항을 극복하기 위해 CDS(contextual data structure)의 DML(data manipulation language)은 CDS 엔티티 간의 관계를 정의하기 위한 지원을 확장하였습니다. CDS는 이러한 관계를 일급 시민(first-class citizen : sap 설명)으로 취급하여 CDS 엔티티 간의 관계를 정의하는 데 도움을 주어 다른 CDS 뷰 내에서 CDS 연관을 더 쉽게 읽고 사용할 수 있도록 합니다.

아래 그림에서 보여지는 대로, 연관 관계(association)을 사용하면 서로 다른 엔티티 간의 관계를 정의할 수 있으며, 이 관계는 최종적으로 데이터베이스 수준에서 조인으로 변환됩니다. 연관의 구문은 다른 엔티티 간의 관계를 간단하고 명확하게 유지합니다. 경로 표현식(path expressions)을 사용하여 가독성을 향상시키며, 이를 통해 기반이 되는 데이터 모델을 노출합니다. 데이터의 원본 및 필터 조건이 어떻게 적용되는지를 WHERE 또는 CASE 표현식을 사용할 때보다 쉽게 읽을 수 있습니다.

 

연관(associations)과 조인(joins)의 구문은 다르게 보일 수 있지만, 데이터베이스 수준에서는 최종적으로 모두 데이터베이스 수준의 조인으로 변환됩니다. 그러나 아래 Types of Associations 주제에서 다룰 Exposed Association의 경우, 연관된 데이터 소스에서 데이터를 요청하는 경우에만 조인이 실행됩니다. 이 접근 방식은 필요에 따라 조인되는 것으로, 성능을 향상시키는 데 도움이 될 수 있습니다. 이 접근 방식은 "조인 온 디맨드(join on-demand)"라고도 불립니다.


Defining Association


연관(associations)은 CDS 엔티티 내에서 키워드인 "ASSOCIATION TO"를 사용하여 정의됩니다. 이후에는 대상 데이터 소스와 엔티티 간의 관계를 지정하는 "ON" 조건이 따라옵니다. "ON" 조건을 지정하는 것은 조인과 유사하며, 조인을 연관으로 리팩토링하는 것이 쉬워집니다. 추가적으로, 대상 데이터 소스에 대해 카디널리티(cardinality)와 별칭(alias name)을 "AS" 키워드로 제공할 수도 있지만, 이는 선택 사항입니다.

연관(associations)은 컬럼 또는 테이블 이름이 사용될 수 있는 모든 곳에서 사용할 수 있습니다.

문법은 다음과 같습니다.

….ASSOCIATION [MIN….MAX] TO TARGET [ AS _ASSOC ]
ON COND_EXP
[WITH DEFAULT FILTER COND_EXP]

아래에 제시된 예제에서는 두 개의 CDS 엔티티인 SFLIGHT와 SCARR 간의 관계를 설정하는 간단한 연관(association)이 정의되었습니다.

@AbapCatalog.sqlViewName: 'ZCDS_EX_SQL_21'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'CDS using simple associations'
define view ZCDS_EXAMPLE_21
as select from sflight
association [0..1] to scarr as _scarr
on sflight.carrid = _scarr.carrid
{
key sflight.carrid,
key sflight.connid,
key sflight.fldate,
_scarr.carrname
}

연관(association)의 구문은 내부 조인(inner join)의 구문과 다르지만, 연관을 사용하여 관계를 정의하기 위해 CDS 정의에서 FROM 절 이후에 키워드 "ASSOCIATION TO"가 필요합니다. 이는 단순히 조인을 나타내는 것으로, 데이터베이스 수준에서의 기술적인 변경은 고려되지 않습니다. 동일한 내용은 ABAP 사전에서 확인할 수 있으며, 이를 위해서는 Menu ● Extras ● Create Statement로 이동하면 됩니다.

inner join을 사용하는 경우, 요소 목록에서 데이터 소스의 필드에 접근할 때 non-unique 필드에 대해서만 데이터 소스의 이름이 필수적입니다. 그러나 연관(association)을 사용하는 경우, 대상 연관의 모든 필드에 대해 데이터 소스의 이름이 필수적입니다.

inner join과 연관의 차이점 중 하나입니다. 연관을 통해 대상 연관의 모든 필드에 접근할 때 데이터 소스의 이름을 지정해야 하며, 이는 모든 필드에 적용됩니다.


Cardinality


연관 관계를 정의할 때, 대상 소스의 Cardinality를 정의하기 위해 [min..max] 값이 지정될 수 있습니다. 최소 및 최대 값은 0 및 별표 (*)를 포함한 양의 정수여야 하며, 이 값들은 대괄호 내에 지정되어야 합니다. 대괄호도 구문의 일부입니다.

만약 연관 관계에 대한 기수가 명시적으로 정의되지 않은 경우, 기본 기수로 [0..1]이 암묵적으로 사용됩니다.

아래 표에는 Mininum & Maximum 값을 구체화할 때 적용되는 규칙이 리스트 업 되어있습니다.

Valeus Required Default Value Forbidden Value
Min Optional 0 *
Max Mandatory 1 0

 

몇몇의 경우, CDS 뷰 정의 할 때, 연관 관계의 사용이 제한이 되어있을 떄가 있어서, Syntax Error나 Warining을 이끌 때가 있는데, 해당 경우는 아래 표에 정의되어 있습니다.

카디널리티가 1보다 큰 값을 가지도록 지정하여 사용되는 연관 관계 Type Message
In the WHERE condition while defining
CDS view
Error Value set associations are not
allowed here
Outside aggregate expressions Warning Associations <..> can influence the
cardinality of the resulting set

 

아래 코드의 예시에서 연관 관계 sflight는 데이터 소스 SPFLI와 SFLIGHT 간의 관계를 설정합니다. 또한 값 [0..*]은 대상 데이터 소스의 기수를 정의합니다. 이 경우, 이 값은 값은 대상 데이터 소스에서 더 많은 레코드가 예상합니다.

@AbapCatalog.sqlViewName: 'ZCDS_EX_SQL_22'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'CDS view using associations'
define view ZCDS_EXAMPLE_22
   as select from spfli
   association [0..*] to sflight as _sflight on spfli.carrid = _sflight.carrid
                                            and spfli.connid = _sflight.connid
{
    key carrid,
    key connid,
    _sflight
}



시나리오 1에서는 대상 데이터 소스의 필드가 요소 목록에서 액세스되지 않는다고 가정하면, 결과 집합은 카디널리티가 [0..*]로 정의되었지만 소스 및 대상 데이터 소스에서 [1..1] 레코드를 반환해야 합니다.

시나리오 2에서 대상 데이터 소스의 FLDATE 필드가 요소 목록에서 액세스되는 경우, 결과 집합의 카디널리티가 수정되어 [1..*] 레코드를 반환하도록 변경됩니다.


Types of Associations


CDS 연관관계 유형은 크게는 두 가지 카테고리로 분류될 수 있습니다.

■ Ad-hoc associations
■ Exposed associations

■ Ad-hoc associations
데이터 정의의 요소 목록에서 연관된 테이블이나 뷰의 개별 필드에 직접 액세스하는 연관 관계를 "임시 연관 관계(ad-hoc association)"라고 합니다(아래 코드). 이러한 연관 관계는 즉시 데이터베이스로 전송되는 SQL 생성 문에서 조인 절로 변환됩니다. 이는 그림 1에서 보여지는 것과 같습니다.

@AbapCatalog.sqlViewName: 'ZCDS_EX_SQL_23'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'CDS view using exposed associations'
define view ZCDS_EXAMPLE_23
    as select from sflight
       association [0..*] to sbook as _sbook
                                   on sflight.carrid = _sbook.carrid
                                  and sflight.connid = _sbook.connid
                                  and sflight.fldate = _sbook.fldate
       association [0..1] to spfli as _spfli
                                   on sflight.carrid = _spfli.carrid
                                  and sflight.connid = _spfli.connid
{
  key carrid,
  key connid,
  key fldate,
--Ad-doc association as individual fields are accessed from the data source sbook
  _sbook.bookid,
  _sbook.customid,
--Ad-doc association as individual fields are accessed from the data source spfli
  _spfli.airpto,
  _spfli.airpfrom
}

아래 그림은 ad-hoc 연관의 결과를 보여줍니다.

 

■ Exposed associations

CDS 뷰는 연관된 데이터 소스의 개별 필드를 통해 처리하는 대신, Element List에서 전체 연관 관계 이름을 단일 요소로 간주할 수 있습니다. 이를 "exposed association"라고 합니다(아래 코드참조). 이 경우, SQL 생성 문은 즉시 연관된 데이터 소스를 조인하지 않습니다. 실제 조인은 소비자가 관련 데이터 소스의 개별 필드에 액세스할 때에만 생성됩니다. 이는 그림 1에서 보여지는 것과 같습니다. 이러한 시나리오는 조인 온디맨드(join on-demand)로 간주되며, 연관된 데이터 소스에서 어떤 정보를 원하는지 소비자가 결정할 때까지 실제 데이터 소스의 조인이 연기될 수 있으므로 성능 향상을 제공할 수 있습니다.

@AbapCatalog.sqlViewName: 'ZCDS_EX_SQL_24'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'CDS viewusingexposedassociations'
define viewZCDS_EXAMPLE_24
    as select from sflight
    association [0..*] to sbook as_sbook 
    			on sflight.carrid = _sbook.carrid
				and sflight.connid = _sbook.connid
				and sflight.fldate = _sbook.fldate
	association [0..1] to spfli as_spfli 
    			on sflight.carrid = _spfli.carrid
				and sflight.connid = _spfli.connid
{
	key carrid,
	key connid,
	key fldate,
--Exposed associationastheentiredatasourceisaccessed
	_sbook,
	_spfli
}

그림 1과 같이 노출된 연관 관계 (_sbook 및 _spfli)에서는 소비자가 요청하기 전까지 결과 집합에 포함되지 않습니다.
또한 그림 2에 나와 있는대로, Create SQL 문에서도 소비자가 요청하기 전까지 데이터베이스 테이블에 조인이 생성되지 않습니다. 이것은 일반적으로 요청에 따른 조인(join on demand)으로 알려져 있습니다.

그림1
그림2

 

반응형