6000+字讲透ElasticSearch 索引设计

news2024/7/6 17:38:11

ElasticSearch 索引设计

img

在MySQL中数据库设计非常重要,同样在ES中数据库设计也是非常重要的

概述

我们创建索引就像创建表结构一样,必须非常慎重的,索引如果创建不好后面会出现各种各样的问题

索引设计的重要性

索引创建后,索引的分片只能通过_split_shrink接口对其进行成倍的增加和缩减

主要是因为es的数据是通过_routing分配到各个分片上面的,所以本质上是不推荐去改变索引的分片数量的,因为这样都会对数据进行重新的移动。

还有就是索引只能新增字段,不能对字段进行修改和删除,缺乏灵活性,所以每次都只能通过_reindex重建索引了,还有就是一个分片的大小以及所以分片数量的多少严重影响到了索引的查询和写入性能,所以可想而知,设计一个好的索引能够减少后期的运维管理和提高不少性能,所以前期对索引的设计是相当的重要的。

基于时间的Index设计

Index设计时要考虑的第一件事,就是基于时间对Index进行分割,即每隔一段时间产生一个新的Index

这样设计的目的

因为现实世界的数据是随着时间的变化而不断产生的,切分管理可以获得足够的灵活性和更好的性能

img

如果数据都存储在一个Index中,很难进行扩展和调整,因为Elasticsearch中Index的某些设置在创建时就设定好了,是不能更改的,比如Primary Shard的个数。

而根据时间来切分Index,则可以实现一定的灵活性,既可以在数据量过大时及时调整Shard个数,也可以及时响应新的业务需求。

大多数业务场景下,客户对数据的请求都会命中在最近一段时间上,通过切分Index,可以尽可能的避免扫描不必要的数据,提高性能。

时间间隔

根据上面的分析,自然是时间越短越能保持灵活性,但是这样做就会导致产生大量的Index,而每个Index都会消耗资源来维护其元信息的,因此需要在灵活性、资源和性能上做权衡

  • 常见的间隔有小时、天、周和月:先考虑总共要存储多久的数据,然后选一个既不会产生大量Index又能够满足一定灵活性的间隔,比如你需要存储6个月的数据,那么一开始选择“周”这个间隔就会比较合适。
  • 考虑业务增长速度:假如业务增长的特别快,比如上周产生了1亿数据,这周就增长到了10亿,那么就需要调低这个间隔来保证有足够的弹性能应对变化。
如何实现分割

切分行为是由客户端(数据的写入端)发起的,根据时间间隔与数据产生时间将数据写入不同的Index中,为了易于区分,会在Index的名字中加上对应的时间标识

创建新Index这件事,可以是客户端主动发起一个创建的请求,带上具体的Settings、Mappings等信息,但是可能会有一个时间错位,即有新数据写入时新的Index还没有建好,Elasticsearch提供了更优雅的方式来实现这个动作,即Index Template

分片设计

所谓分片设计,就是如何设定主分片的个数

看上去只是一个数字而已,也许在很多场景下,即使不设定也不会有问题(ES7默认是1个主分片一个副本分片),但是如果不提前考虑,一旦出问题就可能导致系统性能下降、不可访问、甚至无法恢复,换句话说,即使使用默认值,也应该是通过足够的评估后作出的决定,而非拍脑袋定的。

限制分片大小

单个Shard的存储大小不超过30GB

Elastic专家根据经验总结出来大家普遍认为30GB是个合适的上限值,实践中发现单个Shard过大(超过30GB)会导致系统不稳定。

其次,为什么不能超过30GB?主要是考虑Shard Relocate过程的负载,我们知道,如果Shard不均衡或者部分节点故障,Elasticsearch会做Shard Relocate,在这个过程中会搬移Shard,如果单个Shard过大,会导致CPU、IO负载过高进而影响系统性能与稳定性。

评估分片数量

