Redis介绍与使用

news2024/9/26 5:12:11

1、Nosql

1.1 数据存储的发展
1.1.1 只使用Mysql

以前的网站访问量不大,单个数据库是完全够用的。

但是随着互联网的发展,就出现了很多的问题:

  • 数据量太大,服务器放不下
  • 访问量太大,服务器也承受不了
1.1.2 缓存+Mysql(多台服务器)+读写分离

相同的数据不断的查询数据库比较浪费性能,这时候就会加上缓存,用来减轻服务器的压力提高效率(但同步也是一个问题)

1.1.3 分库分表+数据库集群

由于用户量的增加,读数据由缓存来减轻压力所以数据的压力从读数据到了写数据

  • 数据量多变化快
  • 数据量大(博客,小说等)

用户产生的数据库增长量太快,这个用Nosql可以很好的处理这些问题

1.2 什么是Nosql

Nosql = Not Only Sql

泛指非关系型数据库

  • 关系型数据库:表格、行、列
  • 非关系型数据库:没有固定的存储格式,什么类型的数据都可以存储
1.3 Nosql特点
  • 数据之间没有关系,方便拓展

  • 大数据量的性能高

  • 数据类型多样性(不需要事先设计数据库,随存随取)

  • 没有固定的查询语言

  • 键值对存储、列存储、文档存储、图形数据库

  • CAP定理和BASE

1.5 Nosql分类
  • 键值(Key-Value)存储数据库

这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果数据库管理员(DBA)只对部分值进行查询或更新的时候,Key/value就显得效率低下了。举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB。

  • 列存储数据库

这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.

  • 文档型数据库

文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值,在处理网页等复杂数据时,文档型数据库比传统键值数据库的查询效率更高。如:CouchDB, MongoDb(json形式). 国内也有文档型数据库SequoiaDB,已经开源。

  • 图形(Graph)数据库

图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph。

1.6 不同分类的特点
分类Examples举例典型应用场景数据模型优点缺点
键值(key-value)Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。Key 指向 Value 的键值对,通常用hash table来实现查找速度快数据无结构化,通常只被当作字符串或者二进制数据
列存储数据库Cassandra, HBase, Riak分布式的文件系统以列簇式存储,将同一列数据存在一起查找速度快,可扩展性强,更容易进行分布式扩展功能相对局限
文档型数据库CouchDB, MongoDbWeb应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容)Key-Value对应的键值对,Value为结构化数据数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构查询性能不高,而且缺乏统一的查询语法。
图形(Graph)数据库Neo4J, InfoGrid, Infinite Graph社交网络,推荐系统等。专注于构建关系图谱图结构利用图结构相关算法。比如最短路径寻址,N度关系查找等很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。

2、Redis简介

2.1 概述

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

2.2 作用
  • 内存存储、持久化
  • 效率高,用于高速缓存
  • 发布订阅系统(简单的消息队列)
  • 地图信息分析
  • 计时器、计数器(浏览量)
2.3 特性
  • 多样的数据类型
  • 持久化
  • 集群
  • 事务
2.4 基本知识
  • 基本命令
    select 2  # 选择3号数据库redis有16个数据库,默认使用的是第0个,可以使用select进行切换
    DBSIZE  # 查看DB大小
    keys *  # 查看数据库所有的key
    flushdb  # 清空当前数据库数据库
    FLUSHALL # 清空所有数据的的数据
    exists name # 判断name是否存在,0不存在 1存在
    move name 1 # 移动name到1号数据库
    del name # 删除name
    expire name 10 # 设置name 10s后过期
    ttl name # 查看剩余的过期时间
    type name # 查看name的类型
  • Redis是单线程的

    redis是基于内存操作的,CPU不是Redis的性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽的,不需要用到多线程,就直接用单线程。

  • 为什么单线程还这么快

    redis是把所有的数据放在内存中,所以用单线程操作效率最高,多线程会进行上下文切换,这个是需要耗时的,对于内存系统来说,没有上下文切换效率是就是最高的。

2.5 window下的安装
  • 解压压缩包
  • 安装服务
    • 进入解压的路径
    • 输入 redis-server.exe --service-install redis.windows.conf --service-name redis --loglevel verbose
    • 出现安装成功即可,去服务查看
    • 启动服务:redis-server.exe --service-start --service-name redis (后续启动Redis只需要这个命令就可以了)
    • 停止服务:redis-server.exe --service-stop --service-name redis
    • 卸载服务:redis-server.exe --service-uninstall--service-name redis

