从SQL到NoSQL—如何使用表格存储

SQL 还是 NoSQL?

NoSQL 是一个用于描述高扩展高性能的非关系数据库的术语。 NoSQL 数据库提供的 schemafree 数据模型能够让应用无需预先定义表结构,适应业务的多元化发展,而对超大数据规模和高并发的支持让 NoSQL 数据库得到了广泛的应用。

  • 访问数据库
  • 创建表
  • 写入数据
  • 检索数据
  • 更新数据
  • 删除数据
  • 删除表

SQL 与 NoSQL 数据库对比

关系型数据库 NoSQL 数据库
数据模型 关系模型对数据进行了规范化,严格的定义了表、列、索引、表之间的关系及其他数据库元素,使一张数据表的所有数据具有相同的结构。 非关系(NoSQL)数据库一般不会对表的结构进行严格的定义,一般使用分区键及键值来检索值、列集或者半结构化数据。
ACID 传统关系型数据库支持由 ACID (原子性、一致性、隔离性和持久性)定义的一组属性。其原子性体现在一个事务"全部成功或者全部失败",即完全执行成功或完全不执行某项事务。一致性表示数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。隔离性要求并发事务应分别执行,互不干扰。持久性即一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。 为了获得更为灵活的可水平扩展的数据模型, NoSQL 数据库通常会放弃传统关系数据库的部分 ACID 属性。凭借这些特性,NoSQL数据库可用来克服一系列包括性能瓶颈、可扩展性、运营复杂性以及不断增加的管理和支持成本的问题,这也让 NoSQL 数据库成了传统关系型数据库在面临海量数据及高并发挑战时的最佳选择。
性能 性能一般取决于磁盘子系统、数据集大小以及查询优化、索引和表结构。 写性能通常受限于磁盘子系统,读性能则受限于结果集的大小
扩展 进行纵向扩展最简单的方式是使用更快的CPU、磁盘等硬件设备。要获得跨分布式系统的关系表,就需要增加使用成本及技术复杂度。 能够利用低成本硬件的分布式集群进行横向扩展,从而在不增加延迟的前提下提高吞吐量和数据规模。
API 对存储和检索数据的请求由符合结构化查询语言 (SQL) 的查询来传达。这些查询由关系数据库系统来解析和执行。 应用开发人员可以使用NoSQL数据库开放的 API 轻松存储和检索数据。通过分区键及键值,应用可以查找键值对、列集或者半结构化数据。

为什么使用表格存储?

表格存储(TableStore)是 NoSQL 数据库的一种,提供海量 NoSQL 数据存储错误,支持 schemafree 的数据模型,提供单行级别的事务,服务端自动对数据进行分区和负载均衡,让单表数据从 GBTB 再到 PB,访问并发从__0__至__百万__都无需繁琐的扩容流程,写性能在 TBPB 级数据规模都能保持在单个毫秒,读性能只依赖结果数据集,而不受数据量的影响。

所以相比 OLTP(联机事务处理)场景,表格存储更适用于 Web 规模级应用程序,包括社交网络、游戏、媒体共享和 IoT(物联网)、日志监控等场景。

表格存储数据模型请参考:数据模型概念

访问数据库

与传统关系型数据库不同,客户端都是通过http协议来访问表格存储。

下图展示了客户端与传统关系型数据库和表格存储之间的交互。

客户端使用 Restful API 通过 HTTP 数据包来访问表格存储,表格存储服务端会对数据报文中的签名信息进行验证,详细请参考使用表格存储的 API,如果使用官网的SDK,则只需要提供所访问的表格存储endpoint、实例、AK信息即可调用SDK的接口对数据进行操作。

表格存储通过客户端来访问数据,客户端初始化方式如下:

    final String endPoint = "";
    final String accessKeyId = "";
    final String accessKeySecret = "";
    final String instanceName = "";
    SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);

客户端初始化需要填入如下参数:

  • endPoint:访问的表格存储实例的url地址
  • accessKeyId:访问表格存储所使用的accessKeyId
  • accessKeySecret:访问表格存储的所使用的accessKeySecret
  • instanceName:访问的表格存储的实例名称

详细信息请参考:访问控制

创建表

表是关系数据库和表格存储中的基本数据结构。关系数据库创建表时就需要定义完整的数据结构。相比之下,表格存储的数据表则只需要定义主键信息。

SQL