单个Index的Primary Shard个数 = k * 数据节点个数

在保证第一点的前提下,单个Index的Primary Shard个数不宜过多,否则相关的元信息与缓存会消耗过多的系统资源,这里的k,为一个较小的整数值,建议取值为1,2等,整数倍的关系可以让Shard更好地均匀分布,可以充分的将请求分散到不同节点上。

小索引设计

对于很小的Index,可以只分配1~2个Primary Shard的

有些情况下,Index很小,也许只有几十、几百MB左右,那么就不用按照第二点来分配了,只分配1~2个Primary Shard是可以,不用纠结。

使用索引模板

就是把已经创建好的某个索引的参数设置(settings)和索引映射(mapping)保存下来作为模板,在创建新索引时,指定要使用的模板名,就可以直接重用已经定义好的模板中的设置和映射

Elasticsearch基于与索引名称匹配的通配符模式将模板应用于新索引,也就是说通过索引进行匹配,看看新建的索引是否符合索引模板,如果符合,就将索引模板的相关设置应用到新的索引,如果同时符合多个索引模板呢,这里需要对参数priority进行比较,这样会选择priority大的那个模板进行创建索引。

在创建索引模板时,如果匹配有包含的关系,或者相同,则必须设置priority为不同的值,否则会报错,索引模板也是只有在新创建的时候起到作用,修改索引模板对现有的索引没有影响,同样如果在索引中设置了一些设置或者mapping都会覆盖索引模板中相同的设置或者mapping

索引模板的用途

索引模板一般用在时间序列相关的索引中。

也就是说, 如果你需要每间隔一定的时间就建立一次索引,你只需要配置好索引模板,以后就可以直接使用这个模板中的设置,不用每次都设置settings和mappings.

创建索引模板
COPYPUT _index_template/logstash-village
{
  "index_patterns": [
    "logstash-village-*"  // 可以通过"logstash-village-*"来适配创建的索引
  ],
  "template": {
    "settings": {
      "number_of_shards": "3", //指定模板分片数量
      "number_of_replicas": "2"  //指定模板副本数量
    },
    "aliases": {
      "logstash-village": {}  //指定模板索引别名
    },
    "mappings": {   //设置映射
      "dynamic": "strict", //禁用动态映射
      "properties": {
        "@timestamp": {
          "type": "date",
           "format": "strict_date_optional_time||epoch_millis||yyyy-MM-dd HH:mm:ss"
        },
        "@version": {
          "doc_values": false,
          "index": "false",
          "type": "integer"
        },
        "name": {
          "type": "keyword"
        },
        "province": {
          "type": "keyword"
        },
        "city": {
          "type": "keyword"
        },
        "area": {
          "type": "keyword"
        },
        "addr": {
          "type": "text",
          "analyzer": "ik_smart"
        },
        "location": {
          "type": "geo_point"
        },
        "property_type": {
          "type": "keyword"
        },
        "property_company": {
          "type": "text",
          "analyzer": "ik_smart"
        },
        "property_cost": {
          "type": "float"
        },
        "floorage": {
          "type": "float"
        },
        "houses": {
          "type": "integer"
        },
        "built_year": {
          "type": "integer"
        },
        "parkings": {
          "type": "integer"
        },
        "volume": {
          "type": "float"
        },
        "greening": {
          "type": "float"
        },
        "producer": {
          "type": "keyword"
        },
        "school": {
          "type": "keyword"
        },
        "info": {
          "type": "text",
          "analyzer": "ik_smart"
        }
      }
    }
  }
}
模板参数

下面是创建索引模板的一些参数

参数名称参数介绍
index_patterns必须配置,用于在创建期间匹配索引名称的通配符(*)表达式数组
template可选配置,可以选择包括别名、映射或设置配置
composed_of可选配置,组件模板名称的有序列表。组件模板按指定的顺序合并,这意味着最后指定的组件模板具有最高的优先级
priority可选配置,创建新索引时确定索引模板优先级的优先级。选择具有最高优先级的索引模板。如果未指定优先级,则将模板视为优先级为0(最低优先级)
version可选配置,用于外部管理索引模板的版本号
_meta可选配置,关于索引模板的可选用户元数据,可能有任何内容

