CDS Association

CDS view Association 引入的缘由

CDS 视图不会被业务用户直接访问,而是会被 ABAP 程序、Fiori 应用程序或 BI 前端工具使用。假设在 5 个不同的表上使用 JOINS 创建了 CDS 视图,则每次触发此 CDS 视图时都会执行此 JOIN 条件。即使业务用户只查看 2 个表中的字段,但 CDS 视图将首先运行所有 5 个表的连接条件,并且用户查看的字段数量无关紧要。 这种基于 JOIN 的 SQL 概念,在用户仅查看部分数据的情况下,会导致从 CDS 视图中提取数据的性能延迟。 为了克服这个问题,SAP 对这种获取数据的 SQL 方式进行了增强,引入了  Association的概念。   

association 也是一种 join,可以根据 join 条件从多个表中获取数据,但这些是按需连接,即它们只会在用户访问所需数据时触发。 例如 CDS 视图配置了 4 个关联,而用户仅获取 2 个表的数据,其他 2 个表上的关联将不会被触发,系统将快速返回结果。因此同常规 SQL JOINS 相比,association 的性能更优。

INNER JOIN 和 Association 的区别

INNER JOIN场景下表 Join 一定会发生,无论被 Join 的表的字段在当前事务里是否会被读取,这造成了不必要的性能开销。Association场景下只有查询用到Association的表时才会关联(left outer join)。

           

`

Association中的Cardinality

基数Cardinality是源表和关联表(或CDS视图)之间的关系,它以[MIN …MAX]的形式包含在关联的定义中。(只声明了目标基数)。它主要用于记录数据模型的语义。它不会在运行时进行验证,但会产生语法检查警告。

注意:仅为目标(关联的)表/视图定义基数。[0 . .1] =表示目标的基数可以是0或1。同样[0 . .N]表示目标表/视图基数可以从0到N。 ..的两边并不是源表和关联表的数量。

在关键字关联之后指定基数,但它并不是必需显式定义的。如果没有显式定义基数,则有一个隐式的基数[0..1]。

<think>我们正在讨论ABAP CDS视图中的关联基数(cardinality)问题,特别是[0..1]的用法。 根据用户的问题,我们需要解释在ABAP CDS视图中如何定义和使用基数为[0..1]的关联。 首先,回顾一下关联(association)在CDS视图中的作用:它用于定义两个实体(表或视图)之间的关系。基数(cardinality)用于描述这种关系的数量特征。 基数表示法: [min..max] 其中min表示最小出现次数,max表示最大出现次数。 常见的基数有: [1]:必须存在且仅有一个 [0..1]:可选,最多一个(即0个或1个) [0..*]:可选,可以多个 [1..*]:必须存在至少一个,可以多个 用户询问的是[0..1]的用法。这种基数表示关联的目标实体(被关联的实体)在源实体(关联所在的实体)中可能不存在(即0),或者最多存在一个(即1)。 使用场景举例: - 当我们有一个主表(如销售订单头)和一个可选的明细表(比如特殊折扣表,不是每个订单都有折扣)时,我们可以使用[0..1]的关联。 - 另一个例子是员工和经理的关系:每个员工最多有一个直接经理(经理也是员工),但有些员工可能没有经理(比如CEO),那么员工和经理之间的关联基数就是[0..1]。 在CDS视图中定义关联的语法: association [min..max] to <target> as <alias> on <condition> 例如,假设我们有两个CDS视图实体: - ZI_SalesOrderHeader:销售订单头 - ZI_SpecialDiscount:特殊折扣(只有部分订单有) 我们可以在ZI_SalesOrderHeader中定义一个指向ZI_SpecialDiscount的关联,基数为[0..1]: define view ZI_SalesOrderHeader as select from sord_head as header association [0..1] to ZI_SpecialDiscount as _Discount on header.sales_order_id = _Discount.sales_order_id { key header.sales_order_id, header.buyer_id, header.payment_status, // 关联暴露为字段(使用冒号) _Discount } 注意:在CDS视图中,关联本身不会自动成为结果集的一部分,除非我们显式地将其包含在字段列表中(如上面的`_Discount`)。在字段列表中,我们可以写关联的名称(如`_Discount`)来暴露整个关联结构(在结果中表现为一个内表,但由于基数是[0..1],所以实际上这个内表最多只有一行)。在Open SQL中访问时,我们可以使用`_Discount`来获取关联的字段。 在ABAP程序中,我们可以这样使用: SELECT sales_order_id, buyer_id, payment_status, \_Discount-SpecialDiscountValue // 注意:这里使用反斜杠转义,因为字段名包含连字符 FROM ZI_SalesOrderHeader INTO TABLE @DATA(lt_result). 但是,注意在Open SQL中访问关联字段时,需要使用转义字符(反斜杠)来引用关联的字段,因为关联字段名中可能包含特殊字符(如连字符)。另外,由于基数是[0..1],所以当没有折扣时,关联字段(如`_Discount-SpecialDiscountValue`)将为NULL。 重要:在定义关联时,我们还可以使用`$projection`关键字来引用当前视图的字段,以避免歧义。例如: on $projection.sales_order_id = _Discount.sales_order_id 但是,在上面的例子中,我们直接使用了数据源别名(header)来引用字段,这在简单视图中也是可以的。 另外,基数的设置对于CDS视图的行为和优化器都有影响。设置正确的基数可以帮助数据库优化查询计划。 现在,我们来生成相关问题。</think>### ABAP CDS关联基数`[0..1]`详解 在ABAP CDS视图中,关联基数`[0..1]`用于定义**可选的一对零或一关系**。这种基数表示源实体(定义关联的视图)中的每个条目最多关联目标实体的一个条目,也可能完全不关联(即关联结果可为空)。 #### 核心特性 1. **可选性** 当目标实体无匹配记录时,关联字段返回`NULL`值而非报错 $$ \text{关联结果} = \begin{cases} \text{目标记录} & \text{匹配存在} \\ \text{NULL} & \text{无匹配} \end{cases} $$ 2. **唯一性** 源实体的每个条目最多关联目标实体的一个条目 $$ \forall s \in \text{Source}, \space |\{ t \in \text{Target} \mid \text{关联条件}(s,t) \}| \leq 1 $$ #### 语法示例 ```abap define view ZI_Order_With_Optional_Info as select from sord_head as Order association [0..1] to ZI_Order_Notes as _Note // 基数[0..1] on Order.order_id = _Note.order_id { key Order.order_id, Order.order_date, _Note.comment // 可选字段 } ``` #### 典型应用场景 1. **可选主数据扩展** 订单头表关联可选订单备注(部分订单无备注) ```sql SELECT order_id, \_Note-comment FROM ZI_Order_With_Optional_Info WHERE order_date > '20230101' ``` → 无备注的订单返回`NULL`[^1] 2. **条件性层级关系** 员工表关联经理(非管理人员无经理记录) ```abap association [0..1] to ZI_Employee as _Manager on $projection.manager_id = _Manager.employee_id ``` 3. **软删除数据处理** 关联带删除标志的表,仅关联未删除记录 ```abap association [0..1] to ZI_Product as _Product on $projection.product_id = _Product.product_id and _Product.is_deleted = ' ' ``` #### 性能影响 - 优于`[0..*]`基数:数据库优化器更易生成高效LEFT OUTER JOIN计划 - 避免N+1查询:通过CDS视图单次SQL完成数据获取 - 强制使用`ON`条件:无关联条件将导致编译错误 > ⚠️ **注意**:实际基数需与数据模型一致,错误设置可能导致结果不准确或性能下降。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SAP_太亿真仙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值