NoSQL数据建立模型技术

初稿来自“NoSQL Data Modeling
Techniques
”,由酷壳网陈皓编译《NoSQL数据建立模型技术》。这篇小说看完事后,你可能会对NoSQL的数据结构会有点觉得。作者的痛感是,关系型数据库想把一致性,完整性,索引,CRUD都干好,NoSQL只干某一种事,不过就义了众多别的东西。总体来说,作者以为NoSQL更切合做Cache。

上面是本文:

NoSQL数据库平日被当作很多非成效性的地点,如,扩张性,品质和一致性的地点。那些NoSQL的天性在理论和执行中都正在被群众广泛地钻研着,研商的看好正是那么些和总体性分布式相关的非作用性的事物,我们都精晓CAP
理论
被很好地动用于了NoSQL系统中(陈皓注:CAP即,一致性(Consistency),可用性(Availability),分区容忍性(Partition
tolerance),在分布式系统中,这多少个要素最五只好同时完结七个,而NoSQL一般扬弃的是一致性)。但在单方面,NoSQL的多少建立模型技术却因为缺少像关系型数据库那样的基础理论没有被世人很好地研究。那篇作品从数量建立模型方面对NoSQL家族举行了比较,并探讨多少个普遍的数目建立模型技术。

要起来钻探数量建立模型技术,大家不得不或多或少地先系统地看一下NoSQL数据模型的成材的可行性,以此我们得以了一部分他们内在的联络。下图是NoSQL家族的进化图,大家能够见到这么的前行:Key-Value时期,BigTable时期,Document时期,全文字笔迹检验索时代,和Graph数据库时期:(陈皓注:注意图中SQL说的那句话,NoSQL再那样发展下去即是SQL了,哈哈。)

必发bifa88手机客服端 1

NoSQL Data Models

第三,大家须要专注的是SQL和关系型数据模型已存在了不短的时刻,这种面向用户的自然性意味着:

  • 最后用户一般更感兴趣于数据的聚集显示,而不是分离的数额,那根本通过SQL来形成。
  • 笔者们不可能透过人手工业控制数据的并发性,完整性,一致性,或是数据类型校验这几个事物的。那就是怎么SQL必要在作业,二维表结构(schema)和表面联合上做过多事。

另一方面,SQL能够让软件应用程序在广大情况下不须求关爱数据库的多寡聚合,和数据完整性和有效性举行控制。而一旦我们去除了数量一致性,完整性那几个事物,会对品质和分布存款和储蓄有关键的增派。正因为这么,我们才有数据模型的迈入:

  • Key-Value键值对存款和储蓄是格外简单而强大的。上边包车型地铁很多技巧基本上都是依照这么些技能开头上扬的。可是,Key-Value有四个万分沉重的题材,那就是借使我们须求摸索一段范围内的key。(陈皓注:学过hash-table数据结构的人都应该知道,hash-table是非连串容器,其并不像数组,链接,队列这个有序容器,大家得以控制数据存款和储蓄的种种)。于是,有序键值(Ordered
    Key-Value)数据模型被设计出来化解这一范围,来从根本上升高数据集的题材。

  • Ordered
    Key-Value有序键值
    模型也丰富强大,不过,其也从未对Value提供某种数据模型。常常来说,Value的模子能够由使用负责解析和存取。那种很不便宜,于是应运而生了BigTable类型的数据库,这几个数据模型其实正是map里有map,map里再套map,一层一层套下去,也便是稀缺嵌套的key-
    value(value里又是1个key-value),这种数据库的Value主要通过“列族”(column
    families),列,和岁月截来控制版本。(陈皓注:关于时间截来对数码的版本控制首假设杀鸡取卵数量存款和储蓄并发难题,也正是所谓的开朗锁,详见《多版本现身控制(MVCC)在分布式系统中的应用》)

  • Document databases
    文书档案数据库
     立异了BigTable模型,并提供了多少个有意义的精益求精。第一个是同意Value中有主观的形式(scheme),而不是map套map。第②个是索引。Full
    Text Search
    Engines全文字笔迹检验索引擎
    能够被当做是文书档案数据库的2个变种,他们得以提供灵活的可变的多少情势(scheme)以及自行索引。他们中间的差异点主假诺,文书档案数据库用字段名做索引,而全文字笔迹检验索引擎用字段值做索引。

  • Graph data models图式数据库 能够被认为是其一进化进度中从Ordered
    Key-Value数据库发展过来的3个分支。图式数据库允许构建议图结构的数据模型。它和文书档案数据库有关联的缘故是,它的洋洋落实允许value能够是1个map或是三个document。

