|
|
51CTO旗下网站
|
|
移动端

NoSQL究竟是什么?了解为什么NoSQL数据库不是传统数据库的对手

近年来,我们目睹了NoSQL的兴起,并观察它在各种应用中的应用。本文旨在对SQL和NoSQL技术进行客观比较,并尝试澄清一些不明确的方面,以帮助人们熟悉地选择后端。

作者:程序员新视界来源:今日头条|2019-09-11 15:10

近年来,我们目睹了NoSQL的兴起,并观察它在各种应用中的应用。本文旨在对SQL和NoSQL技术进行客观比较,并尝试澄清一些不明确的方面,以帮助人们熟悉地选择后端。

我对NoSQL的态度

一切都有时间,2014年我开始使用NoSQL。也许我迟到了,但我之前的项目需求完全被传统数据库所满足,所以我没有被迫学习NoSQL。

NoSQL技术被神秘的光环所包围。我第一次发现开发人员有一件名为“NoSQL”的东西,他穿着一件带有“向我询问MongoDB”标记的T恤。我当时没有问过。我被答案吓到了,我画得很长很复杂。然后我看到两个不同的方面:谁是NoSQL的重要推动者,他们讨厌旧数据库,而传统开发人员则拒绝NoSQL的所有好处。

当我意识到这种情况时,我确信我会发现并学习。这让我进入了一个小项目,我将这两个解决方案与基准进行比较,以显示NoSQL的所有优点和限制。最后,我理解NoSQL和SQL只是为不同项目设计的不同工具(即使在某些情况下你需要两者)。五年后,我无法确定文化差距是否已经填补。这就是为什么我刷新文章,切割无聊的部分,我在这里重新发表。

NoSQL究竟是什么?了解为什么NoSQL数据库不是传统数据库的对手

什么是NoSQL

简单来说,NoSQL是一个不遵循关系数据库模型的新数据存储后端。这意味着我们所说的“容器”与传统的基于SQL的后端的工作方式不同。

NoSQL技术的诞生是为了满足传统数据库已经成熟时出现的一系列新需求。当然,在最近几年,应用程序需求发生了变化,变得更加挑剔(大数据,集群,文件存储库),因此这个新的存储系统的设计考虑到了这些新的需求。

但是,我的意思是“要求”?这里有一组NoSQL旨在支持的案例。

  • 该应用程序使用大量数据(大数据)
  • 该应用程序使用快速更改关系和数据类型(半结构化,非结构化和多态数据)的数据。
  • 开发人员使用敏捷方法在一个小团队中工作:针对长期瀑布迭代的许多小冲刺
  • 作为服务的应用程序可以在Web上发布
  • 为数千名用户而非公司内部的少数人提供的应用程序
  • 对应用程序的未来负载一定不确定:需要具有可扩展性和动态性,需要轻松地在后端集群上使用基础软件

市场上提供了许多NoSQL解决方案,无论是开源还是非开源。它们中的每一个都有所不同,可能专门针对某些特定需求,但基本思想和共同特征是提供更好的可扩展性和性能。为此,他们放弃了通用RDBMS的一些功能,引入了新功能,但保留了足够的功能。

NoSQL实现

SQL DB的一个重大变化是SQL后端是一个通用存储系统,NoSQL分发专注于特定类型的数据。这允许DB在其范围内更有效,并允许我们拥有更高性能的系统。在本节中,我们将讨论NoSQL数据库的应用程序。请注意,它们可以一起使用(也可以与传统的SQL系统一起使用),以便从不同的技术中获得最佳效果。

文档导向

这种类型的数据库不需要具有一致的数据结构,因此当您必须处理多态数据或数据结构不断变化时,它们非常有用。这种后端可以将标准化实体(如键值数据集或EAV模型)转换为简单的文档集。

  • 目标:存储非类型的“记录”集,称为“文档”
  • 示例: MongoDB,CouchDB
  • 目标:异构数据,面向工作,敏捷开发

图数据库

我们被告知NoSQL数据库已经删除了关系的概念以实现更好的性能。在这种DB中,这不是真的。相反,图形数据库强制执行关系概念。

