Pointer——就是将一个对象 A 存为另一个对象 B 的属性值,这适合用来处理一对一或者一对多的关联关系。
Array——就是将多个对象 A、B、C 存为另一个对象 D 的属性值,这适合用来处理一对多或者多对多的关联关系。
AVRelation——这是一个专门的关联类,用来建立两种对象之间的关联关系,适合多对多的场景。
中间表——使用专门的类,来为两种对象建立关联关系,与 AVRelation 相比它还可以添加更多的附加信息。譬如我们为用户之间关注/被关注的关系建模,就像流行的社交网络那样,一个用户可以关注别的用户。在这里,我们不仅想知道用户 A 是否关注了用户 B,我们还想知道什么时候用户 A 开始关注的用户 B,这时候就适合建立专门的中间表。中间表适合多对多的关联关系。
数据存储服务总览
感谢你选用 LeanCloud 数据存储服务。你可以通过使用我们提供的 SDK,一行后端代码都不用写,而快速完成一个产品(网站或应用)的开发和发布。
初衷
大部分的产品都是数据驱动的,它们有一个最大的特点,就是对后端的需求在模式上其实是比较统一的:
这样的模式适合互联网上绝大部分产品,虽然数据结构有差异、业务逻辑不一样,但是前后端交互的主体——「数据」,抽象来看是一致的,后端的架构(譬如 LAMP)也是大同小异的,而且同样的系统在一遍一遍地被重复开发,极大浪费了我们宝贵的技术资源。
我们的解决方案
LeanCloud 对大部分场景下的后端需求进行了抽象和统一,我们通过四大系统来实现一个通用、强大、可定制的 BaaS(Backend as a Service)服务:
面向对象的海量数据库
前后端交互的主体,都是「数据」,不管结果多少,属性具体含义如何,它们都可以抽象成统一的「对象」来处理。LeanCloud 支持存储任意类型的对象,支持对象的增、删、改、查等多种操作,并且开发者无需担心数据规模的大小和访问流量的多少,可以简单将 LeanCloud 云端看成是一个面向对象的海量数据库来使用。
大文件存储和分发
任何一款产品,不管是网站、应用还是游戏,都有一些素材或者文件需要存储和分发。与应用内数据不一样,这些文件因为它的体积较大,为了获得更快捷的用户体验,一般都还需要 CDN 服务。LeanCloud 存储系统完整涵盖了大文件存储和分发的需求。
LeanEngine 完成特定业务逻辑
LeanCloud 提供的数据操作 API 能覆盖大部分业务的需求,但是凡事总有例外,这些标准 API 有时候并不能完全满足某些特定需求,这时候怎么办?LeanCloud 还提供了「LeanEngine」自定义服务端业务逻辑的功能。LeanEngine 与大家熟知的 Google App Engine 相似,允许开发者写很少的一部分代码,来完成业务特有逻辑。这些代码会被部署到 LeanCloud 云端,与 LeanCloud 标准服务一起执行,来实现特殊需求。
基于数据仓库的分析服务(仅对商用版和企业版应用开放)
对于完全构建在 LeanCloud 上的产品来讲,在运行一段时间之后会积累大量的业务数据,这时候产品和运营层面都会产生一些数据挖掘或商业智能分析的需求,此时如何才能简便地操作云端,看到数据背后隐藏的趋势和价值呢?为此我们推出了新一代的数据仓库服务,支持云存储对象,日志表的自动入库,从而为业务的运营分析提供支持。
下面我们重点来了解一下存储系统的几个核心概念。
对象 AVObject
我们将客户端与服务端交互的纷繁芜杂的数据,统一抽象成「对象」,在我们的数据模型里面,对应的就是「AVObject」。每个 AVObject 都包含与 JSON 相兼容的键值对(key-value)数据,并有一个类别名(Class Name)。LeanCloud 云端对于 AVObject 里面「键」的数量并没有限制,也不要求每一个 AVObject 里面都包含所有的「键」。譬如在一个游戏里面,我们有多种数据需要保存:
我们可以全部存放在一种 AVObject 对象里面(假定类别名为
AllInOne
):你可以把这两条记录都保存到一种 AVObject 里面,这在 LeanCloud 云端是被允许的。但是我们强烈建议开发者将不同类型的数据根据用途进行分类,形成不同种类的 「AVObject」。譬如上面的例子,我们可以抽象出
User
这种对象来保存账户信息,抽象出GameScore
这种对象来保存得分信息。每种「AVObject」对应 LeanCloud 云端的一张「表」(注意:为了便于理解,这里借用了关系型数据库里面表的概念,在 LeanCloud 存储管理控制台,是按 Class 来区分的),同一类对象的所有数据都存放在一起。每一个 AVObject 的实例保存到 LeanCloud 云端之后,LeanCloud 云端会赋予该实例一个全局唯一的
objectId
,这个objectId
等同于关系型数据库中的主键。同时 LeanCloud 云端还会自动为该实例添加两个属性:createdAt
和updatedAt
,分别表示实例创建时间和最后更新时间。你可以把 LeanCloud 云端看成是一个面向对象的海量数据库,它与传统的关系型数据库的差异有:
有效的数据类型
AVObject 中的 键,必须是由字母、数字或下划线组成的字符串;开发者自定义的键,不能以
__
(双下划线)开头。AVObject 中的 值,可以是字符串、数字、布尔值,或是数组和字典。在平台内部,LeanCloud 将数据存储为 JSON,因此所有能被转换成 JSON 的数据类型都可以保存在 LeanCloud 云端。并且,框架还可以处理日期、Bytes
以及文件类型。总结来说,AVObject 中字段允许的类型包括:String
字符串Number
数字Boolean
布尔类型Array
数组Object
对象Date
日期Bytes
base64 编码的二进制数据File
文件Null
空值(SDK 不支持将字段设为null
,强烈不推荐通过 REST API 设置null
值,如果值不存在,建议干脆不设置相应字段)Object
类型简单地表示每个字段的值都可以由能 JSON 编码的内嵌对象组合而成。对象的 Key(键)包含$
或者.
,或者同时有__type
的键,都是系统保留用来做一些额外处理的特殊键,因此请不要在你的对象中使用这样的 Key。另外,ACL、className、createdAt、objectId、updatedAt
这些属性名是保留字段,不能作为自定义的 键 来使用。我们的 SDK 会处理原生的 Objective-C 和 Java 类型到 JSON 之间的转换。例如,当你保存一个
NSString
对象的时候,它在我们的系统中会被自动转换成String
类型。有两种方式可以存储原生的二进制数据。
Bytes
类型允许直接在 AVObject 中关联NSData
或者bytes[]
类型的数据。这种方式只推荐用来存储小片的二进制数据。当要保存实际文件(例如图片,视频,文档等),请使用 AVFile 来表示File
类型,并且File
类型可以被保存到对象字段中关联起来。数据类型锁定
当一个 Class 初次创建的时候,它不包含任何预先定义并继承的 schema。也就是说对于存储的第一个对象,它的字段可以包含任何有效的类型。
但是,当一个字段被保存至少一次之后,这个字段将被锁定为保存过的数据类型。例如,如果一个
User
对象保存了一个字段name
,类型为String
,那么这个name
字段将被严格限制为只允许保存String
类型(如果你尝试保存其他类型到这个字段,我们的 SDK 会返回一个错误)。一个特例是任何字段都允许被设置为
null
,无论它是什么类型。注意,一个字段第一次被保存时值为null
,那么该字段的类型会被锁定为Object
(对象)。在某些场景下,这可能会导致预期之外的行为。例如,假设User
对象有一个昵称字段nickname
,第一个用户未设昵称,这时如果将nickname
设为null
,并保存该用户,那么,nickname
的类型会被锁定为Object
。之后这个用户或其他用户设置昵称(字符串)并保存,会报错。因此,建议勿将字段的值设为null
,如果一个字段的值不存在,那么干脆不要设置这个字段。事实上,LeanCloud Java SDK 会直接忽略设为null
的操作,换言之,put(key, null)
不会进行任何操作。字段类型锁定会无法更改,除非全部删除后重建。例如,假设有一个
indexId
列,类型为String
,其中保存的都是数字字符串。如果想把这个列的类型改为Number
,可以先建一个临时列,把数据写过去,然后删除indexId
,再根据临时列写回来。数据管理
LeanCloud 控制台 > 数据存储 > 结构化数据 是一个允许在任何应用里更新或者创建对象的 Web UI 管理平台。在这里你可以看到保存在 Class 里的每个对象的原生 JSON 值。
当使用这个平台的时候,请牢记:
null
将会设置值为特殊的空值null
,而非字符串"null"
。objectId
、createdAt
和updatedAt
不可编辑(它们都是系统自动设置的)。数据导入和导出
我们并不锁定用户和数据。相反,我们提供 API 和工具,来支持用户随时随地导出存放在我们平台上的数据。同样地,数据导入也是可以批量操作的。除了 REST API 之外,我们还提供通过 JSON 文件和 CSV 格式文件的导入数据 的功能。
数据关联
上面讲过,AVObject 模型与传统的关系型数据库有一个很大的不同,就是没有了主键、外键的概念,但是对象之间总会存在关联,这时候该如何解决呢?
LeanCloud 中有 4 种方式来构建对象之间的关系:
详细内容请参考 数据模型设计指南。
数据查询 AVQuery
AVObject 保存到 LeanCloud 云端之后,如何再次获取到它们呢?这时候需要用到数据查询功能了。前面我们讲过,查询语法因为面向对象的模型不同,与 SQL 语法有较大差异。这时候我们能用的就是 AVQuery。AVQuery 的功能非常强大,它可以:
文件存储 AVFile
除了应用内数据存储之外,LeanCloud 云端也支持「文件」类数据的存储。这里的「文件」指的是图片、音乐、视频等常见的文件类型,以及其他任何二进制数据。因为 AVObject 有大小限制,所以超过 128 KB 的数据不能直接存储到 AVObject 里面;而且更重要的是,对于图片、音乐、视频类数据,因为它们的体积太大,为了终端用户有快捷的下载体验,都需要额外的 CDN 加速服务,这时候,就需要使用特别的类型「文件」,即 AVFile 来存储。你既可以使用 LeanCloud 默认提供的公用域名来访问这些文件,也可以为它们指定自定义域名(推荐)。文件域名支持 HTTP 和 HTTPS。
用户对象 AVUser
几乎所有的应用都会用户的概念。例如手机号注册用户、邮箱注册、手机验证码登录、手机号一键登录等等,这些都是与用户相关的常见功能,开发者可以通过 AVUser 对象来快速实现它们。
注册和登录支持如下方式:
还支持邮箱密码重置、手机密码重置等辅助功能,详细使用方法请参考各 SDK 开发指南。
数据存储 Hook 机制
详见 云函数开发指南 > Hook 函数。
主要性能指标
LeanCloud 平台保证 99.9% 的高可用性,并且数据访问方面保证了极高的读写性能和极大的数据支持规模:
原生 SDK
如果你是某个特定平台的开发者,想查看我们原生的 SDK 开发指南,请移步到具体页面:
Android 开发指南
详细请参看 数据存储开发指南 · Java。
Objective-C 开发指南
详细请参看 数据存储开发指南 · Objective-C。
JavaScript 开发指南
详细请参看 数据存储开发指南 · JavaScript。
Python 开发指南
详细请参看 数据存储开发指南 · Python。
PHP 开发指南
详细请参看 数据存储开发指南 · PHP。
.NET 开发指南
详细请参看 数据存储开发指南 · .NET。
Unity 开发指南
详细请参看 数据存储开发指南 · Unity。
Java 开发指南
详细请参看 数据存储开发指南 · Java。
Swift 开发指南
详细请参看 数据存储开发指南 · Swift。
REST API 说明
详细请参看 REST API 使用详解。
常见问题
数据安全有保障吗
因为是把自己的核心数据存放到开放的云端,所有用户或多或少都会有这方面的担心:我的数据安全吗?
LeanCloud 重视数据安全,因此提供如下技术手段来保证用户的数据安全可靠:
具体请参考文档 数据和安全。
我会被绑定在 LeanCloud 平台吗
除了安全之外,大家担心的第二个问题就是开放。我们把数据存放到这个平台之后,还可以自由导出吗?以后要想搭建自己的后端专属集群了,可以快速地迁出吗?
放心,LeanCloud 秉承「开放、自由」的理念,绝不会故意制造障碍来「绑架」用户。我们提供 API、工具来让用户随时导出或导入自己的数据,我们相信只有可靠的技术和好的服务才能吸引并留住用户。
标准 API 满足不了业务需求,怎么办
LeanCloud 标准 API 能满足很多通用的需求,但有时候我有一些特殊的需求,譬如:
这时候你可以使用我们的 LeanEngine 服务,来扩展标准 API 的功能,具体请参考文档 云引擎开发指南。
要对存储的数据进行业务分析,怎么办
我把数据都放到了 LeanCloud 上面,两个月后产品经理想看看某一功能的日均使用情况,或者运营人员要分析用户从注册到消费的时间周期,这时候怎么办?
LeanCloud 为此提供了数据仓库,与云存储紧密结合,支持存储数据的自动入库,并提供强大且易用的 SQL 查询来支持数据的多维度分析。具体请参考文档 数据仓库使用指南。