NoSQL数据模型摘要

本文剩下的章节将向你介绍数据建立模型的技艺实现和血脉相通格局。可是,在介绍这个技巧以前,先来一段序言:

  • NoSQL数据模型设计一般从作业应用的切切实实数目查询入手,而不是数额间的涉嫌:
  • 关系型的数据模型基本上是分析数据间的组织和关联。其设计理念是:
    What answers do I have?”
  • NoSQL数据模型基本上是从应用对数据的存取形式初始,如:小编须求协助某种数据查询。其设计理念是 ”What
    questions do I have?”
  • NoSQL数据模型设计比关系型数据库要求对数据结构和算法的更深的打听。在那篇小说中作者会和豪门说那么些明显的数据结构,这几个数据结构并不只是被NoSQL使用,可是对于NoSQL的数据模型却极度有帮忙。
  • 数码冗余和反规格化是一等公民。
  • 关系型数据库对于拍卖层级数据和图式数据丰富的不便于。NoSQL用来缓解图式数据显然是二个尤其好的化解方案,大概全数的NoSQL数据库可以很强地化解此类题材。这正是为啥那篇文章专门拿出一章来注明层级数据模型。

下边是NoSQL的分类表,也是自小编用来写那篇作品时做执行的成品:

  • Key-Value 存储: Oracle Coherence, Redis, Kyoto Cabinet
  • 类BigTable存储: Apache HBase, Apache Cassandra
  • 文书档案数据库: MongoDB, CouchDB
  • 全文索引: Apache Lucene, Apache Solr
  • 图数据库: neo4j, FlockDB

概念技术Conceptual Techniques

这一节关键介绍NoSQL数据模型的中坚尺度。

(1)反规格化Denormalization

反规格化Denormalization能够被认为是把相同的数量拷贝到分歧的文书档案或是表中,那样就足以简化和优化查询,或是正好吻合用户的某中越发的数据模型。那篇小说中所说的绝超越四分之二技艺都或多或少地导向了这一技术。

总体来说,反规格化必要权衡上边那么些东西:

  • 询问数据量
    /查询IO 
    VS 总和据量。使用反规格化,一方面能够把一条查询语句所须要的具备数据整合起来放到四个地点贮存。那意味,别的分裂不一致查询所急需的一模一样的数量,必要放在别差异的地方。由此,那发生了数不胜数冗余的数码,从而造成了数据量的附加。

  • 处理千头万绪度 VS 总和据量.
    在符合范式的多寡格局上海展览中心开表连接的查询,很明白会追加了查询处理的复杂度,尤其对于分布式系统来说尤其。反规格化的数据模型允许我们以有益查询的办法来存构造数据结构以简化查询复杂度。

适用性:Key-Value Store 键值对数据库,Document
Databases文书档案数据库,BigTable风格的数据库。

(2)聚合Aggregates

享有连串的NoSQL数据库都会提供灵活的Schema(数据结构,对数码格式的限量):

  • Key-Value Stores 和 Graph
    Databases基本上来说不会Value的情势,所以Value能够是任意格式。那样一来,那使得我们得以随意组合3个工作实体的keys。比如,大家有3个用户帐号的政工实体,其得以被如下这几个key组合起来: UserID_name,UserID_email,
    UserID_messages
    等等。如果一个用户并未email或message,那么相应也不会有这么的记录。

  • BigTable模型通过列集合来协助灵活的Schema,大家誉为列族(column
    family
    )。BigTable还能在同一记录上出现差别的本子(通过时间截)。

  • Document
    databases文档数据库是一种层级式的“去Schema”的仓库储存,固然有点那样的数据库允许检验要求保留的多寡是不是满足某种Schema。

灵活的Schema允许你能够用一种嵌套式的中间数据情势来储存一组有关系的事体实体(陈皓注:类似于JSON那样的数据封装格式)。那样能够为大家带来多个好处。

  • 最小化“一对多”关系——能够经过嵌套式的格局来储存实体,那样能够少一些表联结。

  • 能够让里面技术上的多少存款和储蓄更类似于事情实体,尤其是那种混合式的事体实体。恐怕存于1个文书档案集或是一张表中。