他们的目标是通过与其他数据的关系来定义数据。当大多数数据结构被设计为保持与实体的关系时(即,当存在大多数外键列时,如果有很多表),这种数据库可能很有用。

  • 目标:描述数据关系
  • 示例: Neo4j,GiraffeDB。
  • 目标:数据挖掘

键值商店

这是一种用于存储大量键值对数据的DB。当数据库用于存储属性,转换或缓存目的时,这可能很有用。

  • 目标:以键值形式存储数据
  • 示例: Redis,Cassandra,MemcacheDB
  • 目标:键值存储

NoSQL的优点

我们知道NoSQL DB有一些有趣的优点,它们可以解决传统RDMS无法解决的问题。如今,他们在关键系统中的大量工作,如大型云系统和一些大型SaaS产品,确认它们已经成熟且有用。但问题是,为什么我应该转向他们?在这种情况下,何时移动有利可图?我们不能只根据我们的印象做出这样的决定,并阅读一些供应商宣传册,其中NoSQL非常酷是不够的。而且,我们不能因为害怕变化而停留在不充分的平台上。

在本节中,我将尝试解释为什么这个解决方案可以很好地转移到哪个用例使其更有利可图。

正如我们所说,NoSQL数据库的创建是为了响应传统关系数据库技术的局限性。这意味着我们会发现一些改进,或者更好的是,传统RDBMS中的某些功能不存在且无法添加,即使生产者会实现它们。

NoSQL的优点包括易于处理的功能:

  • 大数据:使用这个术语,我们描述了包含大量数据的数据集。
  • 可变数据:数据也可以是结构化的,半结构化的和非结构化的。NoSQL还可以管理数据转换。
  • 动态开发:在我们需要敏捷冲刺,快速迭代,频繁代码推送以及总结以响应变化的环境中,拥有一个包含动态的数据库是非常有帮助的。
  • 面向对象:易于使用且灵活的编程
  • 可扩展:我们可以轻松实现高效,可扩展的架构,而不是昂贵的单片架构。即使在传统的数据库中,我们也能做到这一点,但它更难,更有限。
  • 开源:大多数解决方案都是开源的,因此无需许可证

综上所述:

NoSQL数据库更具可扩展性并提供更好的性能,并且它们的数据模型更接近应用程序内部使用的域模型。基于NoSQL数据库启动项目的公司数量正在增长。NoSQL数据库也往往是开源的,这意味着开发,实现和共享软件的成本相对较低。

NoSQL的限制

在评估NoSQL数据库的局限性时,重要的是要记住NoSQL世界是一个多样化的生态系统。并非所有NoSQL存储产品都具有相同程度的所有缺点。这是一件好事,因为这意味着在权衡不同NoSQL解决方案的优缺点时,组织有很多选择,以决定哪一个最适合他们的特定需求。本章总结了使用NoSQL解决方案可能会遗漏的一些功能。

通过阅读这篇文章,你会发现本章扩展的不仅仅是优势之一。这不是阻止使用NoSQL的方法。本章将对NoSQL技术的所有限制进行公正的描述,并且只是想让您了解使用它们时可能遇到的每个问题。许多要点可能会因实施而有所不同(即,当我说支持的工具很少时,大多数工具都适合,但并非所有工具都适用),因此请将它们视为一个概述,提醒您可能存在的风险找。我期望的是,在您选择使用NoSQL产品之后,您可以使用本章作为核对表来了解您的特定数据库中是否存在此问题以及它是否与应用程序相关。

安全

安全是每个人都想要的,但很难达到。从理论上讲,每种技术都可能存在安全问题。SQL系统上也存在安全问题,也许存在安全问题。那么为什么我将此标记为NoSQL的可能问题?

关于安全性的NoSQL“概念”没有真正的问题,但我们可能会遇到与我们采用的产品的成熟度相关的安全问题。产品增长时出现安全问题,然后修复。直观地说,年轻的产品可能有许多未知的安全问题。此外,一个年轻的产品在市场上销售的时间较短,因此顾问没有时间获得它们的经验,许多安全限制可以忽略不计。所以,问题是大多数NoSQL平台的新特性。对于商业用途,我建议使用成熟的解决方案,背后有供应商。

数据一致性