映射配置

上面我们配置了映射模板,但是我们用到了映射,下面我们说下映射

什么是映射

在创建索引时,可以预先定义字段的类型(映射类型)及相关属性

数据库建表的时候,我们DDL依据一般都会指定每个字段的存储类型,例如:varchar、int、datetime等,目的很明确,就是更精确的存储数据,防止数据类型格式混乱,在Elasticsearch中也是这样,创建索引的时候一般也需要指定索引的字段类型,这种方式称为映射(Mapping)

被动创建(动态映射)

此时字段和映射类型不需要事先定义,只需要存在文档的索引,当向此索引添加数据的时候当遇到不存在的映射字段,ES会根据数据内容自动添加映射字段定义。

动态映射规则

使用动态映射的时候,根据传递请求数据的不同会创建对应的数据类型

数据类型Elasticsearch 数据类型
null不添加任何字段
true或者falseboolean类型
浮点数据float类型
integer数据long类型
objectobject类型
array取决于数组中的第一个非空值的类型。
string如果此内容通过了日期格式检测,则会被认为是date数据类型 如果此值通过了数值类型检测则被认为是double或者long数据类型 带有关键字子字段会被认为一个text字段
禁止动态映射

一般生产环境下需要禁用动态映射,使用动态映射可能出现以下问题

  1. 造成集群元数据一直变更,导致不稳定;
  2. 可能造成数据类型与实际类型不一致;

如何禁用动态映射,动态mappingdynamic字段进行配置,可选值及含义如下

  • true:支持动态扩展,新增数据有新的字段属性时,自动添加对于的mapping,数据写入成功
  • false:不支持动态扩展,新增数据有新的字段属性时,直接忽略,数据写入成功
  • strict:不支持动态扩展,新增数据有新的字段时,报错,数据写入失败

主动创建(显示映射)

动态映射只能保证最基础的数据结构的映射

所以很多时候我们需要对字段除了数据结构定义更多的限制的时候,动态映射创建的内容很可能不符合我们的需求,所以可以使用PUT {index}/mapping来更新指定索引的映射内容。

映射类型

我们要创建映射必须还要知道映射类型,否则就会走默认的映射类型,下面我们看看常用的映射类型

准备工作

我们先创建一个用于测试映射类型的索引

COPYPUT mapping_demo

字符串类型

字符串类型是我们最常用的类型之一,我们操作的时候字符串类型可以被设置为以下几种类型

text

当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型,text类型会被分词

设置text类型以后,字段内容会被分词,在生成倒排索引以前,字符串会被分析器分成一个一个词项,text类型的字段不用于排序,很少用于聚合

keyword

keyword类型不会被分词,常用于关键字搜索,比如姓名、email地址、主机名、状态码和标签等

如果字段需要进行过滤(比如查姓名是张三发布的博客)、排序、聚合,keyword类型的字段只能通过精确值搜索到,常常被用来过滤、排序和聚合

两者区别

它们的区别在于text会对字段进行分词处理而keyword则不会进行分词

也就是说如果字段是text类型,存入的数据会先进行分词,然后将分完词的词组存入索引,而keyword则不会进行分词,直接存储,这样划分数据更加节省内存。

使用案例

我们先创建一个映射,name是keyword类型,描述是text类型的

COPYPUT mapping_demo/_mapping
{
  "properties": {
    "name": {
        "type": "keyword"
     },
      "city": {
        "type": "text",
        "analyzer": "ik_smart"
     }
  }
}

插入数据

COPYPUT mapping_demo/_doc/1
{
  "name":"北京小区",
  "city":"北京市昌平区回龙观街道"
}