使用 CREATE TABLE 语句创建表,如以下示例所示。

CREATE TABLE UserHistory (
    user_id VARCHAR(20) NOT NULL,
    time_stamp INT NOT NULL,
    item_id VARCHAR(50),
    behavior_type VARCHAR(10),
    behavior_amount DOUBLE,
    behavior_count INT,
    content VARCHAR(100),
    PRIMARY KEY(UserId, TimeStamp)
);

此表的主键包含 user_id 和 time_stamp,在创建数据表是必须严格的定义所有的主键和属性列,如有需要,需要使用 ALTER TABLE 语句更改这些定义。

表格存储

使用表格存储创建数据表并指定如下参数,如下所示:

    public static final String TABLE_NAME = "UserHistory";

    TableMeta tableMeta = new TableMeta(TABLE_NAME);
    tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("user_id", PrimaryKeyType.STRING));
    tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("time_stamp", PrimaryKeyType.INTEGER));

    // 数据的过期时间, 单位秒, -1代表永不过期. 假如设置过期时间为一年, 即为 365  24  3600
    int timeToLive = -1;

    // 保存的最大版本数, 设置为3即代表每列上最多保存3个最新的版本
    int maxVersions = 3;

    TableOptions tableOptions = new TableOptions(timeToLive, maxVersions);
    CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions);

    // 设置读写预留值,若不设置则读写预留值均默认为0
    request.setReservedThroughput(new ReservedThroughput(new CapacityUnit(1, 1)));

    client.createTable(request);

此表的主键包含 user_id 和 time_stamp,需要提供的参数主要有:

  • TABLE_NAME:表名称
  • PrimaryKeySchema:主键的名称及类型
  • timeToLive:数据表的数据过期时间
  • maxVersion:数据表属性列的最大版本数
  • ReservedThroughtput:数据表的预留读写吞吐量,容量型实例不再支持预留吞吐量的设置

写入数据

SQL

关系数据库中,表是一个由行和列组成的二维数据结构,可以使用 INSERT 语句向表中添加行:

INSERT INTO UserHistory (
    user_id, time_stamp, item_id, behavior_type,
    behavior_amount, behavior_count, content)
VALUES(
    '10100', 1479265526, 'cell_phone', 'share', 4.9, 78,
    'The phone is quit good!'
);

表格存储

使用表格存储中可以使用 PutRow 接口插入一行数据:

    // 设置主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.fromLong(1479265526));
    PrimaryKey primaryKey = primaryKeyBuilder.build();

    // 设置属性列的值
    RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey);
    rowPutChange.addColumn(new Column("item_id", ColumnValue.fromString("cell_phone")));
    rowPutChange.addColumn(new Column("behavior_type", ColumnValue.fromString("share")));
    rowPutChange.addColumn(new Column("behavior_amount", ColumnValue.fromDouble(4.9)));
    rowPutChange.addColumn(new Column("behavior_count", ColumnValue.fromLong(78)));
    rowPutChange.addColumn(new Column("content", ColumnValue.fromString("The phone is quit good!")));

    // 插入该行数据
    client.putRow(new PutRowRequest(rowPutChange));

使用 PutRow 接口需要了解一下几个关键事项:

  • 除了表名 TABLE_NAME 和主键 primaryKey,属性列和类型可以在写入时定义
  • 多行数据的同名属性列也可以使用不同的类型
  • 大多数 SQL 数据库是面向事务的,当发出 INSERT 语句时,只有 COMMIT 之后对数据的修改才是永久性的。使用表格存储,当表格存储通过 HTTP 200 状态码(OK)进行回复时, PutRow 写入的数据已经被持久化到所有备份。
  • 多条记录的插入可以使用 BatchWriteRow 接口,可以大大提高数据的写入速度。

检索数据

SQL

SQL SELECT 语句可以查询关键列、非关键列或任意组合。WHERE 子句确定返回的行,如以下示例所示:

// 根据主键查询一行
SELECT * FROM UserHistory
WHERE user_id = '10100' AND time_stamp = 1479265526;

// 查询某个user_id下的所有数据
SELECT * FROM UserHistory
WHERE user_id = '10100';

// 根据某个user_id下的某段时间的所有记录
SELECT * FROM UserHistory
WHERE user_id = '10100' and time_stamp > 1478660726 AND time_stamp < 1479265526;