3、五大基本数据类型

3.1 String
SET name kk  # 设置name为ab
GET name # 获取name
APPEND name "cd" # 追加内容
STRLEN name # 获取长度
​
SET count 0 # 设置count:0
INCR count # 自增
DECR count # 自减
INCRBY count 10 # 步长+10
DECRBY count 5 # 步长-5
​
GETRANGE name 0 3 # 获取0-3的内容,包括0和3
GETRANGE name 0 -1 # 获取所有字符串
SETRANGE name 1 ss # 从1的位置替换字符串 abcd -> assd
​
SETEX sex 10 "male" # 10s过期
SETNX name kk # 判断是否存在,不存在创建,存在则失败
​
MSET k1 v1 k2 v2 k3 v3 # 批量设置
MGET k1 k2 k3 # 批量获取
MSETNX k1 v1 k4 v4 # 不存在则创建k1,k4(原子性的操作,同时成功或者同时失败)
​
SET user:1 {name:kk,age:18} # 设置一个user,使用json保存数据
MSET user:2:name kk user:2:age 18 # redis中可以直接使用这种方式设置对象
MGET user:2:name user:2:age # 获取  user:{id}:{field}
​
GETSET name kk # 如果不存在值则返回 nil,并设置值
GETSET name ww # 如果存在值则获取原来的值并设置新的值
3.2 List
LPUSH list data1 # 将值插入列表头部
LRANGE list 0 -1 # 获取数据
RPUSH list data4 # 插入尾部
LPOP list # 左边移除
RPOP list # 右边移除
LINDEX list 1 # 通过下标获取数据
LLEN list # 获取长度
LREM list 1 data1 # 移除指定数量的指定数据
LREM list 2 data2 # 移除指定数量的指定数据
LTRIM list 0 2 # 截取指定的长度(闭区间) ltrim start stop,原先的list只剩下截取的内容
RPOPLPUSH list list2 # 移除list最后一个元素并且将这个元素加入到新列表list2中
LSET list 0 data1 # 将指定位置值替换
LINSERT list BEFORE data3333 data # 往data3333前面插入data
LINSERT list AFTER data3333 dataAfter# 往data3333前面插入dataAfter
  • 本质上是一个链表
  • 如果key不存在创建新链表
  • 存在新增内容
  • 可以做栈(lpush,lpop)、队列(lpush,lpop)
3.3 Set

set的值不能重复,无序

SADD myset data1 # 插入
SMEMBERS myset # 查询
SISMEMBER myset data1 # 查看是否有data1这个值
SREM myset data1 # 移除元素
SRANDMEMBER myset 1 # 随机抽选指定个数的元素
SPOP myset # 随机删除一个元素
SMOVE myset myset2 data3 # 移动一个值到另外一个set
SDIFF myset myset2 # 差集 myset2有myset没有的数据
SINTER myset myset2 # 交集 myset和myset2都有的数据
SUNION myset myset2 # 并集 myset和myset2的数据合并的结果
3.4 Hash

其实就是一个Map集合,和String类型没有太大区别,就是一个集合里面存多个key-value

HSET myhash key1 value1 # 插入数据,再次赋值是修改
HGET myhash key1 # 取值
HMSET myhash key2 value2 key3 value3 # 设置多个字段
HMGET myhash key1 key2 key3 # 获取多个字段
HGETALL myhash # 获取所有key-value
HDEL myhash key1 # 删除指定的key-value
HLEN myhash # 获取长度
HEXISTS myhash key1 # 判断指定字段是否存在
HKEYS myhash # 只获取key
HVALS myhash # 只获取value
HINCRBY myhash key4 -2 # 指定增量
HSETNX myhash key4 value4 # 如果不存在则可以设置,存在不能设置

更适合对象的存储,比如个人信息等

3.5 sorted set/zset(有序集合)

在set的基础上,增加了一个值 k s v