当我们开始学习RDBMS时,他们告诉我们ACID事务是使整个数据库保持一致的操作的最佳选择。好吧,大多数NoSQL技术都没有实现这种交易。NoSQL系统基于最终一致性原则。在实践中,拥抱一点风险(一个节点可能与其他节点不同步),它们会获得一些性能提升。是的,这是妥协,但我们不能拥有一切。

我必须提到一些NoSQL实现,比如FoundationDB,允许类似ACID的事务保持NoSQL性能高。顺便说一下,当我们继续使用NoSQL时,数据一致性仍然是一个关键部分:基于您正在开发的应用程序,这可能是一个问题。

JOIN的

当您与试图将您转换为NoSQL技术的人交谈时,您可以从中听到的第一个好处之一是由于删除关系而带来的性能优势。我们都同意一种关系可能会降低性能,但我们会失去什么呢?

想象一下,你在徒步旅行时背着沉重的背包。当然,放弃它你会更快。这样做很方便吗?取决于这个包装包含什么,这取决于背包内容的价值是什么。如果它包含一个夜晚的帐篷,也许最好在一小时后到达目的地,但要保持温暖而不是走得更快。如果你带来有用的一次性用品,也许你可以做相反的事情。

遵循这种并行性,我们是否可以接受松散的一致性以获得性能?方便值得吗?

退后一步,我将从连接的起源开始。RDBMS使用该关系将数据从一个表链接到另一个表,以将数据保存在一个位置而不复制它们。构造连接以允许我们在查询中重新连接它们。当然,在表之间进行连接需要额外的计算成本,而不是直接在要查询的表中查找数据。但是这个成本对于保持关系(没有复制,一致性)是必要的。

很明显,虽然这个功能有可接受的开销,但这没关系,可能是最好的选择。但什么时候它减慢了一切或需要太多的硬件?这个问题允许NoSQL开发人员声称缺少JOIN到一个功能,但NoSQL始终是解决方案吗?

不总是。有时我们只需要重新设计数据库结构,可能会删除一些关系或重组数据。是的,我们将失去一些关系,或者我们将复制日期的某些部分,但它可以接受(在NoSQL中我们将失去所有的关系)。

另一个问题是一致性。考虑类别和产品。我们可能有一个嵌套的类别树,许多产品作为树的叶子。在传统的RDMS中,更改类别树只是对类别表上的外键(自我关系)的更新。这些更改会自动反映所有子类别和产品。在NoSQL中,我们可以在所有类别/产品上拥有冗余数据,并且需要对子元素进行大量更新。

棘手的交易

让我假设我们的应用程序可以放弃JOIN以获得速度,在我们的例子中,这是一个可接受的权衡。我们说过,在许多NoSQL实现中,很难保持各种条目的一致性。当您在没有事务的情况下工作时,您可以按顺序执行许多操作,但过了一段时间后会出现不一致 这对于NoSQL的第一次实现是正确的,并且一些新技术试图给出事务。您还可以考虑在应用程序级别管理事务,尝试回滚脏数据,但在许多情况下可能很难管理。

缺少供应商技术的标准

SQL是一种标准语言。可能会有许多变化带来特定的方言,但这很复杂并不禁止抽象数据访问。想想Hibernate,NHibernate,Doctrine,Entity Framework或其他ORM。它们证明了SQL方言之间的区别并不重要。我们可以得出结论,即使许多供应商实现了不同的数据库技术,SQL也是一种标准语言。此外,如果您不是基于ORM层,如果您为DB生成查询,则大多数代码可以在其他代码中重用。这使迁移更容易,开发人员可以快速适应不同的DB解决方案。

另一方面,在NoSQL世界中,存在更多混乱。每个供应商实现其特定语法,而不涉及任何共享标准。这意味着在不同的NoSQL实现之间迁移应用程序更加困难。这意味着找到一个熟悉许多NoSQL技术的程序员更难。

架构灵活性可能是一个麻烦

NoSQL系统的一个特点是它们不需要架构。在实践中,程序员在保存数据时决定数据结构。因此,没有任何地方可以写出数据的结构以及数据的含义。即使您可以使用某种自动化工具轻松地从数据关系重新创建数据库模型,这可能是传统应用程序中缺少的。