对于keyword的name字段进行精确查询

COPYGET mapping_demo/_search
{
  "query": {
    "term": {
      "name": "北京小区"
    }
  }
}

对于text的city进行模糊查询

COPYGET mapping_demo/_search
{
  "query": {
    "term": {
      "city": "北京市"
    }
  }
}

数字类型

数字类型也是我们最常用的类型之一,下面我们看下数字类型的使用

类型取值范围
long-263 ~ 263
integer-231 ~ 231
short-215 ~ 215
byte-27 ~ 27
double64位的双精度 IEEE754 浮点类型
float32位的双精度 IEEE754 浮点类型
half_float16位的双精度 IEEE754 浮点类型
scaled_float缩放类型的浮点类型
注意事项
  • 在满足需求的情况下,优先使用范围小的字段,字段长度越小,索引和搜索的效率越高。

日期类型

JSON表示日期

JSON没有表达日期的数据类型,所以在ES里面日期只能是下面其中之一

  • 格式化的日期字符串,比如:"2015-01-01" or "2015/01/01 12:10:30"
  • 用数字表示的从新纪元开始的毫秒数
  • 用数字表示的从新纪元开始的秒数(epoch_second)

注意点:毫秒数的值是不能为负数的,如果时间在1970年以前,需要使用格式化的日期表达

ES如何处理日期

在ES的内部,时间会被转换为UTC时间(如果声明了时区)并使用从新纪元开始的毫秒数的长整形数字类型的进行存储,在日期字段上的查询,内部将会转换为使用长整形的毫秒进行范围查询,根据与字段关联的日期格式,聚合和存储字段的结果将转换回字符串

注意点:日期最终都会作为字符串呈现,即使最开始初始化的时候是利用JSON文档的long声明的

默认日期格式

日期的格式可以被定制化的,如果没有声明日期的格式,它将会使用默认的格式:

COPY"strict_date_optional_time||epoch_millis"

这意味着它将会接收带时间戳的日期,它将遵守strict_date_optional_time限定的格式(yyyy-MM-dd'T'HH:mm:ss.SSSZ 或者 yyyy-MM-dd)或者毫秒数

日期格式示例
COPYPUT mapping_demo/_mapping
{
  "properties": {
    "datetime": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
     }
  }
}
# 添加数据
PUT mapping_demo/_doc/2
{
  "name":"河北区",
  "city":"河北省小区",
  "datetime":"2022-02-21 11:35:42"
}
日期类型参数

下面表格里的参数可以用在date字段上面

参数说明
doc_values该字段是否按照列式存储在磁盘上以便于后续进行排序、聚合和脚本操作,可配置 true(默认)或 false
format日期的格式
locale解析日期中时使用了本地语言表示月份时的名称和/或缩写,默认是 ROOT locale
ignore_malformed如果设置为true,则奇怪的数字就会被忽略,如果是false(默认)奇怪的数字就会导致异常并且该文档将会被拒绝写入。需要注意的是,如果在脚本参数中使用则该属性不能被设置
index该字段是否能快速的被查询,默认是true。date类型的字段只有在doc_values设置为true时才能被查询,尽管很慢。
null_value替代null的值,默认是null
on_script_error定义在脚本中如何处理抛出的异常,fail(默认)则整个文档会被拒绝索引,continue:继续索引
script如果该字段被设置,则字段的值将会使用该脚本产生,而不是直接从source里面读取。
storetrue or false(默认)是否在 _source 之外在独立存储一份

布尔类型

boolean类型用于存储文档中的true/false

范围类型

顾名思义,范围类型字段中存储的内容就是一段范围,例如年龄30-55岁,日期在2020-12-28到2021-01-01之间等

类型范围

es中有六种范围类型:

  • integer_range
  • float_range
  • long_range
  • double_range
  • date_range
  • ip_range