ZADD salary 1000 xaiomin # 添加一个值
ZADD salary 3000 xiaohong 2000 xiaolv # 添加多个值
ZRANGE salary 0 -1 # 查看
ZRANGEBYSCORE salary -inf +inf # 升序 负无穷 - 正无穷
ZRANGEBYSCORE salary -inf 2000 WITHSCORES # 自定义范围,并且附带对应的score值
ZREVRANGE salary 0 -1 WITHSCORES # 降序查询
ZCOUNT salary 1000 2000 # 查询 1000-2000有多少个数据
ZREM salary xiaolv # 删除

成绩表、工资表、排行榜等需要排序的

通过maven使用jedis

3、Jedis

Redis官方推荐的JAVA连接开发工具

3.1 依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->    
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
3.2 使用
@Test
void redisTest01() {
    // 创建Jedis连接对象
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    // 直接调用相关语法即可
    System.out.println(jedis.ping());
    System.out.println(jedis.get("k1"));
    jedis.set("k1", "V1");
    
    // 关闭连接
    jedis.close();
}
3.3 事务
@Test
void redisTest02() {
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    // 获取一个Redis事务对象
    Transaction multi = jedis.multi();
    try {
        // 往事务中插入语句
        multi.set("k2", "v2");
        multi.set("k3", "v3");
        // 执行事务
        multi.exec();
    } catch (Exception e) {
        e.printStackTrace();
        // 回滚事务
        multi.discard();
    }
    jedis.close();
}

通过springboot使用Redis

        导入依赖redis

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

         将resourse下的application.property 改成 application.yml

        配置yml

spring:
  redis:
#    本地端口
    host: 127.0.0.1
#    redis的端口
    port: 6379
#    Redis有16个数据库,可以选择要用哪个
    database: 1

        测试类RedisTemplate对象

@Resource
    private RedisTemplate<String,Object> template;

        尝试拿值 

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.annotation.Resource;

@SpringBootTest
class DemoApplicationTests {

    //redisTemplate是外部依赖导入的,不是在我们本身的代码里,所以
    //idea去我们的代码里找不到,会爆红
    //这里必须指明名字
    @Resource(name = "redisTemplate")
    //这里不能用@Autowired
    private RedisTemplate<String,Object> template;

    @Test
    void contextLoads() {
        ValueOperations<String, Object> valueoption = template.opsForValue();
        valueoption.set("s2","abc");

        System.out.println(valueoption.get("s2"));
    }

}

        这样的话是拿不到正确的值的

        键在存和取的时候会有一些差异,无法正常取到,我们存入的s1起始是在16行的位置

自定义template

        为了保证存储和拿取一致,可以自定义template(这个类对键进行了序列化之类的操作)

@Configuration
public class RedisConfig {
    // 定义了一个RedisTemplate
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // RedisTemplate 为了自己方便一般直接使用<String,Object>
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        // 序列化配置
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 设置可见度
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 启动默认的类型
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        // 序列化类,对象映射设置
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key采用String的序列化
        template.setHashKeySerializer(stringRedisSerializer);
        // value采用jackson的序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value采用jackson的序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
}

        封装工具类

/**
 * spring redis 工具类
 *
 * @author ruoyi
 **/
@SuppressWarnings(value = {"unchecked", "rawtypes"})
@Component
public class RedisUtil {
    @Autowired
    public RedisTemplate redisTemplate;

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值
     */
    public <T> void setCacheObject(final String key, final T value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout) {
        return expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @param unit    时间单位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     * 删除单个对象
     *
     * @param key
     */
    public boolean deleteObject(final String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 删除集合对象
     *
     * @param collection 多个对象
     * @return
     */
    public long deleteObject(final Collection collection) {
        return redisTemplate.delete(collection);
    }

    /**
     * 缓存List数据
     *
     * @param key      缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public <T> long setCacheList(final String key, final List<T> dataList) {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }

    /**
     * 获得缓存的list对象
     *
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public <T> List<T> getCacheList(final String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }

    /**
     * 缓存Set
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
        Iterator<T> it = dataSet.iterator();
        while (it.hasNext()) {
            setOperation.add(it.next());
        }
        return setOperation;
    }

    /**
     * 获得缓存的set
     *
     * @param key
     * @return
     */
    public <T> Set<T> getCacheSet(final String key) {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * 缓存Map
     *
     * @param key
     * @param dataMap
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
        if (dataMap != null) {
            redisTemplate.opsForHash().putAll(key, dataMap);
        }
    }

    /**
     * 获得缓存的Map
     *
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(final String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 往Hash中存入数据
     *
     * @param key   Redis键
     * @param hKey  Hash键
     * @param value 值
     */
    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
        redisTemplate.opsForHash().put(key, hKey, value);
    }

    /**
     * 获取Hash中的数据
     *
     * @param key  Redis键
     * @param hKey Hash键
     * @return Hash中的对象
     */
    public <T> T getCacheMapValue(final String key, final String hKey) {
        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
        return opsForHash.get(key, hKey);
    }

    /**
     * 删除Hash中的数据
     *
     * @param key
     * @param hKey
     */
    public void delCacheMapValue(final String key, final String hKey) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.delete(key, hKey);
    }

