表格存储(Tablestore)入门指南

本文涉及的产品
对象存储 OSS,20GB 3个月
文件存储 NAS,50GB 3个月
日志服务 SLS,月写入数据量 50GB 1个月
简介: 表格存储(Tablestore)入门指南内容简介了表格存储(Tablestore)是阿里云自研的 NoSQL 多模型数据库,提供海量结构化数据存储以及快速的查询和分析服务。

表格存储(Tablestore)入门指南

内容简介

表格存储(Tablestore)是阿里云自研的 NoSQL 多模型数据库,提供海量结构化数据存储以及快速的查询和分析服务。表格存储的分布式存储和强大的索引引擎能够提供 PB 级存储、千万 TPS 以及毫秒级延迟的服务能力。

本文将以一个简单的学生成绩查询demo为例,向大家演示如何使用Tablestore提供的Java SDK实现一个表格数据的导入、查询(主键索引、二级索引和多元索引)和导出

demo中表格(table)的存储信息格式如下:

ID(主键) 班级(主键) 姓名(主键) 语文 数学 英语
0 初三1班 云知 99 99 99

主要实现的功能如下:

  • 创建学生成绩的数据表格;
  • 添加学生成绩信息;
  • 查询学生成绩信息;
  • 更新学生成绩信息;
  • 删除学生成绩信息;
  • 查询特定班级的学生成绩信息(二级索引);
  • 查询多科目特定分段的学生成绩信息(多元索引);
  • 导出新增学生成绩信息(通道服务)。

一、配置开发环境

Tablestore的Java SDK开发环境非常简单,主要包括:

   * 了解并开通阿里云表格存储服务

   * 创建AccessKey

   * 配置Java环境(建议:JDK 6及以上版本)

   * 使用Maven项目加入依赖项

<dependencies>
     <dependency>
         <groupId>com.aliyun.openservices</groupId>
         <artifactId>tablestore</artifactId>
         <version>4.12.1</version>
     </dependency>
</dependencies>

二、表格的一般操作

1、获取实例的控制权限

首先创建实例,实例是表格存储资源管理的基础单元,表格存储对应用程序的访问控制和资源计量都在实例级别完成。

实例创建成功后,可以通过“SyncClient client”获取实例控制权柄,然后通过client实现对实例的各种控制。

/**
   * 以下信息可由阿里云控制台获取,依次为:
   * endPoint(实例访问地址)
   * accessId(AccessKey ID)
   * accessKey(Access Key Secret)
   * instanceName(实例名称,用户创建实例时指定)
   */
private static final String endPoint = "https://xxxx.cn-hangzhou.ots.aliyuncs.com";
private static final String accessId = "LTAIxxxebxxxKIxx";
private static final String accessKey = "5P7xxxMm1xxxhHPxxxXnNxxxXscxxx";
private static final String instanceName = "instance-1";
SyncClient client = new SyncClient(endPoint, accessId, accessKey, instanceName);

2、创建学生成绩的数据表格

在创建学生成绩的数据表格时需要描述表的结构信息(TableMeta)和配置信息(TableOptions)。

image

public static void creatTable(){
        System.out.println("开始创建表格。");
          //描述表的结构信息
        TableMeta tableMeta = new TableMeta(tableName);
  
        //添加主键列
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("ID", PrimaryKeyType.INTEGER));
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("班级", PrimaryKeyType.INTEGER));
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema("姓名", PrimaryKeyType.STRING));
  
        //添加属性列
        tableMeta.addDefinedColumn(new DefinedColumnSchema("语文", DefinedColumnType.INTEGER));
        tableMeta.addDefinedColumn(new DefinedColumnSchema("数学", DefinedColumnType.INTEGER));
        tableMeta.addDefinedColumn(new DefinedColumnSchema("英语", DefinedColumnType.INTEGER));
         
        int timeToLive = -1; // 数据的过期时间, 单位秒, -1代表永不过期. 假如设置过期时间为一年, 即为 365 * 24 * 3600.
        int maxVersions = 1; // 最大保存版本数, maxVersions大于1时, 无法使用二级索引和多元索引功能.
        
          //描述表的配置信息
        TableOptions tableOptions = new TableOptions(timeToLive, maxVersions);
  
          //将表的结构信息和配置信息封装到一个request里
        CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions);

        //创建表格
        try {
            client.createTable(request);
            System.out.println("创建表格成功。");
        } catch (TableStoreException e) {
            System.err.println("操作失败,详情:" + e.getMessage());
            System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
            System.err.println("请求失败,详情:" + e.getMessage());
        }
    }

