簇表BSEG和透明表BSID/BSAD

Posted xiaomici

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了簇表BSEG和透明表BSID/BSAD相关的知识,希望对你有一定的参考价值。

先看个链接解释:池表,簇表,透明表

BSEG属于表簇RFBLG。

看它的where used 能看到里面有好多簇表。

 为啥BSEG是个簇表? 这个俺不知道,听说是因为之前Oracle有限制,只能处理一定列数的表,但是BSEG又是个特别多列的表,所以只能把它在数据库层进行压缩?

簇表是一个特殊的表类型,它的数据不是直接存储的,而是存在表簇里。以压缩的格式存储,压缩和解压都在应用层实现。表簇里有好多类似的表,这样允许冗余数据的高性能存储?(待究)这就导致它不能用OpenSQL的一些join语句了。

在这里能看到簇表的表簇。也就是说簇表BSEG的数据实际存储在表簇RFBLG里。簇表一般都有很多列数据,BSEG有300多列。

 

但是表簇里RFBLG就只有很少的列。 看Key对应的都是5个,但是BSEG是BUZID,表簇里是PAGENO。对于不是Key的列字段呢,都被压缩放进VARDATA里了。

 

而作为一个簇表,不能建次级索引,但是又得经常基于它里面的一些字段进行查询,所以建了这些索引表:BSAK, BSIK, BSAS, BSIS, BSAD, BSID

让你能在不知道凭证编号,或者公司代码,只知道总账账号的时候能查询到BSEG的数据。

通过下面这个表关系能看到。这个表关系还是很好的。我就是找不到电子版的了。

这个表关系图里面通过看表前缀和后缀,能看出来,BSI表示open items BSA表示cleared items。

后缀是账户类型字段KOART,K表示Kreditor->Vendor, D表示Debtor->Customer , S表示GL。

这些索引表是为了为了提供直接访问BSEG的索引,这个BSEG包含了AR,AP,GL的数据,但是如果我们想从公司和供应商编号找数据,那就到BSIK或者BSAK去找。如果知道公司和总账账号,那就去BSIS或者BSAS找。

从BW的角度去看,比如AR的数据源0FI_AR_4。应收账款就是从表BSID和BSAD来的。

 

 但是如果你去fb03,这些都是保存到BSEG的。

在没有 INNER JOIN 的选择中使用表 BSEG

【中文标题】在没有 INNER JOIN 的选择中使用表 BSEG【英文标题】:Using the table BSEG in a selection without INNER JOIN 【发布时间】:2021-11-19 15:04:41 【问题描述】:

我正在尝试使用以下代码从表 BSEG 中选择字段 KOART

CONSTANTS: lc_d TYPE c VALUE 'D'.
    SELECT k~bukrs,
         k~belnr,
         k~budat,
         k~gjahr,
         k~buzei,
         k~kunnr,
         i~banks,
         i~bankl,
         i~bankn
    FROM bsid AS k
    INNER JOIN knbk AS i ON k~kunnr EQ i~kunnr
*    INNER JOIN bseg
    INTO TABLE @DATA(lt_data_knbk)
    WHERE k~bukrs IN @so_bukrs
    AND k~budat IN @so_budat
    AND k~blart IN @so_blart
*    AND bseg~koart = @lc_d.

通常我会为表添加 Inner join 语法,但由于 bseg 是一个集群表,它不接受内部连接选项,因此我不能使用字段 koart

谁知道,我怎样才能把BSEG的KOART字段放在上面的选择中?

非常感谢您的热心帮助!

【问题讨论】:

【参考方案1】:

As explained by József Szikszai,在这个特定的用例中实际上不需要内部连接,因为表 BSID 无论如何只包含客户文档。

但如果这里必要的,那么您将有两种选择:

首先是切换到 SAP HANA 作为数据库后端,因为这样所有的集群表都将转换为常规表。由于 SAP 宣布他们将从 2027 年开始为支持其他数据库收取额外费用,并在 2030 年完全放弃对非 HANA 的支持,因此从长远来看,您将无法解决这个问题。但由于 HANA 转换涉及成本和规划工作,如果您今天面临这个问题,这可能不是一个严肃的选择。

当您在不可避免的 HANA 转换之前需要临时解决方案时,还有第二种选择。您可以使用带有FOR ALL ENTRIES 条件的第二次选择来解决此问题。

SELECT bukrs,
     belnr,
     budat,
     gjahr,
     buzei,
     kunnr,
  FROM bsid     
  INTO TABLE @DATA(lt_data_bsid)
  WHERE bukrs IN @so_bukrs
  AND budat IN @so_budat
  AND blart IN @so_blart.

IF lt_data_bsid IS NOT INITIAL.
  SELECT bukrs,
         belnr,
         gjahr,
         buzei
    FROM bseg
    INTO TABLE @DATA(lt_bseg)
    FOR ALL ENTRIES IN @lt_data_bsid
    WHERE bukrs = @lt_data_bsid-bukrs
      AND belnr = @lt_data_bsid-belnr
      AND gjahr = @lt_data_bsid-gjahr
      AND buzei = @lt_data_bsid-buzei
      AND koart = @lc_d.
         
ENDIF.

请注意,这种方法存在许多问题:

您现在有两个内部表中的数据,而不是一个,因此您可能需要执行几个 READ TABLELOOP AT... WHERE 来将数据拼凑在一起。 两个 SELECT 而不是一个意味着到数据库服务器的两次网络往返而不是一次。您还错过了您的数据库可能能够为 JOIN 执行的大多数内部优化。这会增加程序的运行时间。 第一个 SELECT 可能会返回大量您不需要的数据,因此您可能会遇到内存问题。您可以通过使用数据库游标 (OPEN CURSOR) 和 FETCH 数据包中的结果来解决这个问题。但这会进一步降低性能。 在使用FOR ALL ENTRIES 时,永远不要忘记IF itab1 IS NOT INITIAL 检查。直观地说,如果查找表为空,就会假设根本没有接收到任何数据库行。但实际上会发生的是,提及FOR ALL ENTRIES 表的WHERE 条件会被完全忽略,您会收到所有 带有koart = 'D' 的表行。

但是,如果您必须对集群表进行 JOIN,那么很遗憾没有其他选择。

【讨论】:

【参考方案2】:

此选择不需要 KOART。 KOART EQ 'D'表示客户发帖,但BSID只包含客户发帖(见表的第三个字段是客户编号)。

【讨论】:

感谢您的回答。但是,我需要 KOART 来检查客户是否具有值“D”或 Debitoren。这是我的要求。 BSID 表中只有客户(Debitoren),您无需担心。另一方面,KNBK 表中只有客户银行账户,因此您受到双重保护。

以上是关于簇表BSEG和透明表BSID/BSAD的主要内容,如果未能解决你的问题,请参考以下文章

SAP ABAP。取一个透明表数据放到另外一个透明表。并保持数据同步

oracle 索引聚簇表的工作原理

[转帖]堆组织表,索引组织表和索引聚簇表

堆组织表,索引组织表和索引聚簇表

使用 _PARTITIONTIME 从现有表在 BigQuery 中创建聚簇表

在没有 INNER JOIN 的选择中使用表 BSEG