php使用ElasticSearch
ElasticSearch简介
Elasticsearch 是一个分布式的、开源的搜索分析引擎,支持各种数据类型,包括文本、数字、地理、结构化、非结构化。
Lucene与ElasticSearch
Apache Lucene是一款高性能的、可扩展的信息检索(IR)工具库,是由Java语言开发的成熟、自由开源的搜索类库,基于Apache协议授权。Lucene只是一个软件类库,如果要发挥Lucene的功能,还需要开发一个调用Lucene类库的应用程序。
ElasticSearch在底层利用Lucene完成其索引功能,因此其许多基本概念源于Lucene。ElasticSearch封装了许多lucene底层功能,提供了分布式的服务、简单易用的restful API接口和许多语言的客户端。
倒排索引
Lucene中对文档检索基于倒排索引实现,并将它发挥到了极致。
倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。
例如:
id | 句子 |
---|---|
1 | I like apples |
2 | I dislike apples |
3 | I dislike apples too |
如果要用单词作为索引,而句子的位置作为被索引的元素,那么索引就发生了倒置:
id | 单词索引 |
---|---|
I | {1,2,3} |
like | {1} |
apples | {1,2,3} |
dislike | {2,3} |
too | {3} |
如果要检索I dislike apples这句话,那么就可以这么计算 : {1,2,3} ^ {2,3} ^ {1,2,3} (^是交集)
核心概念
-
索引(Index)
ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。
-
类型(Type)
类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。
-
文档(Document)
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。
-
映射(Mapping)
ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。
-
**节点(Node) **
一个es实例即为一个节点,也是集群的一部分,它存储你的数据,并参与集群的索引和搜索。和集群一样,节点也是通过唯一的名字去区分,默认名字是一个随机的UUID,当服务器启动的时候就会设置到节点。你也可以自定义节点的名称。名称对管理员来说十分重要,它可以帮助你辨认出集群中的各个服务器和哪个节点相对应。
-
分片(Shard)和副本(Replica)
ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。 -
集群(Cluster)
集群是一个或多个节点(服务器)的集合,它们联合起来保存所有的数据(索引以分片为单位分散到多个节点上保存)并且可以在所有的节点上进行索引和搜索操作。集群通过一个唯一的名字区分,默认的名字是“elasticsearch”。这个名字十分重要,因为一个节点仅仅可以属于一个集群,并根据集群名称加入集群。
与关系型数据库核心概念对比
Elasticsearch | 关系型数据库(如Mysql) |
---|---|
索引Index | 数据库Database |
类型Type(8.x版本已废弃) | 表Table |
文档Document | 数据行Row |
字段Field | 数据列Column |
映射Mapping | 约束Schema |
数据类型
Elasticsearch 8.x中已经完全删除了数据类型,创建映射时也不再支持使用type
字段指定数据类型,不然会报错"index" is not a valid parameter. Allowed parameters are "create", "error_trace"
这里就不继续介绍数据类型了
安装和启动
Windows
1.去官网Download Elasticsearch | Elastic下载windows版本压缩包,然后解压;
2.修改config
目录下的elasticsearch.yml
文件,将截图中的两个配置项true
改为false
,不然会报错[WARN ][o.e.h.n.Netty4HttpServerTransport] [BF-202205061541] received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress=/[0:0:0:0:0:0:0:1]:9200, remoteAddress=/[0:0:0:0:0:0:0:1]:62134}
3.双击bin/elasticsearch.bat
脚本启动服务
4.打开浏览器访问http://localhost:9200/
,输出下面的json信息表示启动成功
{"name": "BF-202205061541","cluster_name": "elasticsearch","cluster_uuid": "0JlZuKgbSWa3DGX44DnxgQ","version": {"number": "8.12.2","build_flavor": "default","build_type": "zip","build_hash": "48a287ab9497e852de30327444b0809e55d46466","build_date": "2024-02-19T10:04:32.774273190Z","build_snapshot": false,"lucene_version": "9.9.2","minimum_wire_compatibility_version": "7.17.0","minimum_index_compatibility_version": "7.0.0"},"tagline": "You Know, for Search"
}
Docker
-
拉取镜像
docker pull elasticsearch:8.12.2 # 版本号自己选择
-
创建并启动容器
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -d elasticsearch:8.12.2
-
设置密码
docker exec -it elasticsearch # 进入docker cd /usr/share/elasticsearch/bin # 进入elasticsearch目录 ./elasticsearch-setup-passwords interactive #要同时设置内置6个账户的密码
-
访问elasticsearch
浏览器打开
https://192.168.204.128:9200
即可访问,需要输入上面设置的账号和密码,注意这里是要https访问
安装分词器
elasticsearch有默认的分词器,但是对中文不太友好,我们可以单独安装适用于中文的分词器ik;根据你的es版本再Releases · infinilabs/analysis-ik (github.com)下载对应的压缩包,然后解压到es目录下的plugins/ik
目录,然后重启es服务即可
插件
es-client(推荐)
elasticsearch的浏览插件,项目主页 | es-client (esion.xyz),提供各个浏览器插件,在插件市场都能搜得到,界面美观
elasticsearch-head
elasticsearch-head是一种便捷查询操作elasticsearch库的可视化工具,具备集群管理、增删查改等功能,用于监控 Elasticsearch 状态的客户端插件,包括数据可视化、执行增删改查操作等,有npm、docker和浏览器扩展版本(仅Chrome浏览器),按照下面文档选择自己喜欢的方式安装即可
mobz/elasticsearch-head: A web front end for an elastic search cluster (github.com)
php调用
由于实际开发中项目都是使用php框架开发,所以以下分别用ThinkPHP5和Laravel框架实现
ThinkPHP框架
- 安装扩展
composer require elasticsearch/elasticsearch
composer dump-autoload
-
索引和文档的增删改查
<?phpnamespace app\index\controller;use Elasticsearch\ClientBuilder;class Elasticsearch {// 客户端protected $client = null;//索引名称protected $indexName = 'test';public function __construct(){try {$this->client = ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();} catch (\Exception $e) {die($e->getMessage());}}/*** 创建索引* @desc 相当于mysql的数据库,索引只需要创建一次*/public function createIndex(){$params = ['index' => $this->indexName, // 索引名称'body' => ['settings' => ['number_of_shards' => 5, //分片数量:一个索引库将拆分成多片分别存储不同的结点,默认5个'number_of_replicas' => 0 //为每个分片分配的副本数,replica shard是primary shard的副本,负责容错,以及承担读请求负载,如果服务器只有一台,只能设置为0,不然会报错创建超时failed to process cluster event (create-index [test], cause [api]) within 30s],//创建文档映射,就是文档存储在ES中的数据结构,这里以商城商品搜索为例,建立商品的映射'mappings' => ['properties' => ['goods_id' => [ //商品id'type' => 'keyword','index' => 'true',],'goods_name' => [ //商品名称'type' => 'text', //数据类型为text,支持分词;类型为keyword,不支持分词,只能精确索引;8.x以上版本不再支持string等类型'index' => 'true', //字段可以被索引,也就是能用来当做查询条件来查询,只能填写true和false'analyzer' => 'ik_max_word', //索引分词器,用于字符串类型,这里使用中文分词器ik,用默认分词器可以省略'search_analyzer' => 'ik_smart'//搜索分词器,用于搜索关键词的分词器],'goods_desc' => [ //商品描述'type' => 'keyword','index' => 'false', //字段不可以被索引,不能用来当做查询条件来查询],'stock' => [ //商品库存'type' => 'keyword','index' => 'true',],'created_at' => [ //创建时间'type' => 'keyword','index' => 'true',],'status' => [ //上架状态'type' => 'keyword','index' => 'true',],]]]];try {return $this->client->indices()->create($params);} catch (\Exception $e) {return $e->getMessage();}}/*** 删除索引*/public function deleteIndex(){$params = ['index' => $this->indexName, // 索引名称];try {return $this->client->indices()->delete($params);} catch (\Exception $e) {return $e->getMessage();}}/*** 查看映射*/public function getMapping(){$params = ['index' => $this->indexName, // 索引名称];try {return $this->client->indices()->getMapping($params);} catch (\Exception $e) {return $e->getMessage();}}/*** 新增文档*/public function addDoc(){$params = ['index' => $this->indexName, // 索引名称'id' => 1, //文档id,可省略,默认生成随机id'body' => ['goods_id' => 1, //商品id'goods_name' => '爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)', //商品名称'goods_desc' => '煎饼果子', //商品描述'stock' => 100, //库存'created_at' => '2019-06-01 00:00:00', //创建时间'status' => 1, //上架状态]];try {return json_encode($this->client->index($params));} catch (\Exception $e) {return $e->getMessage();}}/*** 获取文档*/public function getDoc(){$params = ['index' => $this->indexName, // 索引名称'id' => 1, //文档id];try {return json_encode($this->client->get($params));} catch (\Exception $e) {return $e->getMessage();}}/*** 更新文档*/public function updateDoc(){$params = ['index' => $this->indexName, // 索引名称'id' => 1, //文档id'body' => ['doc' => ['goods_name' => '爆款煎饼(传统双蛋煎饼+肉松+优质火腿片+配菜+薄脆)', //更新商品名称]]];try {return json_encode($this->client->update($params));} catch (\Exception $e) {return $e->getMessage();}}/*** 删除文档*/public function deleteDoc(){$params = ['index' => $this->indexName, // 索引名称'id' => 1, //文档id];try {return json_encode($this->client->delete($params));} catch (\Exception $e) {return $e->getMessage();}}/*** 查询文档** 查询条件* must(且):数组里面的条件都要满足,该条数据才被选择,所有的条件为且的关系* must_not(或,然后取反):数组里面的条件满足其中一个,该条数据则不被选择* should(或):数组里面的条件满足其中一个,该条数据被选择*/public function searchDoc(){$keywords = '火腿煎饼'; // 查询关键词$params = ['index' => $this->indexName, // 索引名称'body' => ['query' => ['bool' => ['should' => [ //should:模糊查询(or);must:精确查询(and);must_not:or取反;'match' => ['goods_name' => $keywords], //match:匹配字段;range:范围查询]],],'sort' => ['stock' => ['order' => 'desc']], // 排序'from' => 0, // 分页起始位置'size' => 10 // 分页记录数量]];try {return json_encode($this->client->search($params),JSON_UNESCAPED_UNICODE);} catch (\Exception $e) {return $e->getMessage();}}//testpublic function test(){ // $res = 123; // $res = $this->deleteIndex(); // $res = $this->createIndex(); // $res = $this->getMapping(); // $res = $this->addDoc(); // $res = $this->getDoc(); // $res = $this->updateDoc(); // $res = $this->deleteDoc();$res = $this->searchDoc();var_dump($res);} }
Laravel框架
方式一
参考上面的ThinkPHP框架调用
方式二
Laravel框架除了能像tp框架一样自己写es的功能,它还有专门的es扩展包,并且支持在model中使用es及导入数据
-
安装扩展包
composer require elasticsearch/elasticsearch composer require tamayo/laravel-scout-elastic composer require laravel/scout
-
发布配置
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
-
修改配置
修改
config/scout.php
文件的配置,将驱动'driver' => env('SCOUT_DRIVER', 'algolia')
改为'driver' => env('SCOUT_DRIVER', 'elastic')
然后最文件增加elasticsearch配置
/* |-------------------------------------------------------------------------- | Elasticsearch Configuration |-------------------------------------------------------------------------- | | Here you may configure your Elasticsearch settings. | */ 'elasticsearch' => ['index' => env('ELASTICSEARCH_INDEX', 'laravel'), //laravel就是索引的名字,可以根据你的需求随便起'hosts' => [env('ELASTICSEARCH_HOST', 'http://127.0.0.1:9200'),],],
当然,你可以在
.env
环境配置文件中覆盖配置ELASTICSEARCH_HOST=127.0.0.1:9200
-
使用es
public function handle(){$host = config('scout.elasticsearch.hosts');$index = config('scout.elasticsearch.index');$client = ClientBuilder::create()->setHosts($host)->build();if ($client->indices()->exists(['index' => $index])) {$this->warn("Index {$index} exists, deleting...");$client->indices()->delete(['index' => $index]);}$this->info("Creating index: {$index}");return $client->indices()->create(['index' => $index,'body' => ['settings' => ['number_of_shards' => 1,'number_of_replicas' => 0],'mappings' => ['_source' => ['enabled' => true],'properties' => ['id' => ['type' => 'long'],'title' => ['type' => 'text','analyzer' => 'ik_max_word','search_analyzer' => 'ik_smart'],'subtitle' => ['type' => 'text','analyzer' => 'ik_max_word','search_analyzer' => 'ik_smart'],'content' => ['type' => 'text','analyzer' => 'ik_max_word','search_analyzer' => 'ik_smart']],]]]); }
-
Model中使用
参考官方文档Scout 全文搜索 | 官方扩展包 |《Laravel 6 中文文档 6.x》| Laravel China 社区 (learnku.com)
相关文章:

php使用ElasticSearch
ElasticSearch简介 Elasticsearch 是一个分布式的、开源的搜索分析引擎,支持各种数据类型,包括文本、数字、地理、结构化、非结构化。 Lucene与ElasticSearch Apache Lucene是一款高性能的、可扩展的信息检索(IR)工具库…...

wpf prism左侧抽屉式菜单
1.首先引入包MaterialDesignColors和MaterialDesignThemes 2.主页面布局 左侧菜单显示在窗体外,点击左上角菜单图标通过简单的动画呈现出来 3.左侧窗体外菜单 <Grid x:Name"GridMenu" Width"150" HorizontalAlignment"Left" Ma…...

揭秘AI新纪元:近期人工智能发展的惊人突破与未来展望
近年来,人工智能(AI)领域的发展可谓是日新月异,其强大的潜力和广阔的应用前景引发了全球范围内的关注。本文将带您领略近期AI发展的风采,一探这个神奇领域的未来展望。 首先,让我们回顾一下近期AI领域的几…...

C语言基础练习——Day01
目录 选择题 编程题 打印从1到最大的n位数 计算日期到天数转换 选择题 1、执行下面程序,正确的输出是 int x5,y7; void swap(int x, int y) {int z;zx;xy;yz; } int main() { int x3,y8; swap(int x, int y);printf("%d,%d\n",x, y);return …...

用云手机进行舆情监测有什么作用?
在信息爆炸的时代,舆情监测成为企业和政府决策的重要工具。通过结合云手机技术,舆情监测系统在品牌形象维护、市场竞争、产品研发、政府管理以及市场营销等方面发挥着关键作用,为用户提供更智能、高效的舆情解决方案。 1. 品牌形象维护与危机…...

神经网络(neural network)
在这一章中我们将进入深度学习算法,学习一些神经网络相关的知识,这些是有更加强大的作用,更加广泛的用途。 神经元和大脑(neurons and the brain): 我们对于我们的编程的进步主要来自我们对于大脑的研究,根据我们对于大脑的研究…...

微信小程序用户登陆和获取用户信息功能实现
官方文档: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 接口说明: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html 我们看官方这个图,梳理一下用户…...

2024年3月8日 晨会汇报
Good morning, colleagues! Before I dive into today’s work, I’d like to take a moment to share some updates over my work activities from yesterday and outline my agenda for today. Firstly, let me touch on the work activities from yesterday. Yesterday’…...

去电脑维修店修电脑需要注意什么呢?装机之家晓龙
每当电脑出现故障时,你无疑会感到非常沮丧。 如果计算机已过了保修期,您将无法享受制造商的免费保修服务。 这意味着您必须自费找到一家电脑维修店。 去电脑维修店并不容易。 大家一定要知道,电脑维修非常困难,尤其是笔记本电脑维…...

国家妇女节放假是法定的假日
在这个充满活力和希望的春天,我们迎来了一个特殊的节日——国家妇女节。这是一个属于所有女性的节日,是一个庆祝女性成就、关爱女性权益的时刻。在这个特殊的日子里,我们不禁要问:国家妇女节放假是法定假日吗?让我们一…...

Pytorch线性回归实现(Pycharm实现)
步骤都在注释里写清楚了,可以自己调整循环的次数观察输出的w与b和loss的值 import torch#学习率,用来进行w和b的更新 learning_rate 0.01 #1. 准备数据 #这里使用y3x0.8.也就是w3,b0.8.创造一个500行1列的数据 xtorch.rand([500,1]) y_true…...

2024新疆专升本考试报名教程详解
2024新疆专升本报名时间已经开始了,想要参加考试报名的同学可以提前准备好报名照...

unicloud 云数据库概念及创建一个云数据库表并添加记录(数据)
云数据库概念 uniCloud提供了一个 JSON 格式的文档型数据库。顾名思义,数据库中的每条记录都是一个 JSON 格式的文档。 它是 nosql 非关系型数据库,如果您之前熟悉 sql 关系型数据库,那么两者概念对应关系如下表: 关系型JSON 文…...

想交易盈利?Anzo Capital昂首资本发现了一本畅销书
要想在复杂多变的外汇市场中迅速加深了解并想通过交易每天都可以盈利,是通过每天阅读大量的书籍吗?是每天成为行业培训网络资源和论坛的常客吗?是通过花钱请有经验的交易者进行个人培训吗?还是进行EA交易呢? 都不是&a…...

美国站群服务器租用需要考虑哪些关键点
美国站群服务器租用通常指的是租用位于美国数据中心的服务器,这些服务器具备多个IP地址,适合用于建立和管理多个网站(即站群)。那么美国站群服务器租用需要考虑哪些关键点,RAKsmart小编为您整理发布美国站群服务器租用需要考虑哪些关键点。 在…...

如何构建Hive数据仓库Hive 、数据仓库的存储方式 以及hive数据的导入导出
什么是Hive hive是基于Hadoop的一个数据仓库工具,可以将结构化数据映射为一张表。 hive支持使用sql语法对存储的表进行查询 (本质上是把sql转成mapreduce的任务执行) Hive有三个特点: hive所存储的数据是放在HDFS文件系统中的h…...

【Linux】软件管理器yum和编辑器vim
🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 一、Linux下安装软件的方案1.1 源代码安装1.2 rpm安装1.3 yum安装 二、Linux软件…...

怎么才能确定螺栓是拧紧了——SunTorque智能扭矩系统
螺栓拧紧的标准并非仅仅依赖于螺栓的外观,而是依赖于几个关键因素,包括扭矩、预紧力和材料疲劳等。下面SunTorque智能扭矩系统和大家将详细讨论这些因素,并给出如何判断螺栓是否已经拧紧的方法。 SunTorque智能扭矩系统 首先,让我…...

西门子S120故障报警F30003的解决办法总结
西门子S120故障报警F30003的解决办法总结 如下图所示,压机在回程时突然出现报警,故障代码为:30003, 如下图所示,查找手册可以看到F30003的报警分析为:直流母线欠压 如下图所示,本来想测量输入端…...

探索vue框架的世界: 内部、外部样式和内联样式动态绑定的方法
在实际项目中,经常会遇到这样的场景,可以通过逻辑层中设定的变量,在视图层中来呈现不同的样式,那么这种动态绑定样式的方式如何实现呢? 本篇文章,博主将和大家分享动态绑定内联样式style 和 动态绑定内部和…...

代码随想录算法训练营第三十八天|动态规划|理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
理论基础 文章 说实话,没做过题连理论基础都看不懂 1 确定dp数组(dp table)以及下标的含义 2 确定递推公式 3 dp数组如何初始化 4 确定遍历顺序 5 举例推导dp数组 这道题目我举例推导状态转移公式了么? 我打印dp数组的日志了么&…...

运维知识点-JBoss
JBoss 介绍介绍 JBoss是一个基于J2EE的开放源代码的应用服务器,也是一个运行EJB(Enterprise JavaBean)的容器和服务器。它支持EJB 1.1、EJB 2.0和EJB3的规范,体现了J2EE规范中最新的技术。JBoss遵循LGPL许可,可以在任何商业应用中免费使用,并且由开源社区开发,这使得JB…...

HarmonyOS—配置编译构建信息
在进行应用/服务的编译构建前,需要对工程和编译构建的Module进行设置。API Version 9、API Version 8与API Version 4~7的构建体系不同,因此在设置编译构建信息时也存在差异: API Version 9:需要对构建配置文件、构建脚本、应用依…...

Chrome浏览器好用的几个扩展程序
Chrome好用的扩展程序 背景目的介绍JsonHandle例子未完待续。。。。。。 背景 偶然在往上看到Chrome有很多好用的扩展程序,比较好用,因此记录下比较实用的扩展程序。 目的 记录Chrome浏览器好用的插件。 介绍 JsonHandle下载以及无法扩展插件的解决…...

Enzo Life Sciences Cortisol(皮质醇) ELISA kit
皮质醇又称为氢化可的松,是一种由胆固醇合成的类固醇激素。它是肾上腺皮质产生和分泌的主要糖皮质激素。皮质醇在血液中以游离皮质醇的形式存在,或与皮质类固醇结合球蛋白(CBG)结合。皮质醇水平在早上7点左右最高,晚上最低。皮质醇可以调节新…...

面试经典150题 -- 二分查找 (总结)
总的链接 : 面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台 二分算法模板 : 详见 : 基础二分学习笔记-CSDN博客 35 . 搜索插入位置 链接 : . - 力扣(LeetCode) 思路 : 用二分查找第一个>t…...

蓝牙耳机怎么选择比较好?2024年热门机型推荐大揭秘!
蓝牙耳机已经成为了我们日常生活中不可或缺的一部分,随着技术的发展,人们对蓝牙耳机的要求也在不断提升,不仅希望音质出色,还希望能够在不同的场景下使用。然而,如何挑选一款适合自己的蓝牙耳机却是一门学问。今天&a…...

强制Unity崩溃的两个方法
在Unity中,这两种方法都可以用于强制使应用程序崩溃,但它们的作用略有不同: Application.ForceCrash(0); 这个方法会强制应用程序崩溃,并且参数传入的是一个整数值。当参数为0时,它会导致应用程序崩溃并显示一个“Acce…...

中间件 | Redis - [big-key hot-key]
INDEX 1 big-keyhot-key 1 big-key 分类 字符串型 big-key:字符串最大可以到 512M集合型 big-key:集合个数可以到 2^23 问题 内存空间不均匀指令耗时增加:redis 是单线程的,部分操作的时间复杂度是 O(n) 的,big-ke…...

STM32基础--自己构建库函数
什么是 STM32 函数库 固件库是指“STM32 标准函数库”,它是由 ST 公司针对 STM32 提供的函数接口,即API (Application Program Interface),开发者可调用这些函数接口来配置 STM32 的寄存器,使开发人员得以脱离最底层的寄存器操作…...