下图表示了那三种利益。图中描给了电子商务中的商品模型(陈皓注:笔者回忆作者在“挑衅无处不在”一文中说到过电商业中学产品分类数据库设计的挑衅)

  • 先是,所有的货物Product都会有八个ID,Price和Description。

  • 下一场,大家得以驾驭分歧的门类的货色会有两样的质量。比如,小编是书的品质,长度是西裤的性质。其些属性大概是“一对多”或是“多对多”的关系,如:唱片中的曲目。

  • 接下去,大家精晓,某个事情实体不容许利用一定的品种。如:哈伦裤的品质并不是具有的品牌都有些,而且,某些名牌还会搞卓殊特别的天性。

对此关系型数据库来说,要规划那样的数据模型并不简单,而且设计出来的相对离优雅很远很远。而大家NoSQL中灵活的Schema允许你使用二个聚合Aggregate
(product) 能够建出全数差异品类的货色和她俩的不等的属性:

必发bifa88手机客服端 2

Entity Aggregation

上海体育场地中大家得以比较关系型数据库和NoSQL的距离。唯独我们能够看看在多少更新上,非规格化的数据存款和储蓄在性质和一致性上会有极大的熏陶,那正是我们需求注重注意和不得不就义的地点

适用性: Key-Value Store键值对数据库,Document
Databases文书档案数据库,BigTable风格的数据库。

(3)应用层联结Application Side Joins

表联结基本上不被NoSQL援助。正如作者辈日前所说的,NoSQL是“面向难题”而不是“面向答案”的,不支持表联结就是“面向难点”的后果。表的联合是在统一筹划时被组织出来的,而不是在举办时建造出来的。所以,表联结在运维时是有相当的大开发的(陈皓注:搞过SQL表联结的都清楚笛Carl积是如何东西,大能够在参考从前酷壳的“图解数据库表Joins”),可是在利用了Denormalization和Aggregates技术后,大家着力不用进行表联结,如:你们使用嵌套式的数据实体。当然,借使您需求联合数据,你必要在应用层完毕那一个事。下边是多少个主要的Use
Case:

  • 多对多的数据实体关系——日常需求被连接或联合。

  • 聚合Aggregates并不适用于数据字段常常被更改的情景。对此,大家要求把那几个常常被改变的字段分到别的的表中,而在查询时咱们必要联合数据。例如,大家有个Message系统能够有贰个User实体,其包涵了二个内嵌的Message实体。然而,假使用户不断在附加message,那么,最棒把message拆分到另多少个单独的实业,但在询问时联结那User和Message那三个实体。如下图:

适用性: Key-Value Store键值对数据库,Document
Databases文书档案数据库,BigTable风格的数据库,Graph Databases图数据库。

通用建立模型技术General Modeling Techniques

在本书中,大家将斟酌NoSQL中各样差别的通用的数目建立模型技术。

(4)原子聚合Atomic Aggregates

很多NoSQL的数据库(并不是怀有)在事务处理上都以短板。在好几情状下,他们得以由此分布式锁技术恐怕应用层管理的MVCC技术来兑现其事务性(陈皓注:可参考本站的“多版本现身控制(MVCC)在分布式系统中的应用”)不过,日常来说只好选取聚合Aggregates技术来担保一些ACID原则。

那正是干什么我们的关系型数据库须要有无往不胜的事务处理机制——因为关系型数据库的数额是被规格化存放在了分歧的地点。所以,Aggregates聚合允许大家把贰个事情实体存成三个文书档案、存成一行,存成一个key-value,这样就足以原子式的更新了:

必发bifa88手机客服端 3

Atomic Aggregates

自然,原子聚合Atomic
Aggregates那种数据模型并无法落到实处完全意义上的事务处理,不过只要扶助原子性,锁,或test-and-set指令,那么,Atomic
Aggregates是能够适用的。

**适用性: **Key-Value Store键值对数据库,Document
Databases文书档案数据库,BigTable风格的数据库。

(5)可枚举键Enumerable Keys