使用实例
COPYPUT mapping_demo/_mapping
{
  "properties": {
    "age_range": {
        "type": "integer_range"
     }
  }
}

# 指定年龄范围,可以使用 gt、gte、lt、lte。
PUT mapping_demo/_doc/3
{
  "name":"张三",
  "age_range":{
    "gt":20,
    "lt":30
  }
}

分词器

什么是分词器

分词器的主要作用将用户输入的一段文本,按照一定逻辑,分析成多个词语的一种工具

顾名思义,文本分析就是把全文本转换成一系列单词(term/token)的过程,也叫分词,在 ES 中,Analysis 是通过分词器(Analyzer) 来实现的,可使用 ES 内置的分析器或者按需定制化分析器。

举一个分词简单的例子:比如你输入 Mastering Elasticsearch,会自动帮你分成两个单词,一个是 mastering,另一个是 elasticsearch,可以看出单词也被转化成了小写的。

图片

分词器构成

分词器是专门处理分词的组件,分词器由以下三部分组成:

character filter

接收原字符流,通过添加、删除或者替换操作改变原字符流

例如:去除文本中的html标签,或者将罗马数字转换成阿拉伯数字等,一个字符过滤器可以有零个或者多个

tokenizer

简单的说就是将一整段文本拆分成一个个的词

例如拆分英文,通过空格能将句子拆分成一个个的词,但是对于中文来说,无法使用这种方式来实现,在一个分词器中,有且只有一个tokenizeer

token filters

将切分的单词添加、删除或者改变

例如将所有英文单词小写,或者将英文中的停词a删除等,在token filters中,不允许将token(分出的词)position或者offset改变,同时,在一个分词器中,可以有零个或者多个token filters

分词顺序

图片

同时 Analyzer 三个部分也是有顺序的,从图中可以看出,从上到下依次经过 Character FiltersTokenizer 以及 Token Filters,这个顺序比较好理解,一个文本进来肯定要先对文本数据进行处理,再去分词,最后对分词的结果进行过滤。

测试分词

可以通过_analyzerAPI来测试分词的效果,我们使用下面的html过滤分词

COPYPOST _analyze
{
    "text":"<b>hello world<b>"  # 输入的文本
    "char_filter":["html_strip"], # 过滤html标签
    "tokenizer":"keyword", #原样输出
}

image-20220808135231869

什么时候分词

文本分词会发生在两个地方:

  • 创建索引:当索引文档字符类型为text时,在建立索引时将会对该字段进行分词。
  • 搜索:当对一个text类型的字段进行全文检索时,会对用户输入的文本进行分词。

创建索引时指定分词器

如果设置手动设置了分词器,ES将按照下面顺序来确定使用哪个分词器

  • 先判断字段是否有设置分词器,如果有,则使用字段属性上的分词器设置
  • 如果设置了analysis.analyzer.default,则使用该设置的分词器
  • 如果上面两个都未设置,则使用默认的standard分词器
字段指定分词器

为addr属性指定分词器,这里我们使用的是中文分词器

COPYPUT my_index
{
  "mappings": {
    "properties": {
     "info": {
        "type": "text",
        "analyzer": "ik_smart"
       }
    }
  }
}
设置默认分词器
COPYPUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default":{
          "type":"simple"
        }
      }
    }
  }
}

搜索时指定分词器

在搜索时,通过下面参数依次检查搜索时使用的分词器,这样我们的搜索语句就会先分词,然后再来进行搜索

  • 搜索时指定analyzer参数
  • 创建mapping时指定字段的search_analyzer属性
  • 创建索引时指定settinganalysis.analyzer.default_search
  • 查看创建索引时字段指定的analyzer属性
  • 如果上面几种都未设置,则使用默认的standard分词器。
指定analyzer

搜索时指定analyzer查询参数