// 查询某个user_id所有收藏的记录
SELECT * FROM UserHistory
WHERE user_id = '10100' AND behavior_type = 'collect';

表格存储

表格存储中的数据查询接口可以以类似的方式检索数据,单行查询 GetRow 和范围查询 GetRange 能够提供对存储数据物理位置的快速高效访问,查询的性能只受到结果数据集大小的影响,不会受到表中数据总量大小的影响。

提供完整的主键信息,可以使用 GetRow 快速查询这行数据。
    // SELECT * FROM UserHistory WHERE user_id = '10100' AND time_stamp = 1479265526
    // 设置主键信息
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn('user_id', PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn('time_stamp', PrimaryKeyValue.fromLong(1479265526));
    PrimaryKey primaryKey = primaryKeyBuilder.build();

    // 读一行
    SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey);
    // 设置读取最新版本
    criteria.setMaxVersions(1);
    GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
使用 GetRange 对某个 user_id 下所有的数据进行查询:
    // 等同于 SELECT * FROM UserHistory WHERE user_id = '10100'
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    // 设置起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MIN);
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());

    // 设置结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());

    // 设置读取最新版本
    rangeRowQueryCriteria.setMaxVersions(1);

    // 默认读取所有的属性列
    GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));

需要了解的几个关键事项:

  1. GetRange 需要指定所有主键的起始范围,__但每个主键的范围并不是 AND 的关系__,而是以第一个主键到最后一个主键为顺序,优先比较前面的主键,当前面的主键在 GetRange 起止主键范围内,则该条数据就会被读取出来。比如两个主键起止范围为('a',5)~('c',10),由于 'a' < 'b' < 'c',所以主键为('b', 4)的数据也符合要求。
  2. INF_MIN 和 INF_MAX 为 GetRange 操作专用类型,分别表示最小值和最大值。
  3. GetRange 支持 limitdirection 来控制结果集行数和读取的顺序。
  4. 为了防止网络延迟, GetRange 对一次返回的结果集进行了限制,需要对 Response 中的 next_start_primary_key 进行判断,为空时表示结果已经全部返回,不为空需要继续读取。
  5. GetRange 支持过滤器功能。
  6. 表格存储支持数据多版本功能,在使用 GetRow 和 GetRange 接口时可以指定读取属性列的历史版本范围。

更多 GetRange 信息也可以参考:表格存储数据模型和查询操作

使用 GetRange 对某个 user_id 下某段时间范围的所有的数据进行查询:
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    // 设置起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.fromLong(1478660726));
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());

    // 设置结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.fromLong(1479265526));
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());

    // 设置读取最新版本
    rangeRowQueryCriteria.setMaxVersions(1);

    // 默认读取所有的属性列
    GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));

该查询等同于

SELECT * FROM UserHistory
WHERE user_id = '10100' AND time_stamp > 1478660726 AND time_stamp < 1479265526;
如果需要继续对属性列做条件查询,可以使用 过滤器功能, 如下查询某个 user_id 下某所有的收藏记录:

    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    // 设置起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MIN);
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());

    // 设置结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());

    // 设置属性列的过滤条件: behavior_type = 'collect'
    SingleColumnValueFilter filter = new SingleColumnValueFilter("behavior_type", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("collect"));
    // 表格存储是 schemafree 模型,有些行不包括属性列 behavior_type
    // 设置为 false 表示如果该行没有属性列 behavior_type,则不满足条件条件
    filter.setPassIfMissing(false);
    rangeRowQueryCriteria.setFilter(filter);

    // 设置读取最新版本
    rangeRowQueryCriteria.setMaxVersions(1);

    // 默认读取所有的属性列
    GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));

该查询等同于

SELECT * FROM UserHistory
WHERE user_id = '10100' AND behavior_type = 'collect';

当然,也可以通过如下的方式来实现:

    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);
    // 设置起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.INF_MIN);
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MIN);
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());

    // 设置结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.INF_MAX);
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());

    // 设置数据过滤条件:user_id='10100' 并且 behavior_type = 'collect'
    SingleColumnValueFilter filter1 = new SingleColumnValueFilter("user_id", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("10100"));
    SingleColumnValueFilter filter2 = new SingleColumnValueFilter("behavior_type", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("collect"));
    CompositeColumnValueFilter filter = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.AND);
    filter.addFilter(filter1);
    filter.addFilter(filter2);
    rangeRowQueryCriteria.setFilter(filter);