而且,如果发生错误怎么办?我们知道可能存在代码出错的情况。传统的RDMS是脚手架,因此如果您切换某些字段或者您的字段格式错误,它们可以保护您免受不一致。在NoSQL的情况下,DB没有任何帮助,因为没有定义任何模式,没有任何关于数据的信息应该保存:没有人可以说数据是否错误。最糟糕的副作用是,该过程为开发人员带来了很多权力和很多责任,通常不了解所有流程或完整结构。

而且,即使你现在知道什么是保存的,你认为你会记得下个月的所有内容?和第二年?并非所有项目都需要持续开发,在我们需要进行一些更改之前,可能会有一个业务应用程序保持原样多年。

在IT部门,公司通常会将项目委托给某个供应商,因此必须考虑这一部分,以确保在项目结束时轻松移交,可能要求准确记录有关数据的结构以及每个字段/集合的含义。与模式灵活性相关的最后一个问题是团队中的每个成员都无法在项目中工作,因此,对于小团队来说,流量是至关重要的并非所有成员都对数据结构有完整的了解,或者没有足够的文档。

Analytics(分析)

将多个嵌套数据保存在单个文档中可能会丢失“SUM”,“COUNT”等分析功能。在第一次应用程序开发期间这可能不是问题的坏事,但有人可能会在稍后询问某些报告,那么在这种情况下该怎么做?在填充数据库之后很难改变数据结构,并且由于明确定义的数据结构的泄漏,这样做可能具有不可预测的影响。分析对于NoSQL来说是一个难点。

此外,虽然有许多商业工具可以连接到传统数据库来管理分析部分,但对NoSQL系统的支持有限。

可以采取的另一个解决方案是在NoSQL DB中复制某种与非结构化数据的“关系”,可能会创建许多集合并将对象与其他集合链接起来。如果您计划遵循此路径以允许分析报告,请记住,这可能会降低性能,使其与标准SQL系统相媲美。当此DB中涉及的部分最小且记录数量有限时,这是可以接受的。无论如何,即使根据我的经验,构造允许加入NoSQL查询的数据,因为背后没有明确定义的关系,非常有限并且性能不如我们预期的那么好(即,在撰写本文时) ,MongoDB不支持内连接,每次只能进化到表而不创建临时表)。

更少的工具

我们谈到了NoSQL查询语言和语法缺乏标准化。这个问题也可以反映在工具中,以及大多数平台的年轻性。我说的是用于查询的工具,也用于在数据库之间迁移数据,管理备份等。当然,大多数NoSQL项目正在增长,我们期望工具会随之增长,所以这个问题会在某些时候自动解决。

缺乏标准化使第三方供应商难以构建可支持多种NoSQL解决方案的工具。此外,年轻平台意味着更少的用户,更少的客户,更少的时间来开发成熟的工具。

性能比较

指定比较的方式很重要。首先,我需要将两种解决方案置于相同的条件下。这意味着,例如,使用相同的硬件并具有相同的调整级别。所以我在同一台机器上安装了MongoDB(最新版本)和SQLServer Express。因为我们对数据库本身的性能不感兴趣,所以我使用基于标准框架的C#代码构建了我的基准测试。

通过这两种方式来保存数据,一切都是共享的(实体,逻辑,数据生成)以确保公平。

我们将比较的所有操作列表:

  • 质量插入
  • 询问
  • 分析
  • 事务(或更好,在NoSQL情况下,事务模拟)

对单个实体的批量操作

该基准测试包含一组可在较短时间内插入的对象。使用越来越多的项目来复制此测试以保存以证明两个系统中的性能规模。该基准测试以毫秒为单位测量执行时间,并坚持使用单个表/集合。

NoSQL究竟是什么?了解为什么NoSQL数据库不是传统数据库的对手

搜索

此基准测试侧重于查询功能。我们将以下模式分开:

  • CASE 1使用主键获取一个实体:此模式用于从DB获取单个实体,使用唯一标识符
  • CASE 2完全扫描失败:当您要查找已删除的元素时,数据库必须在回复“否”之前扫描所有索引。
  • CASE 3分页查询:一个复杂的查询,其中有一些过滤器,一个订单条件,并且您只想获取一页数据。

我创建了一些基准模拟上面不同比例的模式。在一个示例中,第一个基准假定5%的类型1的查询,70%的类型2和25%的类型3.该基准测量以ms为单位的执行时间。此基准测试坚持使用单个表\集合。

您可以在git-hub上找到用于执行这些测试的所有代码。