恐怕,对于无顺序的Key-Value最大的功利是事情实体能够被简单地hash以分区在多少个服务器上。而排序了的key会把业务搞复杂,不过多少时候,三个用到能从排序key中赢得许多好处,就终于数据库本人不提供这么些效果。让大家来商量下email新闻的数据模型:

  1. 局地NoSQL的数据库提供原子计数器以允许生一些一而再的ID。在那种情景下,大家得以行使 userID_messageID 来做为1个构成key。尽管我们精通最新的message
    ID,就能够领略前3个message,也只怕明白再前边和前边的Message。
  2. Messages能够棉被服装进。比如,每一日的邮件包。那样,大家就足以对邮件按钦赐的岁月段来遍历。

**适用性: **Key-Value Store键值对数据库

(6)降维Dimensionality Reduction

Dimensionality
Reduction降维是一种技术能够允许把贰个多维的数码映射成多少个Key-Value或是其余非多给的数据模型。

历史观的地理地点新闻种类利用部分如“6分树QuadTree”或“R-Tree”来做地理地点索引。那一个数据结构的情节必要被在适合的岗位更新,并且,若是数据量不小的话,操作费用会很高。另1个艺术是大家能够遍历二个二维的数据结构并把其扁平化成二个列表。八个众人周知的事例是Geohash(地理哈希)。三个Geohash使用“之字形”的路径扫描二个2维的空中,而且遍历中的移动能够被总结地用0和1来代表其大方向,然后在活动的经过中发生0/1串。下图体现了这一算法:(陈皓注:先把地图分成四份,经度为率先位,纬度为第几人,于是右边的经度是0,右侧的是1,纬度也同样,下面是为1,下边包车型地铁为0,那样,经纬度就能够组成成01,11,00,10那多个值,其标识了四块区域,大家得以这么不断的递归地对各个地区开始展览五分,然后可以获取一串1和0重组的字串,然后使用0-9,b-z去掉(去掉a,
i, l,
o)那3五个假名实行base32编码获得2个7个长度的编码,那正是Geohash的算法)

必发bifa88手机客服端 4

Geohash Index

Geohash的最强劲的功用是运用简单的位操作就足以精晓多个区域间的偏离,就像是图中所示(陈皓:proximity框着的那四个,那个很像IP地址了)。Geohash把叁个二维的坐标生生地改成了二个一维的数据模型,那就是降维技术。BigTable的降维技术参考到文章后边的[6.1]。更加多的关于Geohash和任何技术能够参考[6.2]
和 [6.3]。

**适用性:** Key-Value Store键值对数据库,Document
Databases文书档案数据库,BigTable风格的数据库。

(7)索引表 Index Table

Index
Table索引表是1个可怜直白的技艺,其得以你在不支持索引的数据库中收获索引的便宜。BigTable是这类最要紧的数据库。那亟需大家保障叁个有相应存取格局的专门表。例如,大家有2个主表存着用户帐号,其可以被UserID存取。某询问需求查出有个别城市里有着的用户,于是大家能够进入一张表,那张表用城市做主键,全数和那个城市有关的UserID是其Value,如下所示:

必发bifa88手机客服端 5

Index Table Example

可知,城市索引表的内需和对主表用户表保持一致性,由此,主表的每多少个更新恐怕必要对索引表实行翻新,不然就是贰个批处理更新。无论哪个情势,那都会风险一些性质,因为需求保持一致性。

Index Table索引表能够被认为是关系型数据库中的视图的等价物。

适用性:BigTable数据库。

(8)键组合索引 Composite Key Index

Composite
key键组合是一个很常用的技巧,对此,当我们的数据库帮衬键排序时能赢得一点都不小的功利。Composite
key组合键的拼接成为第③排序字段能够让你构建出一种多维索引,那很像大家前边说过的 Dimensionality
Reduction降维技术。例如,大家需求存取用户计算。假诺大家要求依照差异的地段来总括用户的分布情形,大家得以把Key设计成这么的格式 (State:City:UserID),那样一来,就使得大家能够透过State到City来按组遍历用户,尤其是大家的NoSQL数据库帮助在key上按区查询(如:BigTable类的系统):

  1. SELECT Values WHERE state=”CA:*” 
  2. SELECT Values WHERE city=”CA:San Francisco*” 

Composite Key Index

**适用性:** BigTable 数据库。

(9)键组合聚合 Aggregation with Composite Keys