COPYGET my_index/_search
{
  "query": {
    "match": {
      "message": {
        "query": "Quick foxes",
        "analyzer": "stop"
      }
    }
  }
}
指定字段analyzer
COPYPUT my_index
{
  "mappings": {
    "properties": {
      "title":{
        "type":"text",
        "analyzer": "whitespace",
        "search_analyzer": "simple"
      }
    }
  }
}
指定默认default_seach
COPYPUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default":{
          "type":"simple"
        },
        "default_seach":{
          "type":"whitespace"
        }
      }
    }
  }
}

内置分词器

es在索引文档时,会通过各种类型 Analyzer 对text类型字段做分析

不同的 Analyzer 会有不同的分词结果,内置的分词器有以下几种,基本上内置的 Analyzer 包括 Language Analyzers 在内,对中文的分词都不够友好,中文分词需要安装其它 Analyzer

分析器描述分词对象结果
standard标准分析器是默认的分析器,如果没有指定,则使用该分析器。它提供了基于文法的标记化(基于 Unicode 文本分割算法,如 Unicode 标准附件 # 29所规定) ,并且对大多数语言都有效。The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog’s, bone ]
simple简单分析器将文本分解为任何非字母字符的标记,如数字、空格、连字符和撇号、放弃非字母字符,并将大写字母更改为小写字母。The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.[ the, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]
whitespace空格分析器在遇到空白字符时将文本分解为术语The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.[ The, 2, QUICK, Brown-Foxes, jumped, over, the, lazy, dog’s, bone. ]
stop停止分析器与简单分析器相同,但增加了删除停止字的支持。默认使用的是 _english_ 停止词。The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.[ quick, brown, foxes, jumped, over, lazy, dog, s, bone ]
keyword不分词,把整个字段当做一个整体返回The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.[The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.]
pattern模式分析器使用正则表达式将文本拆分为术语。正则表达式应该匹配令牌分隔符,而不是令牌本身。正则表达式默认为 w+ (或所有非单词字符)。The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]
多种西语系 arabic, armenian, basque, bengali, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english等等一组旨在分析特定语言文本的分析程序。

IK中文分词器

IKAnalyzer

IKAnalyzer是一个开源的,基于java的语言开发的轻量级的中文分词工具包

从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本,在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化

中文分词器算法

中文分词器最简单的是ik分词器,还有jieba分词,哈工大分词器等

分词器描述分词对象结果
ik_smartik分词器中的简单分词器,支持自定义字典,远程字典学如逆水行舟,不进则退[学如逆水行舟,不进则退]
ik_max_wordik_分词器的全量分词器,支持自定义字典,远程字典学如逆水行舟,不进则退[学如逆水行舟,学如逆水,逆水行舟,逆水,行舟,不进则退,不进,则,退]

ik_smart

原始内容
COPY传智教育的教学质量是杠杠的
测试分词
COPYGET _analyze
{
  "analyzer": "ik_smart",
  "text": "传智教育的教学质量是杠杠的"
}

image-20220808115450647

ik_max_word

原始内容
COPY传智教育的教学质量是杠杠的
测试分词
COPYGET _analyze
{
  "analyzer": "ik_max_word",
  "text": "传智教育的教学质量是杠杠的"
}

image-20220808115513668

本文由传智教育博学谷狂野架构师教研团队发布。

如果本文对您有帮助,欢迎关注点赞;如果您有任何建议也可留言评论私信,您的支持是我坚持创作的动力。

转载请注明出处!

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

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

相关文章

Mac使用svn全教程(安装+命令操作项目)

Mac使用svn&#xff0c;包括安装以及命令检出项目提交项目&#xff0c;下面直接进入正题&#xff1a; 1.安装svn 首先Mac需要安装brew #安装brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"图1: 图2: 图3: 如…

java数组排序,升序和降序

文章目录 前言基本数据类型排序升序降序排列 基本数据类型包装类升序降序 对象排序升序降序 前言 对于数组的排序一直很疑惑&#xff0c;尤其是如何对数组进行降序排列&#xff0c;例如要对int[]类型的数组降序排列&#xff0c;这里来进行说明 基本数据类型排序 升序 int[]…