3、添加学生成绩信息

PutRow 接口用于插入一行数据,如果原来该行已经存在,会覆盖原来的一行。

明确主键信息和属性信息,我们便可以使用PutRow接口将该信息添加入表中。

image

public static void creatRow(){
        //描述主键信息
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.fromLong(3));
        primaryKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.fromLong("初三2班"));
        primaryKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.fromLong("云知"));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
        RowPutChange rowPutChange = new RowPutChange(tableName, primaryKey);
  
        //描述属性信息
        rowPutChange.addColumn(new Column("语文", ColumnValue.fromLong(rand.nextInt(99))));
        rowPutChange.addColumn(new Column("数学", ColumnValue.fromLong(rand.nextInt(99))));
        rowPutChange.addColumn(new Column("英语", ColumnValue.fromLong(rand.nextInt(99))));
          
          //添加新数据到表格
        try {
                client.putRow(new PutRowRequest(rowPutChange));
                System.out.println("添加数据成功。");
        } catch (TableStoreException e) {
                System.err.println("操作失败,详情:" + e.getMessage());
                System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
                System.err.println("请求失败,详情:" + e.getMessage());
        }
        
}

4、查询学生成绩信息

查询单条学生成绩信息

通过描述主键信息,可以在数据库中唯一的确认一条学生信息。

以此主键为索引,可以使用 GetRow 接口读取一行数据。

在描述主键信息时,必须保证主键信息的完整性(即,包含所有主键的对应值),因为只有这样才能保证信息在表内是唯一的。

image

public static void retrieveRow() {
         //构建主键
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.fromLong(3));
        primaryKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.fromLong("初三2班"));
        primaryKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.fromLong("云知"));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
          
        //读取一行
        SingleRowQueryCriteria rowQueryCriteria = new SingleRowQueryCriteria(tableName, primaryKey);

        //设置读取最新版本
        rowQueryCriteria.setMaxVersions(1);
        
        try {
                GetRowResponse getRowResponse = client.getRow(new GetRowRequest(rowQueryCriteria));
                Row row = getRowResponse.getRow();
                System.out.println("查询单条数据成功。");
        } catch (TableStoreException e) {
                System.err.println("操作失败,详情:" + e.getMessage());
                System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
                System.err.println("请求失败,详情:" + e.getMessage());
        }
}

查询多条学生成绩信息

由于主键是有序的,因此可以通过构建Min主键和Max主键,在表内唯一的限定一部分学生信息并将其返回。

下面这个例子,是返回“ID”在50-100之间的学生信息。

image

public static void retrieveRangeRow() {
        //构建Min主键
        PrimaryKeyBuilder primaryMinKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryMinKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.fromLong(50));
        primaryMinKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.INF_MIN);
        primaryMinKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.INF_MIN);
        PrimaryKey primaryMinKey = primaryMinKeyBuilder.build();

        //构建Max主键
        PrimaryKeyBuilder primaryMaxKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryMaxKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.fromLong(101));
        primaryMaxKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.INF_MAX);
        primaryMaxKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.INF_MAX);
        PrimaryKey primaryMaxKey = primaryMaxKeyBuilder.build();

        RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(tableName);
        rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryMinKey);
        rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryMaxKey);

        rangeRowQueryCriteria.setMaxVersions(1);
        try {
            GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
            List<Row> rows = getRangeResponse.getRows();
            System.out.println("查询多条数据成功。");
        } catch (TableStoreException e) {
            System.err.println("操作失败,详情:" + e.getMessage());
            System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
            System.err.println("请求失败,详情:" + e.getMessage());
        }
    }

5、修改学生成绩信息