Composite
keys键组合技术并不仅仅能够用来做索引,同样能够用来区分不用的类别的多寡以支撑数据分组。考虑三个例证,大家有一个海量的日志数组,那个日志记录了互联网上的用户的拜会来源。大家必要计算从某一网站复苏的单身访客的数码,在关系型数据库中,大家兴许需求上边那样的SQL查询语句:

  1. SELECT count(distinct(user_id)) FROM clicks GROUP BY site  

我们得以在NoSQL中成立如下的数据模型:

必发bifa88手机客服端 6

Counting Unique Users using Composite Keys

那般,大家就能够把数量按UserID来排序,大家就足以很简单把同1个用户的数码(一个用户并不会生出太多的event)进行处理,去掉那多少个重复的站点(使用hash
table或是其他什么)。另多个可选的技能是,大家得以对每二个用户建立一个数量实体,然后把其站点来源追加到这一个数据实体中,当然,那样一来,数据的更新在质量相比较之下会有必然损失。

**适用性:** Ordered Key-Value Store 排序键值对数据库,
BigTable风格的数据库。

(10)反转搜索 Inverted Search – 直接聚合 Direct Aggregation

以此技能越多的是多少处理技术,而不是数据建立模型技术。固然如此,这些技能依旧会潜移默化数据模型。那几个技术最关键的想法是选用2个索引来找到满足某条件的多寡,可是把数据聚合起必要运用全文字笔迹检验索。还是让我们的话多少个示范。依然用地方12分例子,大家有很多的日志,在那之中包含互连网用户和她们的造访来源。让我们只要每条记下都有贰个UserID,还有用户的体系 (Men,Women,Bloggers,等),以及用户所在的城市,和走访过的站点。我们要干的事是,为各样用户连串找到满足有个别条件(访问源,所在城市,等)的的独门用户。

很扎眼,大家须要寻找那个满意条件的用户,如若大家选用反转搜索,那会让我们把那事干得很简单,如: {Category
-> [user IDs]}
 或 {Site -> [user
IDs]}
。使用那样的目录,大家可以取七个或三个UserID要的插花或并集(那些事很简单干,而且能够干得飞速,就算这几个UserID是排好序的)。不过,大家要按用户体系来生成报表会变得有个别费劲,因为大家用讲话只怕会像上面那样

  1. SELECT count(distinct(user_id)) … GROUP BY category  

但那样的SQL很没有功用,因为category数据太多了。为了应对这些标题,大家能够建立2个直接索引 {UserID
-> [Categories]}
接下来大家用它来生成报表:

必发bifa88手机客服端 7

Counting Unique Users using Inverse and Direct Indexes

最后,大家必要精晓,对各样UserID的轻易询问是很没有效用的。我们能够通过批查询处理来化解这些题材。那代表,对于有个别用户集,大家可以拓展预处理(分歧的询问条件)。

适用性: Key-Value Store键值对数据库,Document
Databases文书档案数据库,BigTable风格的数据库。

层级式模型Hierarchy Modeling Techniques

(11)树形聚合Tree Aggregation

树形或是任意的图(需反规格化)能够被一贯打成一条记下或文书档案存放。

  • 当树形结构被二回性取出时那会卓殊有功用(如:大家须求体现一个blog的树形评论)
  • 检索和任何存取这一个实体都会存在难题。
  • 对此绝大部分NoSQL的落到实处的话,更新数据都以很不合算的(相比较起独立结点来说)

必发bifa88手机客服端 8

Tree Aggregation

适用性:Key-Value键值对数据库,Document Databases文书档案数据库

(12)邻接列表 Adjacency Lists

Adjacency
Lists邻接列表是一种图–每3个结点都以三个独自的笔录,其涵盖了具有的父结点或子结点。那样,大家就能够经过给定的父或子结点来开展搜寻。当然,大家需求通过hop查询遍历图。那个技能在广度和纵深查询,以及得到有些结点的子树上尚未效用。

适用性:Key-Value键值对数据库,Document Databases文书档案数据库

(13) Materialized Paths

Materialized
Paths能够援助幸免递归遍历(如:树形结构)。那么些技能也足以被认为是反规格化的一种变种。其想尽是为各个结点加上父结点或子结点的标识属性,这样就足以不需求遍历就通晓全体的遗族结点和祖先结点了:

必发bifa88手机客服端 9