缓存失效的三大祸害:穿透、击穿、雪崩及应对策略详解

1、概述 缓存穿透、缓存击穿和缓存雪崩都是常见的缓存问题&#xff0c;下面分别介绍它们的定义和解决方法&#xff1a; 1&#xff09;缓存穿透 缓存穿透指的是恶意用户或攻击者通过请求不存在于缓存和后端存储中的数据来使得所有请求都落到后端存储上&#xff0c;导致系统瘫痪…

【数据库复习】第五章 数据库编程1

存储过程和触发器 PL/SQL &#xff1a; SQL的扩展 增加了过程化语句功能 基本结构是块 块之间可以互相嵌套 每个块完成一个逻辑操作 1.定义部分 DECLARE ------变量、常量、游标、异常等 定义的变量、常量等只能在该基本块中使用 当基本块执行结束时&#…

OpenCL编程指南-3.1OpenCL平台与设备

OpenCL平台 在2.1中讨论过&#xff0c;OpenCL应用的第一步是查询OpenCL平台集合&#xff0c;选择其中一个或多个平台在应用中使用。与平台关联有一个简档 (profile)&#xff0c;描述所支持的特定OpenCL版本的功能。简档可以是完全简档&#xff0c;涵盖定义为核心规范的所有功能…

超好用!免费使用的Sketch在线版真香!

在设计领域中&#xff0c;Sketch是一款非常受欢迎的矢量绘图设计软件&#xff0c;但它只支持Mac系统&#xff0c;这对于Windows用户来说是一个很大的限制。虽然有人称之为Sketch在线版&#xff0c;但实际上并不存在这样的工具。不过&#xff0c;现在有一款全新的在线协同设计工…

SpringBoot整合Mybaties增删改查

文章目录 1、填写pom.xml2、填写application.properties3、User实体4、Springboot主类5、UserMapper6、UserServise层7、UserServiseImpl8、Controller类测试 使用 Java 开发或者学习过程中&#xff0c;最避免不了的是连接和操作数据库&#xff0c;此次&#xff0c;学习如何在S…

Java之单例模式

目录 一.上节内容 1.什么是线程安全 2.线程不安全的原因 3.JMM(Java内存模型) 4.synchronized锁 5.锁对象 6.volatile关键字 7.wait()和notify() 8.Java中线程安全的类 二.单例模式 1.什么是单例 2.怎么设计一个单例 1.口头约定 2.使用编程语言的特性 三.饿汉模式…

文心一言没有体验上,看看讯飞星火认知大模型

目录 前言 正文 1.简单对话环节 1.1什么是讯飞星火认知大模型 1.2你都可以干一些什么 1.3你的训练数据库还在持续更新么 1.4今天是哪一天 1.5宇宙中有哪些目前认为可能存在生命的星球 2.辅助学习对话 2.1我想完成一篇关于CT检测技术的论文综述&#xff0c;你有什么好的…

Elasticsearch - 聚合获取原始数据并分页排序模糊查询

文章目录 概述第一步 &#xff1a; 聚合获取原始数据并分页知识点&#xff1a;bucket_sort实现分页知识点&#xff1a;获取 total -----> cardinality 去重 小结第二步 分页并支持模糊查询方式一 query 方式方式二&#xff1a; 脚本cardinality 的 script 概述 ES版本&…

4.100ASK_V853-PRO开发板支持4寸MIPI屏

0.前言 ​ 由于之前我们已经适配过RGB屏&#xff0c;如果我们去适配了4寸MIPI屏&#xff0c;那么RGB屏就不能使用了。对于4寸屏购买链接为&#xff1a; 百问网4寸MIPI屏 LCD_调试指南:https://tina.100ask.net/SdkModule/Linux_LCD_DevelopmentGuide-01/ Display_开发指南:h…