准确描述主键信息后,我们可以定位到数据表内的唯一数据信息,并修改它。

UpdateRow 接口用于更新一行数据,如果原行不存在,会新写入一行。

public static void updataRow(){
        //构建主键
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.fromLong(3));
        primaryKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.fromLong("初三2班"));
        primaryKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.fromLong("云知"));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
        RowPutChange rowPutChange = new RowPutChange(tableName, primaryKey);
  
        //构建属性列
        rowPutChange.addColumn(new Column("语文", ColumnValue.fromLong(rand.nextInt(100))));
        rowPutChange.addColumn(new Column("数学", ColumnValue.fromLong(rand.nextInt(100))));
        rowPutChange.addColumn(new Column("英语", ColumnValue.fromLong(rand.nextInt(100))));
        
        //添加新数据到表格
        try {
                client.updateRow(new UpdateRowRequest(rowUpdateChange));
                System.out.println("更新数据成功。");
        } catch (TableStoreException e) {
                System.err.println("操作失败,详情:" + e.getMessage());
                System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
                System.err.println("请求失败,详情:" + e.getMessage());
        }
}

6、删除学生成绩信息

准确描述主键信息后,我们可以定位到数据表内的唯一数据信息,并使用DeleteRow 接口删除它。

private static void deleteRow(SyncClient client, String pkValue) {
        //构建主键
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.fromLong(3));
        primaryKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.fromLong("初三2班"));
        primaryKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.fromLong("云知"));
        PrimaryKey primaryKey = primaryKeyBuilder.build();

        RowDeleteChange rowDeleteChange = new RowDeleteChange(tableName, primaryKey);
        
        try {
                GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
        } catch (TableStoreException e) {
                System.err.println("操作失败,详情:" + e.getMessage());
                System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
                System.err.println("请求失败,详情:" + e.getMessage());
        }
        client.deleteRow(new DeleteRowRequest(rowDeleteChange));
}

7、删除表

public static void deleteTable(){
        DeleteTableRequest request = new DeleteTableRequest(tableName);
        try {
            client.deleteTable(request);
        } catch (TableStoreException e) {
            System.err.println("操作失败,详情:" + e.getMessage());
            System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
            System.err.println("请求失败,详情:" + e.getMessage());
        }
    }

三、二级索引

在我们的demo中,我们使用 “ID+班级+姓名”这三个主键来唯一的确定一条学生成绩信息。

由于主键是顺序存储在数据库中的,所以我们可以使用retrieveRangeRow()函数,通过在其中设置“Min主键”和“Max主键”的方式,对ID进行范围查询。

但是当我们期望获取某个范围的班级的时候,因为“班级”并不是主键存储的第一索引,这个思路便失效了。

Tablestore提供了二级索引,以便于解决这个问题。

二级索引可以提供一份以新的关键字(原表的主键和属性皆可)为第一索引的数据表,方便用户使用范围查询去查询这个关键字对应的数据信息。

image

1、创建二级索引

创建二级索引主要是声明一个新的主键,下面的例子就是将“班级”声明为新的二级索引的主键,最终形成“班级+ID+姓名”的索引表。

public static void createIndex() {
        System.out.println("indexName = "+indexName);
        IndexMeta indexMeta = new IndexMeta(indexName); // 要创建的索引表名称。
        indexMeta.addPrimaryKeyColumn("班级"); // 为索引表添加主键列。
        CreateIndexRequest request = new CreateIndexRequest(tableName, indexMeta, true);

        try {
            client.createIndex(request);
            System.out.println("创建索引成功。");
        } catch (TableStoreException e) {
            System.err.println("操作失败,详情:" + e.getMessage());
            System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
            System.err.println("请求失败,详情:" + e.getMessage());
        }

    }

2、查询特定班级的学生成绩信息

以下使用新声明的二级索引查询“班级”为初二1班、初二2班和初二3班的学生成绩信息。

思路同基本的范围查询相同:声明Min,Max主键值,然后在二级索引表中查询到该范围内的所有信息的主键值,再返回到原表查询完整的学生信息即可。

image