    /**
     * 获取多个Hash中的数据
     *
     * @param key   Redis键
     * @param hKeys Hash键集合
     * @return Hash对象集合
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
        return redisTemplate.opsForHash().multiGet(key, hKeys);
    }

    /**
     * 获得缓存的基本对象列表
     *
     * @param pattern 字符串前缀
     * @return 对象列表
     */
    public Collection<String> keys(final String pattern) {
        return redisTemplate.keys(pattern);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1323938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多表插入操作——后端

场景&#xff1a;当添加一个菜品时&#xff0c;还需要记录菜品的口味信息&#xff0c;因此需要对菜品表&#xff08;dish&#xff09;和口味表&#xff08;dish_flavor&#xff09;同时进行插入操作。 两个表的字段&#xff1a; 代码思路&#xff1a;由DishController将前端的…

数字转换:探析数据可视化的激增原因

现在&#xff0c;数据可视化作为一种强大的工具逐渐走进人们的视野&#xff0c;其爆发式发展背后涌现了多种原因值得探讨&#xff0c;今天我就以可视化从业者的视角来简单谈谈数据可视化爆发式发展背后的原因。 首先是互联网和传感技术的普及&#xff0c;令大量数据源不断涌现…

Redis是单线程还是多线程,为什么快?

1.Redis是单线程模型还是多线程模型&#xff1f; 在redis6.X版本之前&#xff0c;属于彻彻底底的单线程模型&#xff0c;redis在解析客户端命令和读写数据的操作都是由一个单线程来解决的。 而redis6.X版本后&#xff0c;引入了多线程&#xff0c;但是只作用于解析客户端的命令…

MapReduce综合应用案例 — 电信数据清洗

文章目录 第1关&#xff1a;数据清洗 第1关&#xff1a;数据清洗 测试说明 平台会对你编写的代码进行测试&#xff1a; 评测之前先在命令行启动hadoop&#xff1a;start-all.sh&#xff1b; 点击测评后MySQL所需的数据库和表会自动创建好。 PhoneLog&#xff1a;封装对象 L…

【MYSQL】-库的操作

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

[Linux] LVS+Keepalived高可用集群部署

一、Keepalived实现原理 1.1 高可用方案 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案&#xff0c;可以解决静态路由出现的单点故障问题。 在一个LVS服务集群中通常有主服务器&#xff08;MASTER&#xff09;和备份服务器&#xff08;BACKUP&#xff09;两种角色…

SQL Server 安装教程

安装数据库 1、启动SQL Server2014安装程序&#xff0c;运行setup.exe文件&#xff0c;打开”SQL Server安装中心“对话框&#xff0c;单击左侧 的导航区域中的”安装“选项卡。 2、选择”全新SQL Server独立安装或向现有安装添加功能“&#xff0c;启动SQL Server2014安装向导…

软件测试实现Finddler的手机抓包过程

Fiddler的手机抓包过程 1、启动Fiddler 打开菜单栏中的 Tools > Fiddler Options&#xff0c;打开“Fiddler Options”对话框&#xff1a; 2、在Fiddler Options”对话框 切换到“Connections”选项卡&#xff0c;然后勾选“Allow romote computers to connect”后面的复选…

create-react-app 打包去掉 map文件

前言&#xff1a; 在使用 create-react-app 创建的React应用中&#xff0c;默认情况下会生成带有.map文件的打包文件&#xff0c;这些.map文件包含了源代码和调试信息&#xff0c;用于开发和调试过程中进行错误跟踪。然而&#xff0c;在生产环境中&#xff0c;这些.map文件通常…

项目管理:分工不明确时,团队成员互相甩锅,应该怎么解决?

在工作中&#xff0c;你是否遇到过这样的情况&#xff1a; 领导分配任务给下属&#xff0c;由于职责边界模糊&#xff0c;平级或者跨部门时互相推诿&#xff1b; 前几天项目经理分配给我一个任务&#xff0c;让我负责项目的一个阶段&#xff0c;这个阶段需要跟平级同事沟通外…

Python基础05-函数

零、文章目录 Python基础05-函数 1、函数的作用及其使用步骤 &#xff08;1&#xff09;函数的作用 在Python实际开发中&#xff0c;我们使用函数的目的只有一个“让我们的代码可以被重复使用” 函数的作用有两个&#xff1a; ① 代码重用&#xff08;代码重复使用&#xf…

【为数据之道学习笔记】5-7五类数据主题联接的应用场景

在数字化转型的背景下&#xff0c;华为的数据消费已经不再局限于传统的报表分析&#xff0c;还要支持用户的自助分析、实时分析&#xff0c;通过数据的关联&#xff0c;支持业务的关联影响分析以及对目标对象做特征识别&#xff0c;进行特定业务范围圈定、差异化管理与决策等。…

(保姆级教程)一篇文章,搞定所有Linux命令,以及tar解压缩命令,wget、rpm等下载安装命令,Linux的目录结构,以及用户和用户组

文章目录 Linux命令1. Linux目录结构2. 基本命令&#xff08;了解&#xff09;3. 目录&#xff08;文件夹&#xff09;命令列出目录切换目录创建目录删除目录复制目录移动和重命名目录 4. 文件命令创建文件编辑文件编辑文件时的其他操作 查看文件移动/重命名文件复制文件删除文…

hive 用户自定义函数udf,udaf,udtf

udf&#xff1a;一对一的关系 udtf&#xff1a;一对多的关系 udaf&#xff1a;多对一的关系 使用Java实现步骤 自定义编写UDF函数注意&#xff1a; 1.需要继承org.apache.hadoop.hive.ql.exec.UDF 2.需要实现evaluete函数 编写UDTF函数注意&#xff1a; 1.需要继承org.apache…

word 文档表格使用问题记录

word 文档表格使用问题记录 表格断页表格属性设置段落属性设置 表格断页 有时在Wps Word表格增加内容时&#xff0c;如超过表格时&#xff0c;自动跳到下一页&#xff0c;导致上一页空白&#xff0c;出现不连续的现象 表格属性设置 选中表格进行属性设置 段落属性设置

hive企业级调优策略之分组聚合优化

测试用表准备 hive企业级调优策略测试数据 (阿里网盘下载链接)&#xff1a;https://www.alipan.com/s/xsqK6971Mrs 订单表(2000w条数据) 表结构 建表语句 drop table if exists order_detail; create table order_detail(id string comment 订单id,user_id …

电脑自动录屏软件怎么录制视频

电脑自动录屏软件是一种非常实用的工具&#xff0c;可以帮助我们轻松地录制屏幕上的视频内容&#xff0c;它会自动录制和停止&#xff0c;不需要人在电脑前一直盯着。那么&#xff0c;大家可能会有一个疑问&#xff0c;如何使用这样的软件进行视频录制呢&#xff1f; 首先&…

java中基本类型之间的转换

基本类型容量 java中的 8 种基本数据类型&#xff0c;以及它们的占内存的容量大小和表示的范围 byte&#xff1a;字节型&#xff0c;占内存容量为 1 个字节&#xff08;8 位&#xff09;&#xff0c;表示范围为 -128&#xff08;-2^7&#xff09;到 127&#xff08;2^7-1&…

带大家做一个,易上手的家常芹菜炒土豆

家里有芹菜土豆需要处理的看过来了呀 先土豆去皮 芹菜如果上面叶子发黑了 就切掉然后清洗干净 将芹菜切成条 土豆也切条 最好大小按芹菜的来 准备两瓣蒜 切小块 起锅烧油 倒入土豆翻炒一小会儿 倒水煮一会儿 土豆真的不太好熟 可以多放一点点水 但也别过了 等水少了一…