ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

银行数据仓库数据架构实践:分层设计、主题域与维度建模全解析

银行数据仓库数据架构实践:分层设计、主题域与维度建模全解析 银行数据仓库体系实践3——数据架构上个月我们刚处理完一个特别典型的线上问题业务部门在月初报表里发现个人存款时点余额与分行统计口径差了将近三十个亿。一开始所有人都盯着SQL排查查了好几天也没找到原因最后发现问题出在模型本身——某分行在源系统做了一轮产品迁移把一部分结构性存款切换到了新的核算产品代码下数据仓库里的产品维表没有同步更新DWS汇总层还按老产品代码过滤新代码下的余额直接落进了“未知产品”分组。这类问题在银行数据仓库里太常见了。它跟你的ETL写得漂不漂亮、调度有没有延迟、性能调没调优关系都不大根子就一个数据架构没有兜住。数据架构不是一个画在PPT上的分层示意图它是一整套决定数据怎么进、怎么存、怎么算、怎么出的规则和结构设计。我在银行做数据仓库建设这些年踩过不少坑也总结出了一些在金融场景里真正管用的打法。这篇是银行数据仓库体系实践的第三篇重点聊数据架构适合正在做银行或类金融企业数仓建设的数据工程师、架构师以及刚接手数仓项目但还没理清模型和分层思路的同学参考。1. 数据架构到底在解决什么问题1.1 银行数仓和互联网数仓不是一回事很多从互联网行业转过来的同事一上手就把银行数仓按互联网那套思路设计结果后面被折磨得够呛。不是说互联网那套不好而是两个场景的核心目标本身就不同。互联网数仓的核心诉求是快速响应业务变化整个体系高度灵活甚至允许口径快速调整特点是业务种类多、分析场景变化快、对实时性要求高但对“数据的精确性”没那么较真——A/B测试里差个0.1%根本无所谓。银行完全反过来。我从第一天做数仓就被老一辈反复强调一件事账要平。银行任何一个汇总数据出去监管要查、审计要查、业务要实际去对账一分钱的差错都可能上升到操作风险层面。银行数据仓库要解决的几个核心矛盾用大白话说是这样的多套系统之间“口径打架”。一家银行随便就有几十上百套源系统核心系统一套客户信息、信贷系统一套客户信息、手机银行又是一套同一客户在不同系统里可能证件类型、证件号码、客户名称格式都不一样。数据仓库要把这些串起来就得先定游戏规则。源系统变更频繁但下游不能老跟着变。银行的源系统经常做版本升级、产品参数调整、字段新增如果数仓模型直接暴露源表结构上游一改下游全崩。数据架构要做的是把“源系统的变化”消化在可控范围内不让它扩散到整个下游链路。需求响应慢与稳定性要求高的矛盾。业务部门今天要一个客户分层明细明天要一个产品盈利分析后天监管又来一个新报送要求。如果不能靠一套分层的模型结构去承接每次需求都从头写SQL、从头取数整个数仓会被拖垮。监管报送的硬约束。银行有大量固定格式、固定口径的监管报表。这类需求不是“差不多就行”而是精确到每一个字段错一个格子都是合规问题。数据架构必须把这些口径前置固化到模型设计里而不是靠ETL脚本临时拼。1.2 数据架构具体包括哪些范畴我不太喜欢把数据架构讲得太玄。落到实际建设工作上我理解的数据架构就五件事数据怎么分层、模型怎么设计、标准怎么统一、主数据怎么管、数据生命周期怎么控。再加一个贯穿始终的数据流向和分布规则。分层解决的是数据加工的组织方式模型解决的是数据怎么组合才能既稳定又高效标准解决的是不同系统数据到了数仓之后能不能讲同一种语言主数据解决的是跨系统的公共实体客户、产品、机构怎么统一识别生命周期解决的是海量数据怎么在成本、性能和合规之间取得平衡。这五个部分不是孤立的它们是一套组合拳。我在后面几节里把这五件事逐一说透讲清楚每一项在银行场景里到底怎么做、为什么这么做。2. 分层设计是数据架构的骨架2.1 从ODS到ADS每层存在的理由银行数仓最主流的分层方式是五层结构加公共维度层ODS贴源层、DWD明细数据层、DWS汇总数据层、ADS应用数据层和DIM公共维度层。先说每一层具体干什么再看层之间的纪律。ODS层是全仓库的“接水区”。它的核心职责是近源存储也就是说源系统给我什么我先原封不动地接进来不做过深的加工。这一层解决的是“源系统的数据能不能稳定纳进来”的问题同时形成一个数据备份万一后面加工链路上出了什么问题还有机会从ODS重新跑。DWD层是数据架构的核心也是最考验功力的地方。这一层做的事情是清洗、标准化、码值转换、统一粒度。比如核心系统的“客户名称”和信贷系统的“借款人名称”在ODS是两张表两个字段到了DWD就被统一成客户维表里唯一的“客户名称”字段。DWD建设得好不好直接决定了上面所有应用层开发的效率和数据质量。DWS层是面向公共场景的汇总层把高频使用的指标提前算好。比如“客户当日总资产”“机构当季总存款”“产品月度日均余额”这些指标被几十张报表用同一个口径反复取就没必要在每张报表里各算一遍提前在DWS汇总好。ADS层是应用专属层直接面向报表、下游数据集市、监管报送、BI前端。这一层允许“长得很丑”可以针对特定应用建设临时宽表、分级汇总表因为它的目标只有一个——让最终使用者拿得顺手、查得快。DIM层是公共维表包括客户维、产品维、机构维、渠道维、日期维等被各个层次共享引用。下面这张表是我在项目里给团队做的分层定位对照基本每次新人培训都先过一遍层级核心职责数据粒度加工深度使用对象ODS接水、近源存储与源系统一致低仅做必要转换DWD/ETL程序DWD清洗、标准化、统一粒度最细业务粒度中高核心建模DWS/ADS/部分场景直取DWS公共指标汇总主题汇总粒度高提前汇总ADS/报表ADS应用数据组装面向应用灵活报表/下游/业务DIM公共维表维度属性中全层通用2.2 层间流向遵守几条硬规矩分层架构最怕的不是哪一层设计得不合理而是“肉眼可见的失控”。我见过一个项目ODS层有表直接被下游数据集市取数DWD和DWS形同虚设整条链路退化成“源系统→ODS→下游”最后源系统一个字段变更下游连着挂了三套应用。从那以后我在团队里立了几条硬规矩禁止跨层取数。ODS只服务DWDDWS只接DWD数据ADS只消费DWS和DWD谁都不能越级。这条规矩看着简单但执行起来需要数据血缘和权限管控做配套不是靠大家自觉。ODS表结构要与源系统保持松耦合。ODS的字段命名、数据类型可以和源系统不完全一致但结构上不要轻易做删减字段这种操作避免上游变动直接破坏ODS的完整性。层与层之间的数据流转必须有记录。每次跑批处理ODS到DWD跑了多少行、过滤了多少行、异常了多少行全都要有日志。这样一旦后面发现数据对不上你才能快速定位是“没接进来”还是“加工错了”。敏感数据分层打标。银行数据涉及客户隐私ODS/DWD通常是敏感数据最密集的地方一定要在分层设计的时候就确定脱敏和加密策略不能等出了安全事件再补。分层设计在实践中从来不是“画五条线就完事”的事。你要持续关注每一层的增速、每张表的访问频率、每个字段的血缘覆盖不断微调。数据架构是一个活的结构它会跟着业务和源系统的变化慢慢演进。3. 主题域划分与模型设计打法3.1 主题域不能按“部门”分要按“业务本质”分模型设计的第一步是定主题域。很多数仓项目一上来就问业务部门“你们关心什么”然后按“公司部”“零售部”“运营部”这种部门组织来划分主题域。这种划分方式上线第一天看着很顺可过不了半年就乱——部门会调整业务会合并两个部门的数据天然有交集一个客户既可能跟公司部有关系也可能跟零售部有关系按部门建主题域等于把数仓设计成了部门墙。我在银行项目里更习惯按业务对象和业务过程来划主题域。银行的数据不管怎么变化核心就那么几类客户是业务的主体协议是客户与银行之间的契约关系存款协议、贷款协议、理财协议等产品是协议的标准化模板渠道是客户接触银行的入口事件是实际发生的交易和活动再加上机构、员工、地址、介质银行卡/存折、资产抵押物这些支撑性主题。一个银行数仓最核心的主题域大概长这样客户域客户基本信息、客户关系、客户分层、客户标签协议域存款账户、贷款账户、理财持仓、信用卡账户产品域产品目录、产品参数、产品利率/费率渠道域网点、ATM、手机银行、网上银行、第三方渠道事件域交易流水、合约变动、营销活动响应、渠道访问日志机构域总分行层级、部门结构、网点信息资产域抵质押物、担保关系公共域日期、币种、码值、参数主题域划分完成后每个主题域内部再往下拆解成实体和关系。比如客户域里有个人客户、对公客户、同业客户协议域里有存款协议、贷款协议、担保协议客户与协议之间是一对多的关系。这一整套实体关系通常在数据架构设计文档里用E-R图来呈现但在搭建模型时Hive数仓和MPP数仓建模的侧重点会略有不同这个我后面单独讲。3.2 范式建模和维度建模在银行里不是二选一我见过很多关于“数仓建模到底用范式还是维度”的争论。实际做银行项目你会发现这个问题根本不需要争不同的层次就应该用不同的建模方式组合着用。ODS层就是把源系统原样接进来谈不上建模核心目标就一条“不丢数据”。DWD层是最需要仔细斟酌的地方。传统银行的核心系统基本都是按范式建模的数据规范度很高把核心系统的范式模型同步到DWD也不是不行但后续做分析就会很痛苦——一个大查询要把客户表、协议表、产品表、利率表join六七张跑起来又慢又难维护。我在DWD层的主推思路是以范式建模为骨架做主题整合但在高频访问的公共明细上适度反范式。什么意思就是说基础关系比如客户、协议、产品的核心属性保持规范化设计确保数据的唯一性和一致性但对于那些被几十个下游反复关联的“热点数据”比如客户的账户总览、协议的基本信息可以构建公共明细宽表把常用属性先拼装好避免下游每个应用都重复join一遍。DWS层明确采用维度建模。这里你要先梳理业务过程明确“谁在什么时间通过什么渠道做了什么交易”然后定义事实表和维度表。事实表放度量金额、数量、利率维度表放描述属性客户名称、产品名称、渠道名称通过维度和度量组合去支持各种粒度的分析需求。说得更直白一点建模方式适用层次核心优势主要劣势范式建模ODS/DWD基础区数据一致性好、冗余低、易维护关联查询复杂、性能受限维度建模DWS/ADS查询性能好、易理解、面向分析冗余多、一致性依赖规范管控公共明细宽表DWD热点区兼顾性能与一致性需要维护同步逻辑3.3 公共明细层是银行数仓的“地基工程”在建DWD层时我一直坚持一个原则把全行最核心的业务明细沉淀为公共明细层只加工一次供全行复用。这不是为了省那几张表的存储空间而是为了治“重复加工导致口径分裂”的病。举个例子“客户当日总资产”这个指标在A报表里可能是客户活期存款加定期存款B报表可能加上了理财持仓C报表可能把基金也算进去了。每个报表团队自己写一套加工逻辑出来的数字永远对不上。业务部门拿着三张报表问数据团队“到底哪个是对的”这是数据口径管控上最典型的失败场景。公共明细层的思路是把客户、账户、产品、余额、交易这些最核心的明细加工成标准化的公共明细在指标的标准定义里固化“总资产存款理财基金贵金属”的计算逻辑下游只允许引用公共层的计算结果不允许自己去拼装。这样一来口径源头上就是一致的报表对不上账的问题基本从根上消掉了一大半。公共明细层建设还有一个实际好处它能倒逼你建立统一的数据标准。因为要把那么多源系统的数据揉到一起你就不得不去面对“这个系统的性别代码是0/1那个系统是M/F”“这个系统日期是yyyyMMdd那个系统是yyyy-MM-dd”这些乱七八糟的差异统一处理好这些差异之后整个数据体系才会稳定下来。4. 数据标准与主数据管理解决“多套系统打架”4.1 指标口径不统一是银行数仓最痛的“内伤”做银行数仓时间久了你会发现最大的挑战往往不是技术而是**“同一个指标十个部门有十种定义”**这种事。拿最日常的“存款余额”来说是时点余额还是日均余额含不含保证金存款含不含同业存款含不含应计利息按产品口径归集还是按部门归属归集这些问题如果不在指标标准层面定死每个下游都按自己的理解去取数那全行数据永远是一笔糊涂账。我在实际项目里的做法是建立一套指标体系核心分三层第一层是原子指标即最基础的度量值如“存款余额”“贷款余额”“利息收入”本身不带任何业务限定条件。第二层是派生指标由“原子指标维度修饰词时间周期”组成。比如“对公活期存款日均余额”“存款余额原子指标”“客户类型对公产品分类活期时间日均”。“个人贷款不良率”“不良贷款余额原子指标经修饰客户类型个人时点”。第三层是维度就是各种分类角度如机构维度、产品维度、客户维度、渠道维度。这套体系的价值在于当业务部门提出一个新指标时不是从零开始定义而是先去指标体系里找“有没有可以直接复用的原子指标”再通过“套维度、加修饰、定时间周期”拼装出来。这样从机制上保证了绝大部分报表指标的来源和口径是一致的。4.2 主数据管理客户、产品、机构三件大事主数据是银行数据架构里最特殊也最关键的部分。我把主数据理解为跨系统共享的核心业务实体银行里最重要的主数据有三个客户、产品、机构。客户主数据是最复杂的。一个客户可能在核心银行系统开了储蓄卡在信用卡系统办了一张信用卡在手机银行注册了线上账户在三套系统里分别是三条完全独立的记录。数据仓库要做客户级分析就得先把这三条记录识别成同一个人。我做过一个实际项目识别规则分几层走首选证件类型证件号码精确匹配匹配不上就退而求其次用姓名手机号出生日期组合匹配再不行就靠地址、职业等辅助信息做概率匹配。每一层的阈值都要经过样本验证做出来的客户统一视图才能勉强达到业务可接受的标准。产品主数据解决的是产品目录不统一的问题。核心系统的存款产品叫“整存整取储蓄存款”信贷系统可能叫“定期储蓄-整存整取”到了手机银行又变成“定期存款”。产品主数据要把这些别名全部映射到一个标准产品目录下同时维护产品与核算科目、分类属性个人/对公活期/定期等映射关系。机构主数据相对简单但也不能小看。银行经常发生机构合并、网点撤销、部门改名维度表里机构的历史沿革关系必须完整维护。如果不做历史数据按新机构统计时会发现“机构对不上”跨期对比直接失真。主数据在数仓里的落地方式通常是公共维表映射表。公共维表存标准信息和唯一标识映射表存各系统代码与标准代码的对应关系。ETL在进入DWD层时统一完成转换。4.3 码值标准化看起来是小问题炸起来是大坑码值标准化大概是数据标准里最琐碎但最不能省的一环。同样的“证件类型”核心系统用“01”表示身份证“02”表示护照信贷系统可能用“1”表示身份证“2”表示护照反洗钱系统又是另外一套“I”和“P”。到了数仓层面必须统一成一套标准码值并且用映射表把它和所有源系统对应起来。我遇到的典型事故是这样的某个下游分析应用直接以ODS层的原始码值做关联源系统某次升级把某个证件类型的代码从“9”改成了“A”关联直接断掉该客户的全部数据在报表里人间蒸发了三天才被发现。从那以后我对所有下游应用有一个硬性要求一律不允许直接用ODS原始码值做业务逻辑判断必须经过DWD层标准化转换之后再做关联。码值标准化落地时要注意的细节是标准码值表一定要有生效日期和失效日期。银行码值经常有历史变更比如“贷款五级分类”的代码曾经调整过如果映射表不维护时间版本历史数据的分类口径就对不上监管报表一跨期就出问题。5. 技术实现路径与架构建设的关键决策5.1 技术选型从传统数仓到MPP平台银行数仓的技术选型这些年经历了一个明显的迁移过程。早些年金融行业普遍使用Teradata这类一体机稳定、强悍但扩容成本高、软硬件紧耦合。近几年国产化和降本驱动下主流方向逐渐迁移到分布式MPP架构的数据库产品典型代表有GaussDB(DWS)、TDSQL以及基于Greenplum构建的各类数据仓库平台配合Kafka和Flink处理实时链路。技术选型这件事我给后来者的建议是别只盯着跑分和功能清单要重点看几点你现有的团队熟不熟悉这个产品、有没有成熟的迁移工具链、原厂或服务商能不能提供及时的支持响应、这个产品在同类规模的金融客户中有没有成熟案例。性能指标可以通过压测来验证但生态和支撑能力只有实际用过的团队才说得清楚。银行数仓的架构形态通常会演变成“批流一体”的混合架构。离线部分以MPP数据仓库为计算和存储核心承载T1的批处理业务包括日常报表、监管报送、数据分析实时部分由Kafka接入数据Flink做实时计算支撑实时风控、实时大屏等低延迟场景。两个体系共享同一套指标口径和维表但物理上是分开的避免实时作业和离线作业互相干扰。5.2 数据生命周期管理不是“存得久”而是“该删就删”银行数据生命周期管理有一个天然的矛盾监管和审计要求数据留存足够久但数据量持续增长带来的存储和计算成本压力又越来越大。我们的做法是把数据按生命周期划分几个阶段在线热数据如最近1到3个月的交易明细、当前客户信息存储在数据仓库主存储上保证高性能访问。近线温数据如1到3年前的历史数据使用频率明显下降但仍有查询需求可以迁移到成本更低的存储介质保留查询能力允许降低查询并发。归档冷数据超过3年且满足合规留存要求的数据以文件或压缩格式归档到离线存储不提供在线查询需要时走审批流程恢复。到期销毁达到法定留存期限的数据按银行内部合规流程完成审批后安全销毁。数据生命周期管理的关键在于分类标准和自动流转机制。哪些表属于哪个阶段需要按数据域、数据敏感性、业务价值综合评估并且要在元数据系统里打标。流转不能靠手工迁移要配置自动化的作业周期性执行。我见过有些银行把三年前的流水直接放在在线库里不管结果在线存储扩容速度永远赶不上数据增长性能问题越来越严重这就是没有认真做生命周期管理的后果。5.3 数据架构必须和元数据、数据质量、数据安全联动数据架构不是一张孤立的蓝图它要真正落地必须和另外三套体系协同运转。元数据管理是数据架构的“说明书”。表结构、字段含义、数据血缘、调度依赖、指标定义这些如果只存在于设计文档里很快就会被遗忘。我的经验是元数据一定要跟具体的表和字段绑定自动采集加人工维护相结合并且数据血缘要能可视化。这样数据架构的规则才能被大家看到、被新人接手时快速理解。数据质量是数据架构的“体检报告”。架构定完了数据在流转过程中质量到底怎么样需要有完整性校验该有的表有没有、该有的分区有没有、一致性校验主数据映射是否成功、码值是否都能转换、准确性校验汇总值和明细值能否对上。我所在的团队有一个坚持了很长时间的做法每天批处理结束后自动运行一套数据质量检查脚本有问题当天发送到值班群宁可晚发数也不把错误数据发出去。数据安全是数据架构的“边界”。银行数据涉及客户隐私和商业秘密数据架构在规划存储和传输方案时就必须同步考虑哪些字段是敏感字段身份证号、手机号、账户余额在哪个层级需要加密存储在哪个层级需要脱敏展示哪些数据只能从指定的网络区域访问。事后补安全方案的代价远大于事前同步设计这个坑我不希望你再踩一次。6. 银行数据架构实践中的常见坑与排查实录6.1 异常现象一需求一来模型就返工常听到的抱怨是“需求又变了底层模型又要改”。但仔细排查你会发现大多数模型返工不是因为需求真的变了而是因为模型当初建设时就没有留对扩展位。比如最典型的设计把“客户类型”设计成了一个固定的代码字段“1”对公、“2”个人。后来行里新增了同业客户类型不得不加一个“3”涉及所有引用这个字段的ETL脚本和报表。但如果你在设计之初就把客户类型做成维度表关联而不是在事实表里使用硬编码新增一个类型只是维表里加一条记录的事。排查思路看模型中对业务分类的处理是“硬编码”还是“维表驱动”看事实表是不是被塞进了过多本应放在维表中的描述性属性看表结构设计是否考虑了业务扩展的可能性。实践心得是凡是你在设计时觉得“可能以后会变”的地方基本上就一定会变但具体什么时间变、怎么变、扩展到什么程度很难预测。常见的应对是第一控制直接写死在代码里的业务判断第二每张核心表的扩展字段预留几个备用位第三接口层面尽量按“宽入窄出”的原则设计让模型结构保持稳定。6.2 异常现象二ODS到DWD链路过长跑批老超时银行批处理跑批窗口是非常有限的。正常规划是每天凌晨开始跑必须在早上业务开门前完成留给你的批量窗口通常就四五个小时。如果ODS到DWD的加工链路过长跑批超时是家常便饭。我排查过很多次跑批超时问题大部分根因集中在三类一是DWD层加工步骤过多且串行执行一个大的存储过程跑完才跑下一个二是同一张明细大表被多处重复扫描比如两张DWS表各join了一次DWD的千万级大表白白浪费计算资源三是DWD层缺少有效的分区裁剪条件全表扫描了不该扫描的历史分区。解决方向是批量里面能并行的一定要并行注意避免资源争抢把重复扫描同一张表的逻辑尽量合并一次扫描产出多个结果对分区键做合理的物理设计让大多数查询能通过分区裁剪大幅减少扫描范围。通常可以先把DWD的公共明细逻辑跑完跑出一个统一的明细表DWS再从这个表同时产出多个维度的汇总结果比每个指标都去源表join一遍要快得多。6.3 异常现象三指标口径永远“差一点”口径不一致的事情前面已经反复提到了。真正在实施中每当出现指标对不上的情况我的排查路径是这样的第一步两边先确认取数的SQL看是不是一边加了“仅含已核销”一边没加第二步如果SQL一致但结果不一致就比对双方用的底层表看是否一个是DWD明细汇总、一个是DWS预汇总第三步如果表也一样就逐层往下看DWD到DWS加工过程中的过滤条件、类型转换、去重逻辑有没有差异。这里有一个需要特别注意的地方空值处理方式不同很容易导致结果不一致。比如贷款余额字段一个作业在汇总时把空值当成0累计另一个作业在过滤时把空值行直接排除了两边数据就差出几个亿。以后凡是做汇总必须明确空值的处理策略并在指标定义里写清楚。6.4 异常现象四数据量涨得比预期快存储性能双双告急银行数仓的数据量增长往往是超预期的特别是流水类、日志类数据每年翻倍不稀奇。等你发现“查询变慢了、空间不够了”再去救火通常已经比较被动。我建议从架构层面提前做几件事一是数据生命周期管理的自动归档机制必须从一开始就配置好二是分区策略要合理按日期分区是银行数据的标准做法涉及跨区查询的业务模式要尽量减少三是MPP数据库的分布键选择要谨慎选择分布键时优先考虑关联频繁的等值关联字段避免数据倾斜导致个别节点成为瓶颈。7. 一个独家的实操技巧分层权限设计最后分享一个我在实际项目中深有体会的技巧——分层权限设计。银行数据仓库一定是多团队协作的每个团队的角色不同、数据权限需求也不同。如果所有团队都能访问所有层级的表那数据管理和安全审计会变得极其困难但如果你把所有数据都锁死只给看ADS层那数据开发团队也没法干活了。我的实践做法是分角色配置权限数仓管理员拥有全量表的访问和管理权限负责模型设计、元数据维护、生命周期管理。ETL开发人员拥有ODS和DWD的读写权限、DWS的读权限但只限于自己负责的数据域。报表开发人员拥有DWS和ADS的读写权限一般不允许直接访问ODS和DWD的明细数据。业务分析人员仅拥有ADS层的权限通常还要配置行级权限控制比如只能看自己所在分行的数据。这个设计让不同角色之间形成一种自然的隔离既不影响开发效率也能把数据安全风险控制在一个可控的范围内。配合统一的数据权限审批流程谁在什么时间访问了哪些敏感数据全部有审计记录。我在实际做数据架构这几年最深的一个体会就是架构不是一个静态的产出物而是一个持续演进的治理过程。刚开始做的时候不用追求一步到位的大而全模型先把分层、标准、主数据和公共明细这几根柱子立起来后面随着业务和源系统的稳定模型自然会越来越完善。另外有一个小小的判断标准可以分享给你每次新需求评审时先问一句“这个指标在DWD公共明细层能不能算出来”如果算不出来大概率是模型有缺失应该优先补模型而不是在应用层加临时逻辑。用这个标准反推模型演进了两三年之后你会发现整个数仓会越走越顺各种“突发”的数据问题也会越来越少。
返回列表