该实现对整张表进行了扫描,并找出 user_id='10100' AND behavior_type='collect' 的记录,但是由于是全表扫描,其效率会远远低于基于特定主键范围的查询。

需要了解的几个关键事项:

  1. 过滤器 Filter 可以支持最多10个条件组合,可以用于 GetRow、BatchGetRow 和 GetRange 接口中。
  2. 过滤器 Filter 是对GetRange的数据在服务端进行过滤,并不会减少磁盘的IO次数,但是能够有效的降低网络传输流量。
  3. 良好的主键设计能够大大提交范围查询的效率。

更新数据

SQL

关系数据库中,可以使用 UPDATE 语句对表中的一行或者多行记录进行修改:

UPDATE UserHistory
    SET behavior_type = 'collect'
    WHERE user_id = '10100' AND time_stamp = 1479265526 AND behavior_count > 4.0;

表格存储

使用表格存储中可以使用 UpdateRow 接口更新一行数据:

    // 设置主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("10100"));
    primaryKeyBuilder.addPrimaryKeyColumn("time_stamp", PrimaryKeyValue.fromLong(1479265526));
    PrimaryKey primaryKey = primaryKeyBuilder.build();

    // 设置更新条件:期望原行存在, 且behavior_count的值大于4.0时更新
    Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
    condition.setColumnCondition(new SingleColumnValueCondition("behavior_count", SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromDouble(4.0)));
    rowUpdateChange.setCondition(condition);

    // 设置属性列的值
    RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey);
    rowUpdateChange.put(new Column("behavior_type", ColumnValue.fromSting("collect")));

    // 插入该行数据
    client.updateRow(new UpdateRowRequest(rowUpdateChange));

使用UpdateRow接口需要了解一下几个关键事项:

  1. DeleteRow 需要指定表名 TABLE_NAME 和全部的主键 primaryKey ,更新的列可以存在或者不存在
  2. UpdateRow 只会修改这一行中需要修改的列,PutRow则会使用新的数据覆盖原来整行的数据
  3. 更新可以设置两种条件检查:行存在检查和条件检查
  4. SQL中 UPDATE 会对满足 WHERE 的所有记录做更新,表格存储的 UpdateRow 只更新指定主键的一行数据,条件检查也只针对本行的主键列或者属性列做检查。
  5. 多条记录的更新可以使用 BatchWriteRow 接口,可以大大提高数据的写入速度。

删除表

SQL

关系数据库中,可以使用 DROP TABLE语句来删除不再需要的数据表:

DROP TABLE UserHistory;

表格存储

使用表格存储中可以使用 DeleteTable 接口删除数据表:

    DeleteTableRequest request = new DeleteTableRequest(TABLE_NAME);
    client.deleteTable(request);

需要注意:表一经删除将无法恢复。

时间: 2024-09-11 17:15:43

从SQL到NoSQL—如何使用表格存储的相关文章

表格存储技术方案实践及客户案例分享

表格存储是一款2014年10月份正式商业化的NoSQL数据存储服务,在商业化之前,早在2010年就在阿里云内部开始使用,云邮箱和云OS都是表格存储最早的一批用户.到目前,无论是在阿里集团内部还是在公共云环境上,在移动社交.金融风控.电商物流.存储备份.物联网IoT.日志监控.大数据分析报表等领域都有着广泛的用户基础与成熟的实践方案. 为了方便更多的用户了解和使用表格存储,该帖子会将最近非常有参考意义的方案设计.技术实践及相关客户分享的博客文章汇总到这里,大家可以在这里快速查找到和自己业务场景相近

基于表格存储的高性能监控数据存储计算方案