public static void getRangeRow(){
        System.out.println("开始查询数据。");
        //构建Min主键
        PrimaryKeyBuilder primaryLKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryLKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.fromString("初二1班"));
        primaryLKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.INF_MIN);
        primaryLKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.INF_MIN);
        PrimaryKey startPrimaryKey = primaryLKeyBuilder.build();

        //构造Max间主键
        PrimaryKeyBuilder primaryRKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryRKeyBuilder.addPrimaryKeyColumn("班级", PrimaryKeyValue.fromString("初二3班"));
        primaryRKeyBuilder.addPrimaryKeyColumn("ID", PrimaryKeyValue.INF_MAX);
        primaryRKeyBuilder.addPrimaryKeyColumn("姓名", PrimaryKeyValue.INF_MAX);
        PrimaryKey endPrimaryKey = primaryRKeyBuilder.build();

        RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(indexName);
        rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKey);
        rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKey);

        rangeRowQueryCriteria.setMaxVersions(1);
        try {
            GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
            List<Row> rows = getRangeResponse.getRows();
            System.out.println("查询到的行数"+rows.size());
           for (int i = 0; i < rows.size(); i++) {
                long index = rows.get(i).getPrimaryKey().getPrimaryKeyColumn("ID").getValue().asLong();
                Fmt.PrintRow(rows.get(i));
            }
        } catch (TableStoreException e) {
            System.err.println("操作失败,详情:" + e.getMessage());
            System.err.println("Request ID:" + e.getRequestId());
        } catch (ClientException e) {
            System.err.println("请求失败,详情:" + e.getMessage());
        }
    }

3、删除二级索引

我们可以通过表名字和二级索引名来唯一的确定一个二级索引,然后通过DeleteIndexRequest(String tableName, String indexName)函数,将其删除。

public static void deleteIndex() {
        DeleteIndexRequest request = new DeleteIndexRequest(tableName, indexName); // 要删除的索引表及主表名
        client.deleteIndex(request);
    }

四、多元索引

当我们要对多个字段进行联合查询的时候,就很难通过前边的思路找到一个切实可行的方案。

因此Tablestore提供了多元索引,可以让我们轻松实现多种高效的索引结构解决大数据的复杂查询难题。

下面,我们将使用多元索引去实现对三科成绩同时限定区间的查询(例如,三科成绩都大于60分的人数),更多的实现可以查阅官方多元索引开发指南

1、创建多元索引

我们可以在一张表上创建多个多元索引,在创建多元索引时可以指定索引名和索引结构。

public static void createSearchIndex(){
        CreateSearchIndexRequest request = new CreateSearchIndexRequest();
        request.setTableName(tableName);
        request.setIndexName(searchIndexName);
        IndexSchema indexSchema = new IndexSchema();
        indexSchema.setFieldSchemas(Arrays.asList(
                new FieldSchema("语文", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true),
                new FieldSchema("数学", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true),
                new FieldSchema("英语", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true)));
        request.setIndexSchema(indexSchema);
        client.createSearchIndex(request);
        System.out.println("创建SearchIndex成功。");
    }

2、查询多科目特定分段的学生成绩信息

我们使用BoolQuery进行多条件组合查询,在其中包含了三个子查询条件:rangeChineseQuery,rangeMathQuery和rangeEnglishQuery。

将他们封装到BoolQuery中形成一个组合查询条件,查询三个成绩均大于60分的学生成绩信息。

public static void boolSearchQuery(){
        RangeQuery rangeChineseQuery = new RangeQuery(); // 设置查询类型为RangeQuery
        rangeChineseQuery.setFieldName("语文");  // 设置针对哪个字段
        rangeChineseQuery.greaterThan(ColumnValue.fromLong(60));  // 设置语文成绩大于60
      
        RangeQuery rangeMathQuery = new RangeQuery(); // 设置查询类型为RangeQuery
        rangeMathQuery.setFieldName("数学");  // 设置针对哪个字段
        rangeMathQuery.greaterThan(ColumnValue.fromLong(60));  // 设置数学成绩大于60
      
        RangeQuery rangeEnglishQuery = new RangeQuery(); // 设置查询类型为RangeQuery
        rangeEnglishQuery.setFieldName("英语");  // 设置针对哪个字段
        rangeEnglishQuery.greaterThan(ColumnValue.fromLong(60));  // 设置英语成绩大于60
       
        SearchQuery searchQuery = new SearchQuery();
        BoolQuery boolQuery = new BoolQuery();
        boolQuery.setMustQueries(Arrays.asList(rangeChineseQuery, rangeMathQuery, rangeEnglishQuery));
        searchQuery.setQuery(boolQuery);
        searchQuery.setGetTotalCount(true);
        SearchRequest searchRequest = new SearchRequest(tableName, searchIndexName, searchQuery);
        SearchResponse resp = client.search(searchRequest);
        System.out.println("Row: " + resp.getRows());
    }