第一个测试是在“小”数据集上,大约2.500,000行。

对“更大”的数据集进行第二次测试,大约5M行。

此基准测试突出显示了对索引的查询性能的重大改进,但是当使用MongoDB读取一组数据时,增益会降低并且在数据增加时保持稳定。

NoSQL究竟是什么?了解为什么NoSQL数据库不是传统数据库的对手

交易

我们知道NoSQL世界的事务大多不受支持。我们也明白放弃交易可以从表演中获益,一个问题是:我从中获得多少收益?我构建了这个基准来比较插入与一个与许多孩子相关的主行的事务。基准测试的重点是执行时间,以ms表示。

NoSQL究竟是什么?了解为什么NoSQL数据库不是传统数据库的对手

Analytics(分析)

该基准专注于分析。假设我们有一个分类的主 - 详细数据模型,您希望:

  • export:整个加入整体数据树
  • 报告:汇总所有类别的所有项目,即为所有客户提供发票金额
  • 关键绩效指标:总结所有总计总计详细小计

在内连接后的4M行的基础上:

NoSQL究竟是什么?了解为什么NoSQL数据库不是传统数据库的对手

兴趣点

革命在科技领域是不可避免的。新技术带来了一些革命性的功能,但往往不得不打败开发人员的先入之见。有时他们会被误解,所以他们的弱点在他们受雇后就会出现。

关于创新,我们必须“对立”人群:

  1. “热心”的人:希望无条件地接受变革,并准备好处理过去所做的一切,以便使用最后的技术;
  2. “保守派”人:讨厌改变,宁愿保持其习惯,拒绝任何新技术。

在现实生活中,我们必须保持中间位置,因此了解和了解新技术可以为我们做些什么并准备好在项目需要之前采用新技术非常重要。“在工作中进行审判”是一种可能导致不良后果的坏习惯。

同样的原则适用于NoSQL技术。因为我们之前看过NoSQL,现在我们知道赞成和利弊,所以我们可以利用这种工具。当我们分析这项技术时,我们不能停止从传统习惯(如交易,模式和标准)中看到我们想念的东西。我们需要研究和熟悉这些技术,这些技术在几年前还很年轻,但现在却是一个具体的选择。学习,学习,理解,使用:这是进步的本质。

什么时候我应该使用NoSQL Db?

为什么NoSQL会比使用SQL数据库更好?阅读完本文后,我确信您会理解NoSQL不是SQL数据库的替代品,而是具有不同功能的不同存储系统,并且在某些特定领域中非常有用。所以答案不能与“它取决于”有所不同。因为它取决于项目的许多特征。

说实话,谨慎,当以下所有陈述都成立时,NoSQL是最佳解决方案:

  • 当您的项目需要扩展时,或将来可能。
  • 当你必须处理大数据时,或者你的数据在不久的将来会变得很大
  • 当应用程序中的分析组件简单或不那么重要时
  • 当您的应用程序需要适合数据库目的时(即您在图表和数据库中保存数据)

在某些情况下,NoSQL可能是一个很好的选择,但对于构​​建耐用的基础架构并不是必不可少的。当然,如果在您的应用程序中,NoSQL系统覆盖了99%的所有需求,则没有理由将其与RDBMS结合使用。但是,如果您需要标准RDBMS的关系,事务和其他功能,可能最好将它们用作主存储系统,并使用NoSQL仅覆盖关键部分(可能源自数据的大小)。

在上面的情况下,表现有多好?

这取决于具体的用例。从一方面来说,我们在大型表或大量使用方面有很多好处,但从另一方面来说,我们使用查找而不是加入小型数据集会有一些性能损失。一个现实的估计,如果有使用NoSQL DB的基础,我们可以将性能从10提高到100。当然,这种估计考虑了应用程序的所有方面,并且与最终用户体验有关。这意味着您可以在数据库层上测量更好的加速,但最终用户体验会因许多减少差距的因素(缓存,网络延迟,页面呈现)而失真。

