`

FoodmartSchema2012 解析

 
阅读更多

原文引用自:http://triffic.iteye.com/blog/1123760

BI中如何配置模式文件(Schema)

 

在这里系统的看看构成模式文件的元素:
首先说明一点:这个sample中每一部分在形式上有很多重复的地方,为了尽可能地讲的完全,所以在讲解的过程中,
每一部分提取形式上不重复的部分,然后加入该部分的一些可选项,同时可以查阅FoodMart.xml这个Schema文件。
从宏观上来看,配置一个Schema大致可以分成五部分,分别是:1、Table配置 2、Dimension配置 3、Measure配置 4、VirtualCube配置 5、访问权限配置。在本sample中已经标记出,下面分析每一部分中的元素构成。

<第一部分>
  <Table name="sales_fact_1997">
    <AggExclude name="agg_c_14_sales_fact_1997" />
    <AggName name="agg_c_special_sales_fact_1997">
        <AggFactCount column="FACT_COUNT"/>
        <AggIgnoreColumn column="foo"/>
        <AggForeignKey factColumn="product_id" aggColumn="PRODUCT_ID" />
        <AggMeasure name="[Measures].[Unit Sales]" column="UNIT_SALES_SUM" />
        <AggLevel name="[Time].[Year]" column="TIME_YEAR" />
    </AggName>
    <AggPattern pattern="agg_sales_fact_1997_.*">
        ....
      <AggExclude name="agg_sales_fact_1997_olddata" />
      <AggExclude pattern="agg_sales_fact_1997_test.*" />
  </AggPattern>
 </Table>
</第一部分>
1、首先给出表名,在一般情况下,一个Cube是建立在一张事实表之上的,所以Table name=某事实表,但也可以在一张基础表上建立Cube。
2、在本sample中加入了一个聚合表(aggregate table),在一个Cube中可以加,也可以不加,需要根据实际情况来决定。聚合表的作用简单的说表现在考虑报表设计时,通过聚合预先计算好数据汇总,从而改进查询响应的时间。聚合表的内容非常丰富,在这里只讲解最基本的概念,进一步了解请访问官网http://mondrian.pentaho.com/documentation/aggregate_tables.php,接下来简单的理解构成聚合表的元素。
3、AggExclude name,这里给出的表名旨在告诉Mondrian该表不是相应事实表的聚合表。
4、AggName name,这里给出的表名告诉Mondrian该表是相应事实表的聚合表
5、AggFactCount column="FACT_COUNT",这个字段在每一张聚合表中都存在,记录了相应的事实表中有多少列写入到聚合表中。
6、AggIgnoreColumn column,该列名的作用是告知Mondrian该列是已知的,应该被忽略。
7、<AggForeignKey factColumn="product_id" aggColumn="PRODUCT_ID"/>这里给出了一个映射关系,即事实表中的product_id列对应了聚合表中的PRODUCT_ID列。
8、AggMeasure name和AggLevel name这两个元素同样也给出了一个映射关系,即把在Cube的模式文件中定义的逻辑名映射到聚合表中的列名。
9、AggPattern pattern使用了正则表达式,把符合该pattern的聚合表包括进来。如在本sample中把前缀为agg_sales_fact_1997_的聚合表全部包括进来作为孩子元素。
10、AggPattern pattern中的AggExclude name元素,该元素很明确地指出在已包括进来的聚合表中,剔除某特定的聚合表。
11、AggPattern pattern中的AggExclude pattern元素,该元素的作用表现在把符合AggExclude pattern的正则表达式的聚合表剔除。
12、第一部分的完整框架是:
  <Table>
     <AggExclude>
     <AggName>
         <AggFactCount/>
         <AggIgnoreColumn/>
         <AggForeignKey/>
         <AggMeasure/>
         <AggLevel/>
     </AggName>
     <AggPattern>
       <AggExclude name/>
       <AggExclude pattern/>
   </AggPattern>
  </Table>

 

 

<第二部分>
  <DimensionUsage name="Store" source="Store" foreignKey="store_id"/>
  <Dimension name="Promotion Media" foreignKey="promotion_id">
    <Hierarchy hasAll="true" allMemberName="All Media" primaryKey="promotion_id" defaultMember="All Media">
      <Table name="promotion"/>
      <Level name="Media Type" column="media_type" uniqueMembers="true"/>
    </Hierarchy>
  </Dimension>
  <Dimension name="Customers" foreignKey="customer_id">
    <Hierarchy hasAll="true" allMemberName="All Customers" primaryKey="customer_id">
      <Table name="customer"/>
      <Level name="City" column="city" uniqueMembers="false"/>
      <Level name="Name" column="customer_id" type="Numeric" uniqueMembers="true">
        <NameExpression>
          <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
          <SQL dialect="access">fname + ' ' + lname</SQL>
          <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
          <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
          <SQL dialect="mssql">fname + ' ' + lname</SQL>
          <SQL dialect="derby">"customer"."fullname"</SQL>
          <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
          <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
          <SQL dialect="generic">fullname</SQL>
        </NameExpression>
        <OrdinalExpression>
          <SQL dialect="oracle">"fname" || ' ' || "lname"</SQL>
          <SQL dialect="access">fname + ' ' + lname</SQL>
          <SQL dialect="postgres">"fname" || ' ' || "lname"</SQL>
          <SQL dialect="mysql">CONCAT(`customer`.`fname`, ' ', `customer`.`lname`)</SQL>
          <SQL dialect="mssql">fname + ' ' + lname</SQL>
          <SQL dialect="derby">"customer"."fullname"</SQL>
          <SQL dialect="db2">CONCAT(CONCAT("customer"."fname", ' '), "customer"."lname")</SQL>
          <SQL dialect="luciddb">"fname" || ' ' || "lname"</SQL>
          <SQL dialect="generic">fullname</SQL>
        </OrdinalExpression>
        <Property name="Gender" column="gender"/>
        <Property name="Marital Status" column="marital_status"/>
        <Property name="Education" column="education"/>
        <Property name="Yearly Income" column="yearly_income"/>
      </Level>
    </Hierarchy>
  </Dimension>
</第二部分>
1、DimensionUsage元素:如果在之前定义了共享维(shared dimensions),并且在该Cube中想要使用该共享维,
那么就如<DimensionUsage name="Store" source="Store" foreignKey="store_id"/>使用,通过store_id把
事实表sales_fact_1997和基础表Store相连接。
2、<Dimension name="Promotion Media" foreignKey="promotion_id">
    <Hierarchy hasAll="true" allMemberName="All Media" primaryKey="promotion_id" defaultMember="All Media">
      <Table name="promotion"/>
      <Level name="Media Type" column="media_type" uniqueMembers="true"/>
    </Hierarchy>
   </Dimension>
  定义了一个名为Promotion Media的维,通过promotion_id连接基础表promotion和事实表sales_fact_1997。
 <Level name="Media Type" column="media_type" uniqueMembers="true"/>定义了一个层次中的级别,选择了基础表promotion的media_type字段,不包括该表中的其他字段。
3、在本上面的例子中又定义了一个名为Customers的demension,通过字段customer_id连接基础表customer和事实表sales_fact_1997。接下来来解释下其他元素的作用:
 <Level name="XXXX" column="XXXX" type="XXXX" uniqueMembers="XXXX">
    <KeyExpression>
     SQL表达式,用于该级别的key,代替了column
    </KeyExpression>
    <CaptionExpression>
     SQL表达式,用于计算一个成员的标题,代替了Level.captionColumn
    </CaptionExpression>
    <ParentExpression>
     SQL表达式,用于计算一个度量,代替了Level.parentColumn
    </ParentExpression>
        <NameExpression>
          SQL表达式,用于计算一个成员的名字,代替了Level.nameColumn
        </NameExpression>
        <OrdinalExpression>
          SQL表达式,用于对一个level的所有成员进行排序,代替了Level.ordinalColumn
        </OrdinalExpression>
        <Property name="XXXX" column="XXXX">
         <PropertyExpression>
          SQL表达式,用于计算一个属性的值,代替了Property.column
         </PropertyExpression>
        </Property>
  </Level>
4、第二部分的完整框架是:
  <DimensionUsage/>
   <Dimension>
     <Hierarchy>
       <Table name=/>
       <Level name=/>
     </Hierarchy>
   </Dimension>
   <Dimension name>
     <Hierarchy>
       <Table name=/>
       <Level name=/>
       <Level name=>
         <KeyExpression>
      <SQL dialect></SQL>
     </KeyExpression>
     <CaptionExpression>
      <SQL dialect></SQL>
     </CaptionExpression>
     <ParentExpression>
      <SQL dialect></SQL>
     </ParentExpression>
         <NameExpression>
           <SQL dialect></SQL>
         </NameExpression>
         <OrdinalExpression>
           <SQL dialect></SQL>
         </OrdinalExpression>
         <Property name="XXXX" column="XXXX">
          <PropertyExpression>
           <SQL dialect></SQL>
          </PropertyExpression>
         </Property>
       </Level>
     </Hierarchy>
   </Dimension>

 

 

<第三部分>
  <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="Standard"/>
  <Measure name="Promotion Sales" aggregator="sum" formatString="#,###.00">
    <MeasureExpression>
      <SQL dialect="oracle">(case when "sales_fact_1997"."promotion_id" = 0 then 0 else "sales_fact_1997"."store_sales" end)</SQL>
    </MeasureExpression>
  </Measure>
  <CalculatedMember name="Profit" dimension="Measures">
    <Formula>[Measures].[Store Sales] - [Measures].[Store Cost]</Formula>
    <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
  </CalculatedMember>
</第三部分>
1、第一个Measure的名字是Unit Sales,对应事实表中的unit_sales列,聚合的方法是求和(还可以是:sum,count,min,max,avg,distinct-count),求和之后的结果格式为标准格式。
2、第二个Measure的名字是Promotion Sales,在该Measure下加入了一个MeasureExpression。期望是:从事实表sales_fact_1997中挑选出promotion_id=0的所有行,然后对该事实表的store_sales进行求和(如果某行的sales_fact_1997.store_sales=0,则不对该行进行计算)
3、CalculatedMember元素是一个计算成员,在本sample中取名Profit,属于Measures维。期望是:商店的销售额减去商店的成本得到利润值,得到的值的类型是字符串类型,值的格式是$#,##0.00
4、第三部分一个完整的框架是:
  <Measure>
   <MeasureExpression>
    <SQL/>
   </MeasureExpression>
  </Measure>
  <CalculatedMember>
   <Formula/>
   <CalculatedMemberProperty/>
  </CalculatedMember>
  <NamedSet>
   该集合的值是由公式推导出的,是Cube的组成部分
  </NamedSet>
  

 

<第四部分>
 <VirtualCube name="Warehouse and Sales" defaultMeasure="Store Sales">
   <VirtualCubeDimension cubeName="Sales" name="Customers"/>
   <VirtualCubeDimension name="Product"/>
   <VirtualCubeMeasure cubeName="Sales" name="[Measures].[Sales Count]"/>
   <CalculatedMember name="Profit Per Unit Shipped" dimension="Measures">
     <Formula>[Measures].[Profit] / [Measures].[Units Shipped]</Formula>
   </CalculatedMember>
 </VirtualCube>
</第四部分>
1、VirtualCube,A cube defined by combining the dimensions and measures of one or more cubes. A measure originating from another cube can be a <CalculatedMember>.即若干个Cube中的dimension和measure相结合形成一个Cube,该Cube就叫做VirtualCube。来自另一个Cube的measure可以是该VirtualCube的计算成员。
2、在本sample中定义了一个叫Warehouse and Sales的多维虚拟分析主题,VirtualCubeDimension定义了一个来自Sales的Cube,并且选择了该Cube中的Customers维。注意在VirtualCubeDimension的定义中还有另一种方法,如<VirtualCubeDimension name="Product"/>,这是针对共享维的使用方法。
3、VirtualCubeMeasure定义了一个来自Sales的Cube,并且选择了该Cube中的Sales Count度量。
4、CalculatedMember定义了一个计算成员,使用方法和一般的Cube一样。
5、第四部分一个完整的框架是:
  <VirtualCube>
   <CubeUsages>
    <CubeUsage>
    </CubeUsage>
   </CubeUsages>
   
    <VirtualCubeDimension>
    </VirtualCubeDimension>
    
   <VirtualCubeMeasure>
   </VirtualCubeMeasure>
   
   <CalculatedMember>
   </CalculatedMember>
  </VirtualCube>
  或者如本sample中的写法,即把在VirtualCube中要使用到的Cube写在<VirtualCubeDimension>,<VirtualCubeMeasure>和<CalculatedMember>中,
  从而不需要在<CubeUsages>中定义。
 

  

<第五部分>
<Role name="California manager">
  <SchemaGrant access="none">
    <CubeGrant cube="Sales" access="all">
      <HierarchyGrant hierarchy="[Store]" access="custom" topLevel="[Store].[Store Country]">
        <MemberGrant member="[Store].[USA].[CA]" access="all"/>
        <MemberGrant member="[Store].[USA].[CA].[Los Angeles]" access="none"/>
      </HierarchyGrant>
      <HierarchyGrant hierarchy="[Gender]" access="none"/>
    </CubeGrant>
  </SchemaGrant>
</Role>
</第五部分>
1、该部分属于访问控制配置文件
2、Role定义了一个访问者
3、SchemaGrant是一个访问Schema的权利的集合
4、CubeGrant是一个访问Cube的权利的集合
5、HierarchyGrant是一个访问该层次以及属于该层次的级别的权利的集合
6、MemberGrant是一个访问成员以及该成员的孩子的权利的集合
在理解上述元素的情况下,我们来了解在本sample中该部分的作用:首先定义了一个访问用户,是California manager(加州经理),他不能访问整个Schema中的Cube,但他可以访问Sales这个Cube。其次,自定义了对该Sales Cube中的Store这个层次的访问控制,他可以访问位于美国加州的store(除了洛杉矶)。最后定义了他对该Sales Cube中的Gender层次无访问权限。
7、第五部分的完整框架是:
  <Role>
    <SchemaGrant>
      <CubeGrant>
        <HierarchyGrant>
          <MemberGrant/>
        </HierarchyGrant>
        <HierarchyGrant>
      </CubeGrant>
    </SchemaGrant>
  </Role>

分享到:
评论

相关推荐

    基于STM32的弦波无刷电机控制资料:源码及带Video教程.pdf

    基于STM32的弦波无刷电机控制资料:源码及带Video教程.pdf

    机器学习(预测模型):关于银枫树生长的研究数据

    这个数据集是关于银枫树生长的研究数据,主要探讨了生长调节剂对银枫树顶芽萌蘖长度、单个节间长度以及芽数的影响。根据数据集的名称可以推测,它可能包含与树木生长相关的数据,例如树木的种类、年龄、高度、直径、生长速度、土壤类型、气候条件等信息。这些数据可能来源于对不同地区、不同种类树木的长期观测和记录,旨在研究树木生长的规律、影响因素以及与环境之间的相互关系。该数据集可能对生态学家、林业工作者、环境科学家等研究人员具有重要价值。例如,生态学家可以利用这些数据来研究树木在不同生态系统中的生长模式和生态位;林业工作者可以分析树木的生长速度和质量,为森林资源的管理和可持续利用提供依据;环境科学家则可以探究气候变化、土壤污染等因素对树木生长的影响,从而更好地制定环境保护策略。此外,该数据集也可能在教育领域发挥作用,为学生提供实际的生态数据,帮助他们更好地理解生态学和环境科学的概念和原理。

    S7-200-PC-Access-SMART-V2.3

    ‌S7-200 PC Access SMART V2.3‌是西门子公司推出的一款针对S7-200 SMART PLC与上位机通信的OPC(OLE for Process Control)服务器软件。其主要作用是与其他标准的OPC客户端进行通信,并提供数据信息。S7-200 PC Access SMART V2.3与S7-200 PLC的OPC服务器软件PC Access类似,也具有OPC客户端测试功能

    服务器运维之统信服务器操作系统 V20(1060)安装指南详解

    内容概要:文档提供了统信服务器操作系统 V20(1060)详尽的安装指导。涵盖前期准备工作、多种安装方式(如光盘、USB盘、PXE、镜像引导)、系统配置过程中的重要设置(如网络、时间、分区、授权管理等)、FAQ等常见疑问解决方案。该指南有助于用户顺利完成系统部署和初步配置。文中对不同架构(包括 AMD64, ARM64, LoongArch)的支持情况做了特别介绍,并针对鲲鹏服务器进行了特定提示和参数调整。 适合人群:具备Linux基础知识的专业IT技术人员,尤其是在服务器安装和管理系统方面的工作者。 使用场景及目标:为那些计划部署或升级到统信服务器操作系统的数据中心提供全面的安装指导,确保系统能够稳定高效地投入使用。此外也为遇到安装难题的技术员提供排障方法。 其他说明:除了图文并茂的教学流程,文中还涉及了诸如BIOS设置、安装过程中可能出现的问题及其解决方案等多个方面。特别强调了安全性配置和支持多语言特性等内容。

    阿里巴巴的销售管理分析(50页).ppt

    阿里巴巴的销售管理分析(50页)

    基于SVPWM的直接转矩控制:Matlab_Simulink仿真模型(成品)——包含PI控制的转速环、转矩环和磁链环,以及空间矢量SVPWM调制与转矩脉动优化.pdf

    基于SVPWM的直接转矩控制:Matlab_Simulink仿真模型(成品)——包含PI控制的转速环、转矩环和磁链环,以及空间矢量SVPWM调制与转矩脉动优化.pdf

    chromedriver-mac-x64-135.0.7049.28.zip

    chromedriver-mac-x64-135.0.7049.28.zip

    是一个专为Windows用户设计的免费Android应用反编译和打包工具 这款工具集成了多种实用功能,包括解包、搜索、重新打包、签名以及批量打包,使得Android应用的逆向工程过程变得更加简便

    是一个专为Windows用户设计的免费Android应用反编译和打包工具 这款工具集成了多种实用功能,包括解包、搜索、重新打包、签名以及批量打包,使得Android应用的逆向工程过程变得更加简便

    门户元素-消息通知.zip

    门户元素-消息通知.zip

    基于SpringBoot的福泰轴承进销存系统(源码+数据库+万字文档)

    一、项目介绍 403.系统包含三种角色:管理员、仓库人员、销售人员,主要功能如下。 管理员: 1. 个人中心:管理个人信息,包括修改密码、查看个人资料等。 2. 管理员管理:对其他管理员进行添加、编辑、删除等操作。 3. 基础数据管理:管理系统的基础数据,包括商品分类、供应商信息、客户信息等。 4. 公告管理:发布公司内部公告通知。 5. 供应商信息管理:管理供应商的信息,包括添加、编辑、删除供应商等操作。 6. 客户管理:管理客户信息,包括添加、编辑、删除客户等操作。 7. 商品管理:管理商品信息,包括添加、编辑、删除商品信息等操作。 8. 商品出入库管理:管理商品的出入库记录,包括入库、出库、调拨等操作。 9. 商品销售管理:管理商品的销售记录,包括销售订单管理、销售统计等。 10. 商品退货管理:处理客户退货请求,包括审核、退款等操作。 11. 销售人员管理:对销售人员进行添加、编辑、删除等操作。 12. 仓库人员管理:对仓库人员进行添加、编辑、删除等操作。

    chromedriver-win64-134.0.6998.90.zip

    chromedriver-win64-134.0.6998.90.zip

    VLAN划分在网络管理中的应用:基于Cisco 2960交换机的广播域隔离实践

    内容概要:本文主要介绍了VLAN的概念及其重要性,尤其是如何将大量设备划分为多个广播域,从而有效防止局部网络攻击对整个网络的影响。文中具体讲述了利用Cisco 2960系列交换机来进行VLAN划分的方法步骤,并附带了一个简单实验案例。实验内容展示了如何通过配置命令设置不同部门所用的机器归属于特定VLAN,同时测试跨VLAN间主机间的不可达状态,以验证分区的有效性。 适合人群:对于有一定基础但想要深入理解企业级网络管理和安全性措施的学习者、网络管理员和技术爱好者。 使用场景及目标:适用于任何规模的企业内部网络架构设计与优化过程中,尤其是在面对复杂的网络安全环境时,能够更好地规划和控制网络流量。 其他说明:文章侧重于理论结合实际操作,详细解释每个步骤背后的原理,确保读者可以动手搭建并测试自己的小型网络实验环境。此外,还提及到了关于ARP攻击的具体防范措施之一——限制传播范围。这有助于提高用户对企业信息化安全的认知水平,增强应对潜在风险的能力。

    DBeaver MongoDB驱动包

    DBeaver MongoDB驱动包

    uwsgi-alarm-curl-2.0.27-4.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统uwsgi-alarm-curl-2.0.27-4.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf uwsgi-alarm-curl-2.0.27-4.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    基于SpringBoot的海滨体育馆管理系统(源码+数据库+万字文档)

    427海滨体育馆管理系统,系统包含两种角色:用户、管理员,系统分为前台和后台两大模块,主要功能如下: 登录模块的实现 管理员和学生在登录界面输入用户名、密码,并选择用户类型进行登录操作。 注册模块的实现 没有账号的学生用户可进行注册操作。 学生管理模块的实现 管理员可以添加、修改和删除学生信息。 系统主界面模块的实现 学生可以进入系统前台查看系统信息,包括首页、器材信息以及体育论坛等。 器材管理模块的实现 管理员可以添加、修改和删除器材信息,学生可查看器材信息。 器材借出管理模块的实现 学生可以添加器材借出信息,管理员可以查看和管理所有器材借出信息,并可进行修改和删除操作。 活动预约管理模块的实现 学生可以添加活动预约信息,管理员可以查看活动预约信息,并可进行审核、修改和删除操作。

    2025年福建三明公交路线及站点矢量shp数据.zip

    2025年福建三明公交路线及站点矢量shp数据.zip

    高性能计算集群操作系统迁移的技术细节及实施方案

    内容概要:本文详细介绍了高性能计算集群的操作系统选型和迁移实施过程。主要内容包括操作系统迁移背景,如CentOS生命周期结束后的安全风险,硬件不兼容等问题;迁移内容涵盖管理节点和计算节点的操作系统更换及其与各类基础软件和计算软件的适配工作;详细展示了选型评估标准(如安全性、性能支持和技术社区),以及适配步骤(从软件调研到部署及用户引导)。还对迁移前后的性能进行了测试和对比,确认满足系统性能要求。 适合人群:面向高性能计算领域的IT管理和技术人员、系统管理员和相关领域的研究者。 使用场景及目标:旨在为那些需要进行大型运算集群改造的人群提供指导,帮助他们理解和实操操作系统迁移的整个过程。同时,确保新的操作系统能够与现有的硬件和各种应用无缝衔接,在迁移过程中保持集群工作的连贯性和效率。 其他说明:文中提供了大量的实际案例分析,包括交我算平台的具体实例,并探讨了不同Linux发行版的特性和优势(如openEuler、Rocky Linux)。此外还有性能测试的数据支撑,验证了新型操作系统是否能继续支持高性能计算任务的需求。

    全国计算机等级考试四级操作系统原理考点解析与试题详解

    内容概要:本文档是全国计算机等级考试(NCRE)四级操作系统原理科目的样题及参考答案,涵盖单项选择题与多项选择题两大部分。主要内容涉及操作系统的并发性和多道程序设计、进程管理和调度、内存管理和虚拟存储、文件系统和I/O控制等方面的关键知识点和技术细节。此外还提供了详细的答案解析,旨在帮助考生更好地理解和掌握操作系统原理。 适合人群:参加全国计算机等级考试四级操作系统原理科目考试的学生及希望深入了解操作系统核心技术的专业人士。 使用场景及目标:考生可通过做题巩固所学的操作系统理论知识,加深对该学科的理解,并熟悉考试题型与答题技巧,为目标是在短时间内快速提升应试能力以及全面掌握操作系统的专业知识。 其他说明:文档不仅包含了各类典型的练习题目及其解答提示,而且还强调了实际应用中常见的操作系统设计挑战及相关解决方案的讨论。这有助于读者更深入地思考和探究操作系统的设计思想及其实现机制。

    基于vue3+springboot的教务管理系统源代码+数据库+答辩PPT

    基于vue3+springboot的教务管理系统源代码+数据库+答辩PPT

    2025年使用DeepSeek赋能家庭教育.pdf

    2025年使用DeepSeek赋能家庭教育.pdf

Global site tag (gtag.js) - Google Analytics