Materialized Paths for eShop Category Hierarchy

本条技能对于全文检索引擎来说万分有援救,因为其得以允许把3个层级结构转成三个文书档案。上边的示图中大家能够阅览有着的货品或Men’s
Shoes
下的子分类能够被一条不够长的查询语句处理——只供给给定个分类名。

Materialized
Paths能够储存一个ID的聚集,或是一堆ID拼出的字符串。后者允许你通过三个正则表明式来探寻四个一定的分支路径。下图浮现了这一个技术(分支的途径不外乎了结点自己):

必发bifa88手机客服端 10

Query Materialized Paths using RegExp

适用性:Key-Value键值对数据库,Document Databases文书档案数据,Search
Engines搜索引擎

(14)嵌套集 Nested Sets

Nested
sets
嵌套集是树形结构的正规化技术。它被周边地用在了关系性数据库中,它完全地适用于Key-Value键值对数据库和Document
Databases文书档案数据库。那一个技能的想法是把叶子结点存款和储蓄成一个数组,并透过采纳索引的初叶和终止来映射每二个非叶子结点到1个叶子结点集,就像下图所示一样:

必发bifa88手机客服端 11

Modeling of eCommerce Catalog using Nested Sets

那般的数据结构对于immutable
data不变的多寡有特别科学的频率,因为其点内部存款和储蓄器空间小,并且能够快速地找出全部的纸牌结点而不必要树的遍历。固然如此,在插入和翻新上须要很高的习性花费,因为新的叶子结点须要大规模地换代索引。

适用性:Key-Value Stores键值数据库,Document Databases文书档案数据库

(15)嵌套文书档案扁平化:有限的字段名Nested Documents Flattening:Numbered Field Names

寻找引擎基本上来说和扁平文书档案一同工作,如:每2个文书档案是四个扁平的字段和值的例表。那种数据模型的用来把业务实体映射到一个文本文书档案上,假如您的事体实体有很复杂的内部结构,那可能会变得很有挑衅。多少个金榜题名的挑战是把叁个有层级的文书档案映映射出来。例如,文书档案中嵌套另三个文书档案。让我们看看下边包车型客车示范:

必发bifa88手机客服端 12

Nested Documents Problem

上边的每1个事情实体代码一种简历。其包涵了人名和3个技巧列表。笔者把那些层级文书档案映射成1个文本文档,一种方法是开创Skill和Level字段。那个模型能够透过技术恐怕等级来查找1个人,而上海教室标注的那么的组成查询则会失利。(陈皓注:因为分不清Excellent是还是不是是Math依旧Poetry上的)

在引用中的[4.6]交给了一种缓解方案。其为每种字段都标上数字 Skill_i 和 Level_i,这样就足以分离搜索每多少个对(下图中利用了OLacrosse来遍历查找全部或然的字段):

必发bifa88手机客服端 13

Nested Document Modeling using Numbered Field Names

如此那般的形式根本没有扩张性,对于一些错综复杂的难点的话只会让代码复杂度和掩护理工科人作变大。

适用性:Search Engines全文字笔迹检验索

(16)嵌套文书档案扁平化:邻近查询 Nested Documents Flattening: Proximity Queries

在附录[4.6]中提交了那几个技能用来化解扁平层次文书档案。它用靠近的询问来界定可被询问的单词的限制。下图中,全部的技艺和等级被放在2个字段中,叫
SkillAndLevel,查询中出现的“Excellent”和“Poetry”必需1个紧跟另1个:

必发bifa88手机客服端 14

Nested Document Modeling using Proximity Queries

附录[4.3]必发bifa88手机客服端,中讲述了那个技能被用在Solr中的三个成功案例。

适用性:Search Engines全文字笔迹检验索

(17) 图结构批处理 Batch Graph Processing

Graph
databases图数据库,如neo4j是一个头名的图数据库,特别是使用二个结点来商讨邻居结点,或是探索多个或少量结点前的关系。可是处理大批量的图数据是很没有效能的,因为图数据库的品质和扩张性并不是其指标。分布式的图数据处理能够被MapReduce
和 Message Passing
pattern来处理。如:在自作者前一篇的篇章中的那么些示例。那么些方法能够让Key-Value
stores, Document databases和BigTable-style databases适合于处理大图。

小说来源:酷壳网

相关文章