pmp学习对职场的影响有多大?

不知不觉&#xff0c;2021的进度条已经走过了一半。行业政策的变化&#xff0c;岗位的能力对比&#xff0c;都让职场竞争变得更加激烈&#xff0c;成为一名优秀且具有竞争力的项目经理好像变得越来越难了。 为什么这样说呢&#xff1f;因为各行各业在对PM要求各项专业技能的同…

ChatGPT人工智能聊天机器人的优势与应用

当今社会&#xff0c;聊天机器人(Chatbot)已经成为一种新的交互方式。而ChatGPT则是一种基于深度学习技术的聊天机器人&#xff0c;它可以模拟人类对话的过程&#xff0c;可以为人们提供快速、便捷的解决方案。以下是ChatGPT的简介和优势&#xff1a; 基本信息&#xff1a;Chat…

将区块链技术融入电梯管理系统

电梯管理系统 电梯是人们日常生活和工作中必不可少的交通工具&#xff0c;为了保障电梯的安全性和运营效率&#xff0c;需要实时监测电梯状态及事件/故障。这里可以查考网络上提供的方案&#xff0c;在电梯内部安装了各种各样的传感器&#xff0c;通过网关将收集到的数据上传到…

小红书保姆级投放指南 | 助力引爆618

5月到来&#xff0c;618营销正式进入放量冲刺期&#xff0c;作为年中重量级营销节点&#xff0c;各大品牌角逐激烈。 本期千瓜推出618投放指南&#xff0c;助力品牌在冲刺期抢占用户心智、抓住高转化周期流量&#xff0c;打赢这场无硝烟之战。整体节奏把控四个阶段循序渐进 品牌…

Acrel-2000系列监控系统在亚运手球比赛馆建设10kV供配电工程中的应用

安科瑞 耿敏花 摘要:智能化配电监控系统是数字化和信息化时代应运而生的产物&#xff0c;已经被广泛应用于电网用户侧楼宇、体育场馆、科研设施、机场、交通、医院、电力和石化行业等诸多领域的高/低压变配电系统中。安科瑞自研的Acrel-2000系列监控系统可监控高压开关柜、低压…

第八章 SSM整合

1.整合关键点 Spring&#xff1a;负责对象的创建、维护、管理及对象依赖资源的注入 SpringMVC&#xff1a;负责请求的处理相当于(Servlet) MyBatis&#xff1a;负责与数据库进行交互 2.整合步骤 2.1.在pom.xml文件中导入依赖 mybatis、spring-webmvc、mybatis-spring、bonecp数…

GIF动态图录制工具

大家好&#xff0c;我是小寻&#xff0c;欢迎关注公众号:工具优选&#xff0c;免费领取优质项目源码和常用工具&#xff0c;还可以加入我的交流群! 一、工具介绍 Screen to Gif中文版是一款方便可靠的gif动画录制软件&#xff0c;可以用来快速录制屏幕上的指定区域&#xff…

二十年前的老游戏,为何再次让无数程序员痴迷不已?

SpaceTraders是个古老的策略类游戏&#xff0c;运行在古老的Palm OS和Windows Mobile PDA上。 游戏开始时&#xff0c;玩家将获得一艘飞船&#xff0c;然后驾驶它在各个星球之间穿梭&#xff0c;挖掘星球矿产&#xff0c;低买高卖赚取利润&#xff0c;赚了钱可以升级飞船&#…

麻了,一个操作把MySQL主从复制整崩了

最近公司某项目上反馈mysql主从复制失败&#xff0c;被运维部门记了一次大过&#xff0c;影响到了项目的验收推进&#xff0c;那么究竟是什么原因导致的呢&#xff1f;而主从复制的原理又是什么呢&#xff1f;本文就对排查分析的过程做一个记录。 主从复制原理 我们先来简单了…