3、删除多元索引

我们可以通过表名字和多元索引名来唯一的确定一个多元索引,然后通过clinet.deleteSearchIndex(DeleteSearchIndexRequest request)函数,将其删除。

public static void deleteSearchIndex() {
        DeleteSearchIndexRequest request = new DeleteSearchIndexRequest();
        request.setTableName(tableName);
        request.setIndexName(searchIndexName);
        client.deleteSearchIndex(request);
        System.out.println("删除SearchIndex成功。");
}

五、通道服务

1、创建通道

通道的类型主要分为三类:全量(BaseData)、增量(Stream)和全量加增量(BaseAndStream)。

我们可以通过设置通道类型,限定通道获取数据的范围。

image

TunnelClient tunnelClient = new TunnelClient(endPoint, accessId, accessKey, instanceName);
    public static void createTunnel() {
        CreateTunnelRequest request = new CreateTunnelRequest(tableName, tunnelName, TunnelType.BaseData);
        CreateTunnelResponse resp = tunnelClient.createTunnel(request);
        System.out.println("RequestId: " + resp.getRequestId());
        System.out.println("TunnelId: " + resp.getTunnelId());
    }

2、导出学生信息

用户调用printAllRow()函数可以开启一个通道服务,使得通道自动调用process()函数内的逻辑。