概述         随着软件架构的愈发复杂,了解系统现状.调查问题的困难度也增加了很多.此时,一套完善的监控方案能够让开发和运维工程师快速排查问题,更好的维护系统的稳定性.        开源监控方案中,Zabbix.Nagios都是不错的监控软件,可以针对数十万的设备监控数百万的指标,强大的功能让开发和运维都很赞叹.但是,网上经常看到的抱怨是其写入和存储能力的不足,以Zabbix为例,文章[1]提到使用NoSQL方案(HBase.Cassandra.Riak)比利用传统RDBMS方案(MyS

使用HBase Client访问阿里云NoSQL数据库表格存储

Apache HBase Apache HBase是Hadoop database,属于Hadoop生态系统. 自从十四年前Google相继发布论文:<The Google File System>.<MapReduce: Simplified Data Processing on Large Clusters>和<Bigtable: A Distributed Storage System for Structured Data>后,开源界开始模仿论文设计开源版本的这

阿里云表格存储技术分享

  下面是之前在一个技术群里面分享的阿里云表格存储的内容,因为时间因素,只对[技术分享附件]中的少部分内容进行了分享,下面是分享内容,欢迎下载附件并就里面的内容深入交流.   接下来的内容分为几个方面,第一是背景,就是为什么要做这个东西:第二是几个使用场景,让大家有个感性的认识:第三是系统架构以及该架构如何做到高性能.高可靠.高可用:第四是一些工程经验:我也比较希望大家看看最后的附录中我对垂直和分层两大设计体系的思考,这部分我们可以做更深入的交流.     好,下面正式开始.先介绍为什么要做,大

表格存储服务在社交应用场景的实践

阿里云的表格存储服务(http://www.aliyun.com/product/ots)是一款面向PB级结构化/半结构化数据存储和百万级高并发读写访问的NoSQL数据库服务,在移动社交场景中有着非常广发的应用,如今非常火热的钉钉也将后台的消息推送和存储功能从MySQL迁移到表格存储上,以获得更加优秀的高并发和规模扩展能力:同时也有非常多的创业企业将企业自身针对客户的消息推送能力基于表格存储来构建.本文将详细介绍表格存储在移动社交中的技术实践.本文的主要内容已经在2016年云栖大会深圳场的存储论

表格存储在QCon2017的分享

        在QCon2017的基础设施专场,笔者以表格存储为基础分享了分布式系统设计的几点考虑,主要是扩展性.可用性和性能.每个点都举了一个具体的例子来阐述.这里对这次分享做一次简单的总结.        首先,说到了表格存储产生的背景,大规模.弱关系数据,对灵活schema变动的需求,传统数据库无法很好的满足,NOSQL的出现是一个很好的补充.NOSQL不是为了取代SQL,也无法取代SQL,是已有数据库生态的很好补充.我认为未来会出现更多种类的数据库,面向不同的业务,使用不同的硬件,数据

Sqoop:SQL与NoSQL间的数据桥梁

SQL处理二维表格数据,是一种最朴素的工具,NoSQL是Not Only SQL,即不仅仅是SQL.从MySQL导入数据到HDFS文件系统中,最简单的一种方式就是使用Sqoop,然后将HDFS中的数据和Hive建立映射.通过Sqoop作为数据桥梁,将传统的数据也存入到NoSQL中来了,有了数据,猴戏才刚刚开始. 猴年伊始 SQL处理二维表格数据,是一种最朴素的工具,查询.更新.修改.删除这四种对数据的基本操作,是处理数据的一个巨大进步.近些年,各种新的数据处理技术兴起了,都想革SQL的命,这些技

老司机带你用MaxCompute和表格存储玩转车联网数据

"自动驾驶汽车"在近两年频频出现于各大科技新闻头条,自2012年谷歌获得美国首个自动驾驶汽车许可证以来,国外各大知名汽车厂商如奔驰.沃尔沃.大众.通用.丰田.日产.特斯拉等也纷纷宣布自己的自动驾驶汽车验证开发计划.自动驾驶依托于人工智能技术的发展,而对于一个人工智能平台来说,重要的不光是算法和平台,更重要的是数据!今天我们暂且不聊自动驾驶,我们先聊聊最基础的车联网数据的存储与处理. 初始方案 出于对两客一危监管的需要,车联网很早就开始起步,彼时大家的车联网方案都长这个样子:   将车辆

解析SQL与NoSQL的融合架构产品GBase UP

文章讲的是解析SQL与NoSQL的融合架构产品GBase UP,本文根据[DTCC2016中国数据库技术大会]现场演讲嘉宾武新博士分享内容整理而成.录音整理及文字编辑IT168@杨璐 讲师简介 武新博士 武新,博士,现任南大通用高级副总裁兼CTO. 第五批"国家千人计划" 专家,2010年获得中组部实施的国家"千人计划"荣誉(海外高层次人才引进计划);曾作为资深数据库专家,在甲骨文公司(法国)任职11年;曾是法国 EKIP 软件公司的技术负责人.法国电信软件开发工程