只是为了解释我所说的内容,当有一个页面进行查询并返回数据时,请参考示例中的极限情况。假设此页面使用传统数据库获取结果为500毫秒,使用NoSQL为50毫秒,渲染页面为200毫秒,通过互联网传输数据为1秒。DB层的性能提升为-90%,但对于最终用户,1700只增加了450ms,因此只有26%。通过这个例子,我会解释说很难衡量复杂系统的改进,在很多情况下,NoSQL还不足以解决性能问题。更直接的是,如果您考虑解决因迁移到NoSQL的应用程序中的设计不良而导致的性能问题,那么您就没有走上正确的道路。

但最大的问题是:为了获得这种表现,我失去了什么?因为在某些情况下,不可能放弃某些功能,如交易或关系。在移动之前理解这一点非常重要。

NoSQL系统在生产环境中应用是否成熟?

这主要取决于您的需求,或更好地取决于项目要求。我们可以说NoSQL肯定足够成熟。所以,如果你需要它,你可以毫无顾虑地使用它。但并非所有应用程序都需要处理大数据或大规模扩展。大多数Saas产品确实如此,在企业环境中也有很多关键应用程序,但现在大多数应用程序仍然非常简单。

根据我的经验,很难在数据库中找到超过10万行的表。想想你的数据库,排除你上面的2-3个更大的表并查看行数。它们有多大?DB应用程序上的常用DB结构计数很多“小”表(小于10万行)相关。对于这种类型的应用程序,传统的RDBMS就足够了,它将永远存在。重要的是,而不是开始使用它,就是要了解在您的案例需要时准备好的利益和发展模式。

SQL过时了吗?

当男人发明飞机时,汽车已经过时了?不,当然。如果飞机比汽车快。它们只是两种不同的系统来移动人,具有不同的特征。根据您的旅行类型,您在旅行和预算上花费的时间,您将决定什么是最适合您的选择。同样,NoSQL即将推出过时的SQL。它们只是两种不同的存储数据的方式,具有不同的特征。您将根据自己的需求决定什么是最适合您的。

SQL不适合存在问题,因此您不必使用它来启动大数据项目。这将是试图用汽车而不是飞机到达岛屿。但SQL仍然有其优势。许多数据模型最好表示为相互引用的表的集合。这就像试图用飞机去买牛奶一样。NoSQL数据库不是SQL的替代品,但它们是替代品。

市场是否为NoSQL做好准备?

回答这个问题的关键点是更接近开发人员实现的经验。大多数数据库程序员都接受了一年的培训,以便相关地思考数据。他们如何在这么短的时间内改变思维方式?它并不容易,特别是当开发人员必须在许多项目中工作时,其中一些是SQL和其他NoSQL。将SQL上的相同模式复制到NoSQL系统的诱惑很难被击败,并且经常会导致糟糕的结果。

实际上,有更多的SQL专有技术,RDBMS上的开发人员比NoSQL更多。同时,DBA花费大部分时间专注于关系数据库,我们不能指望在不到十年前出生的技术上找到相同的东西。在学校和大学都达到了SQL,NoSQL正在开始。

在第一点之后,第二点是,因为这些系统较新,开发工具较少,或者它们不像其他系统那么先进,但我确信这不是一个真正的问题。有一些“企业就绪”的解决方案,它提供了管理所有基本需求的工具,我们希望这些工具随着平台的发展而增长。

什么是最好的解决方案?

没有涵盖任何案例的最佳解决方案。答案很简单,但仍然相同:“这取决于”。通过本文,我希望能够概述这些系统的所有功能以及了解它们何时有用的一些基础知识。

【编辑推荐】

  1. 一份完整的MySQL开发规范,进大厂必看!
  2. 记一次MySQL数据库升级导致授权失败的案例
  3. 一文看懂MySQL数据库LnnoDB崩溃恢复机制
  4. MySQL如何优化大分页查询?
  5. 超详细的MySQL数据库InnoDB崩溃恢复机制总结
【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

用Python玩转excel

用Python玩转excel

让重复操作傻瓜化
共3章 | DE8UG

110人订阅学习

AI入门级算法

AI入门级算法

算法常识
共22章 | 周萝卜123

108人订阅学习

这就是5G

这就是5G

5G那些事儿
共15章 | armmay

120人订阅学习

读 书 +更多

Linux编程技术详解

本书全面介绍了Linux编程相关的知识,内容涵盖Linux基本知识、如何建立Linux开发环境、Linux开发工具、Linux文件系统、文件I/O操作、设备文...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微