public static class PrintProcessor implements IChannelProcessor {
        @Override
        public void process(ProcessRecordsInput input) {
            System.out.println("Default record processor, would print records:");
            System.out.println(input.getRecords());
            try {
                // Mock Record Process.
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void shutdown() {
            System.out.println("Mock shutdown");
        }
    }

    public static void printAllRow(){        
        ListTunnelRequest request = new ListTunnelRequest(tableName);
        ListTunnelResponse resp = tunnelClient.listTunnel(request);
        // tunnelId会用于后续TunnelWorker的初始化, 该值同样可以通过ListTunnel或者DescribeTunnel获取。
        String tunnelId = resp.getTunnelInfos().get(0).getTunnelId();
        System.out.println(tunnelId);
        TunnelWorkerConfig config = new TunnelWorkerConfig(new PrintProcessor());
        TunnelWorker worker = new TunnelWorker(tunnelId, client, config);
        try {   
            worker.connectAndWorking();
        } catch (Exception e) {
            e.printStackTrace();
            worker.shutdown();
            client.shutdown();
        }
    }

3、删除通道

public static void deleteTunnel() {
        DeleteTunnelRequest request = new DeleteTunnelRequest(tableName, tunnelName);
        DeleteTunnelResponse resp = tunnelClient.deleteTunnel(request);
        System.out.println("RequestId: " + resp.getRequestId());
    }

附录

更多精彩文章

《表格存储Tablestore权威指南(持续更新)》

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
阿里云表格存储使用教程
表格存储(Table Store)是构建在阿里云飞天分布式系统之上的分布式NoSQL数据存储服务,根据99.99%的高可用以及11个9的数据可靠性的标准设计。表格存储通过数据分片和负载均衡技术,实现数据规模与访问并发上的无缝扩展,提供海量结构化数据的存储和实时访问。 产品详情:https://www.aliyun.com/product/ots
目录
相关文章
|
3月前
|
存储 算法 数据挖掘
表格存储(Tablestore)支持 Serverless 低成本向量检索服务
在当今 GPT 技术盛行的时代,大模型推动了向量检索技术的迅猛发展。向量检索相较于传统的基于关键词的检索方法,能够更精准地捕捉数据之间的语义关系,极大提升了信息检索的效果。特别是在自然语言处理、计算机视觉等领域,向量能够将不同模态的数据在同一空间中进行表达和检索,推动了智能推荐、内容检索、RAG 和知识库等应用的广泛普及。阿里云表格存储(Tablestore)的多元索引提供了向量检索能力。表格存储是一款 Serverless 的分布式结构化数据存储服务,诞生于 2009 年阿里云成立时,主要特点是分布式、Serverless 开箱即用、按量付费、水平扩展和查询功能丰富和性能优秀等。
423 13
|
存储 NoSQL Java
OTS(Table Store)
OTS(Table Store)是阿里云提供的分布式NoSQL数据库服务,支持海量结构化数据的存储、查询和分析。OTS具有高可用、高性能、高扩展性和低成本等特点,适用于各种场景下的数据存储和处理,例如电商、物流、游戏等。
4305 2
|
存储 SQL NoSQL
表格存储 Tablestore 十年发展总结
这篇文章接下来会先整体介绍下表格存储 Tablestore,之后会分享下在技术层面产品这几年的功能演进、技术架构演进以及稳定性优化相关的工作,以及在业务层面我们定义的核心应用场景和一些典型案例。
66795 7
表格存储 Tablestore 十年发展总结
|
NoSQL 开发工具
TableStore表格存储(阿里云OTS)多行数据操作查询,支持倒序,过滤条件和分页
1. 批量读取操作 批量读取操作可以通过多种方式进行,包括: GetRow:根据主键读取一行数据。 BatchGetRow:批量读取多行数据。 GetRange:根据范围读取多行数据。
873 0
|
存储 NoSQL
|
存储 SQL NoSQL
表格存储 Tablestore SQL 商业版介绍
表格存储(Tablestore)是阿里云自研的多模型结构化数据存储,提供海量结构化数据存储以及快速的查询和分析服务。表格存储的分布式存储和强大的索引引擎能够支持 PB 级存储、千万 TPS 以及毫秒级延迟的服务能力。使用表格存储你可以方便的存储和查询你的海量数据。 表格存储在 21 年 9 月正式公测了 SQL 功能,使得你在享受表格存储全托管,灵活的存储能力之外,可以让你的业务迁移更加平顺。经
1209 0
表格存储 Tablestore SQL 商业版介绍
|
存储 自然语言处理 NoSQL
表格存储 Node.js SDK 开发入门
本文将结合电商订单场景为例,介绍表格存储 Tablestore Node.js SDK 的基本使用方法。
411 1
|
存储 SQL 运维
Tablestore 控制台入门指南
通过阅读本文您将了解和学习到如何通过表格存储Tablestore控制台快速搭建和操作一款零运维、无限容量的数据库。表格存储Tablestore提供了一定使用量的免费额度(10GB数据存储量、1000万按量读写吞吐),供大家体验测试使用。下面将开始介绍如何通过Tablestore控制台创建实例、创建数据表、读写数据、创建索引、搜索数据、删除索引和数据表。
539 0
Tablestore 控制台入门指南
|
存储 运维 NoSQL
表格存储 Tablestore 简介
近十年来互联网技术得到了飞速的发展,越来越多的行业逐渐加入到了互联网的阵营中来,同时也产生了更丰富、更复杂的业务场景和需求,这对于数据应用系统的性能无疑是巨大的挑战。传统关系型数据库有什么瓶颈,如何通过分布式数据库表格存储 Tablestore 进行优化?
932 0
|
缓存 运维 NoSQL
使用 Blink 访问表格存储 Tablestore
本文介绍如何使用实时计算 Blink 服务访问表格存储服务(Tablestore),并进行开发。背景Blink 产品介绍阿里云实时计算Flink版(Alibaba Cloud Realtime Compute for Apache Flink,Powered by Ververica)是阿里云基于Apache Flink构建的企业级、高性能实时大数据处理系统,由Apache Flink创始团队官方
558 0
使用 Blink 访问表格存储 Tablestore