MySQL原理之UUID主键分析,插入或更新语法分析

文章目录

  • 1 MySQL不能用UUID做主键
    • 1.1 前言
    • 1.2 mysql和程序实例
      • 1.2.1 准备工作
      • 1.2.2 开始测试
      • 1.2.3 程序写入结果
      • 1.2.4 效率测试结果
    • 1.3 使用uuid和自增id的索引结构对比
      • 1.3.1 自增id
      • 1.3.2 uuid
    • 1.4 自增id缺点
    • 1.5 雪花算法
  • 2 插入或更新
    • 2.1 on duplicate key
      • 2.1.1 定义
      • 2.1.2 values函数
      • 2.1.3 注意事项
      • 2.1.4 操作分析
    • 2.2 replace info
      • 2.2.1 定义
      • 2.2.2 操作
      • 2.2.3 MySQL中特殊插入语法
    • 2.3 INSERT IGNORE

1 MySQL不能用UUID做主键

1.1 前言

mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复雪花id(long形且唯一,单机递增),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究竟有什么坏处?

1.2 mysql和程序实例

1.2.1 准备工作

要说明这个问题,我们首先来建立三张表
分别是user_auto_key,user_uuid,user_random_key分别表示自动增长的主键,uuid作为主键,随机key作为主键,其它我们完全保持不变.
根据控制变量法,我们只把每个表的主键使用不同的策略生成,而其他的字段完全一样,然后测试一下表的插入速度和查询速度:

注:这里的随机key其实是指用雪花算法算出来的前后不连续不重复无规律的id,一串18位长度的long值
id自动生成表:

create table user_key_auto(id int UNSIGNED not null auto_increment,user_id BIGINT(64) not NULL DEFAULT 0,user_name VARCHAR(64) not NULL DEFAULT '',sex int(2) not NULL,address VARCHAR(255) not null DEFAULT '',city VARCHAR(64) not NULL DEFAULT '',email VARCHAR(64) not nulT DEFAULT '',state int(6) not NULL DEFAULT 0,PRIMARY KEY(id),key user_name_key(user_name)
)ENGINE=INNODB

用户uuid表

create table user_uuid(id VARCHAR(36) not null,user_id BIGINT(64) not NULL DEFAULT 0,user_name VARCHAR(64) not NULL DEFAULT '',sex int(2) not NULL,address VARCHAR(255) not null DEFAULT '',city VARCHAR(64) not NULL DEFAULT '',email VARCHAR(64) not null DEFAULT '',state int(6) not NULL DEFAULT 0,PRIMARY KEY(id),key user_name_key(user_name)
)ENGINE=INNODB

随机主键表:

create table user_random_key(id BIGINT(64) not null DEFAULT 0,user_id BIGINT(64) not NULL DEFAULT 0,user_name VARCHAR(64) not NULL DEFAULT '',sex int(2) not NULL,address VARCHAR(255) not null DEFAULT '',city VARCHAR(64) not NULL DEFAULT '',email VARCHAR(64) not null DEFAULT '',state int(6) not NULL DEFAULT 0,PRIMARY KEY(id),key user_name_key(user_name)
)ENGINE=INNODB

1.2.2 开始测试

光有理论不行,直接上程序,使用spring的jdbcTemplate来实现增查测试:
技术框架:springboot+jdbcTemplate+junit+hutool,程序的原理就是连接自己的测试数据库,然后在相同的环境下写入同等数量的数据,来分析一下insert插入的时间来进行综合其效率,为了做到最真实的效果,所有的数据采用随机生成,比如名字、邮箱、地址都是随机生成。

import cn.hutool.core.collection.CollectionUtil;
import com.wyq.mysqldemo.databaseobject.UserKeyAuto;
import com.wyq.mysqldemo.databaseobject.UserKeyRandom;
import com.wyq.mysqldemo.databaseobject.UserKeyUUID;
import com.wyq.mysqldemo.diffkeytest.AutoKeyTableService;
import com.wyq.mysqldemo.diffkeytest.RandomKeyTableService;
import com.wyq.mysqldemo.diffkeytest.UUIDKeyTableService;
import com.wyq.mysqldemo.util.JdbcTemplateService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StopWatch;
import java.util.List;
@SpringBootTest
class MysqlDemoApplicationTests {@Autowiredprivate JdbcTemplateService jdbcTemplateService;@Autowiredprivate AutoKeyTableService autoKeyTableService;@Autowiredprivate UUIDKeyTableService uuidKeyTableService;@Autowiredprivate RandomKeyTableService randomKeyTableService;@Testvoid testDBTime() {StopWatch stopwatch = new StopWatch("执行sql时间消耗");/*** auto_increment key任务*/final String insertSql = "INSERT INTO user_key_auto(user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?)";List<UserKeyAuto> insertData = autoKeyTableService.getInsertData();stopwatch.start("自动生成key表任务开始");long start1 = System.currentTimeMillis();if (CollectionUtil.isNotEmpty(insertData)) {boolean insertResult = jdbcTemplateService.insert(insertSql, insertData, false);System.out.println(insertResult);}long end1 = System.currentTimeMillis();System.out.println("auto key消耗的时间:" + (end1 - start1));stopwatch.stop();/*** uudID的key*/final String insertSql2 = "INSERT INTO user_uuid(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";List<UserKeyUUID> insertData2 = uuidKeyTableService.getInsertData();stopwatch.start("UUID的key表任务开始");long begin = System.currentTimeMillis();if (CollectionUtil.isNotEmpty(insertData)) {boolean insertResult = jdbcTemplateService.insert(insertSql2, insertData2, true);System.out.println(insertResult);}long over = System.currentTimeMillis();System.out.println("UUID key消耗的时间:" + (over - begin));stopwatch.stop();/*** 随机的long值key*/final String insertSql3 = "INSERT INTO user_random_key(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";List<UserKeyRandom> insertData3 = randomKeyTableService.getInsertData();stopwatch.start("随机的long值key表任务开始");Long start = System.currentTimeMillis();if (CollectionUtil.isNotEmpty(insertData)) {boolean insertResult = jdbcTemplateService.insert(insertSql3, insertData3, true);System.out.println(insertResult);}Long end = System.currentTimeMillis();System.out.println("随机key任务消耗时间:" + (end - start));stopwatch.stop();String result = stopwatch.prettyPrint();System.out.println(result);}

1.2.3 程序写入结果

user_key_auto写入结果:
在这里插入图片描述

user_random_key写入结果:
在这里插入图片描述

user_uuid表写入结果:
在这里插入图片描述

1.2.4 效率测试结果

在这里插入图片描述

在已有数据量为130W的时候:我们再来测试一下插入10w数据,看看会有什么结果:
在这里插入图片描述

可以看出在数据量100W左右的时候,uuid的插入效率垫底,并且在后序增加了130W的数据,uuid的时间又直线下降

时间占用量总体可以打出的效率排名为:auto_key>random_key>uuid,uuid的效率最低,在数据量较大的情况下,效率直线下滑。那么为什么会出现这样的现象呢?带着疑问,我们来探讨一下这个问题:

1.3 使用uuid和自增id的索引结构对比

1.3.1 自增id

使用自增id的内部结构
在这里插入图片描述
自增的主键的值是顺序的,所以Innodb把每一条记录都存储在一条记录的后面。当达到页面的最大填充因子时候(innodb默认的最大填充因子是页大小的15/16,会留出1/16的空间留作以后的修改):

  • 下一条记录就会写入新的页中,一旦数据按照这种顺序的方式加载,主键页就会近乎于顺序的记录填满,提升了页面的最大填充率,不会有页的浪费
  • 新插入的行一定会在原有的最大数据行下一行,mysql定位和寻址很快,不会为计算新行的位置而做出额外的消耗
  • 减少了页分裂和碎片的产生

1.3.2 uuid

使用uuid的索引内部结构
在这里插入图片描述

因为uuid相对顺序的自增id来说是毫无规律可言的,新行的值不一定要比之前的主键的值要大,所以innodb无法做到总是把新行插入到索引的最后,而是需要为新行寻找新的合适的位置从而来分配新的空间。
这个过程需要做很多额外的操作,数据的毫无顺序会导致数据分布散乱,将会导致以下的问题:

  • 写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb在插入之前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机IO
  • 因为写入是乱序的,innodb不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少需要修改三个页以上
  • 由于频繁的页分裂,页会变得稀疏并被不规则的填充,最终会导致数据会有碎片
  • 在把随机值(uuid和雪花id)载入到聚簇索引(innodb默认的索引类型)以后,有时候会需要做一次OPTIMEIZE TABLE来重建表并优化页的填充,这将又需要一定的时间消耗。

结论:使用innodb应该尽可能的按主键的自增顺序插入,并且尽可能使用单调的增加的聚簇键的值来插入新行

1.4 自增id缺点

那么使用自增id就完全没有坏处了吗?并不是,自增id也会存在以下几点问题:

  • 别人一旦爬取你的数据库,就可以根据数据库的自增id获取到你的业务增长信息,很容易分析出你的经营情况
  • 对于高并发的负载,innodb在按主键进行插入的时候会造成明显的锁争用,主键的上界会成为争抢的热点,因为所有的插入都发生在这里,并发插入会导致间隙锁竞争
  • Auto_Increment锁机制会造成自增锁的抢夺,有一定的性能损失
    Auto_increment的锁争抢问题,如果要改善,需要调优innodb_autoinc_lock_mode的配置

点击了解MySQL自增锁机制

参考连接:https://mp.weixin.qq.com/s/px-vRWikt8xp7b3ZCr27uw

1.5 雪花算法

点击了解MySQL分布式环境下生成全局自增有序ID(雪花算法Snowflake)

2 插入或更新

MySQL中假如想要在插入时没有就插入有则更新,可以用MyISAM引擎的merge或者InnoDB引擎的on duplicate key,现在主要是用InnoDB,下面主要介绍on duplicate key

2.1 on duplicate key

2.1.1 定义

如果在INSERT语句末尾指定了 on duplicate key update,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE;如果不会导致唯一值列重复的问题,则插入新行。

2.1.2 values函数

values函数使用说明:在一个 INSERT … ON DUPLICATE KEY UPDATE … 语句中,可以在 UPDATE 子句中使用 VALUES(col_name ) 函数,用来访问来自该语句的 INSERT 部分的列值。换言之,UPDATE 子句中的 VALUES(col_name ) 访问需要被插入的 col_name 的值 , 并不会发生重复键冲突。这个函数在多行插入中特别有用。

values(col_name)函数只是取当前插入语句中的插入值,并没有累加功能。 如:count = values(count) 取前面 insert into 中的 count 值,并更新。
当有多条记录冲突,需要插入时,前面的更新值都被最后一条记录覆盖,所以呈现出取最后一条更新的现象。如:count = count + values(count) 依然取前面 insert into 中的 count 值,并与原记录值相加后更新回数据库,这样,当多条记录冲突需要插入时,就实现了不断累加更新的现象
注意VALUES() 函数只在 INSERT ... UPDATE 语句中有意义,而在其它情况下只会返回 NULL

2.1.3 注意事项

注意事项:

  • insert into ... on duplicate key update ... values() 这个语句,尽管在冲突时执行了更新,并没有插入,但是发现依然会占用 id 序号(自增),出现很多丢失的 id
  • 因为这是个插入语句,所以不能加where条件
  • 如果是插入操作,受到影响行的值为1;如果更新操作,受到影响的行的值为2;如果更新的数据和已有的数据比对一样(就相当于没变,所有值保持不变),受到影响的行的值为0
  • 更新的内容中unique key或者primary key最好按照一个来判断是否重复,不然不能保证语句执行正确(有任意一个unique key重复就会走更新);尽量不对存在多个唯一键的talbe使用该语句,避免可能导致数据错乱
  • 在有可能有并发事物执行的insert语句下不要使用该语句,可能导致产生dead lock
  • 如果数据表id是自动递增的不建议使用该语句;id不连续,如果前面更新的比较多,新增的下一条会相应跳跃的更大
  • 该语句是mysql独有的语法,如果可能涉及到其他数据库语言要慎重使用

2.1.4 操作分析

创建案例表 word_count(单词计数表)use test;CREATE TABLE IF NOT EXISTS word_count (id int(11) NOT NULL AUTO_INCREMENT,word varchar(64) NOT NULL,count int(11) DEFAULT 0,date date NOT NULL,PRIMARY KEY (id),UNIQUE KEY word (word, date)  // (word,date) 两字段组合唯一) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;执行第一次:(首次数据库表中没有数据,正常插入)
insert into word_count (word, count, date) values 
('a',5,curdate()) 
on duplicate key update count=values(count);# 结果显示:id   word    count    date 1    a       5        2023-03-11执行第二次:(与第一次的唯一(word,date)冲突,执行更新)
insert into word_count (word, count, date) values 
('a',6,curdate()) 
on duplicate key update count=values(count);# 结果显示:id   word    count    date 1    a       6        2023-03-11  (更新)执行第三次:
insert into word_count (word, count, date) values 
('a',6,curdate()-1),    // 取前一天,不会冲突
('a',7,curdate()) // 冲突
on duplicate key update count=values(count);# 结果显示:id   word    count    date 1    a       7        2023-03-11  (更新)3    a       6        2023-03-10  (新插入)执行第四次:(更新冲突的最后一条插入值)
insert into word_count (word, count, date) values 
('a',2,curdate()),  // 冲突
('a',1,curdate())  // 冲突
on duplicate key update count=values(count);# 结果显示:id   word    count    date 1    a       1        2023-03-11  (更新最后一条插入值)3    a       6        2023-03-10  (不变)执行第五次:(更新冲突的累加插入值)
insert into word_count (word, count, date) values 
('a',2,curdate()),
('a',1,curdate()) 
on duplicate key update count=count+values(count); // 实现每行累加# 结果显示:id   word    count    date 1    a       4        2023-03-113    a       6        2023-03-10执行第六次:(无冲突插入,观察 id 键值,出现了很多丢失,id 直接跳到了 9insert into word_count (word, count, date) values 
('b',2,curdate())
on duplicate key update count=count+values(count);# 结果显示:id   word    count    date 1    a       4        2019-06-263    a       6        2019-06-259    b       2        2019-06-26

2.2 replace info

2.2.1 定义

咱们在运用数据库时能够会常常遇到这种状况。若是一个表在一个字段上建立了索引,当咱们再向这个表中运用现已存在的键值插进一条记载,那将会抛出一个主键抵触的过错。当然,咱们能够想用新记载的值来掩盖本来的记载值。若是运用传统的做法,有必要先运用 DELETE 句子删去原先的记载,然后再运用 INSERT 插进新的记载。而在MySQL中为咱们供给了一种新的解决方案,这即是 REPLACE 句子。
运用REPLACE插进一条记载时,若是不重复,REPLACE就和INSERT的功用相同,若是有重复记载,REPLACE就运用新记载的值来更换本来的记载值。

运用REPLACE的最大优点即是能够将DELETEINSERT合二为一,构成一个原子操作。这样就能够不用思考在一起运用DELETEINSERT时增加业务等杂乱操作了。
在运用REPLACE时,表中有必要有索引,并且这个索引地点的字段不能答应空值,不然REPLACE就和INSERT彻底相同的

在履行REPLACE后,体系回来了所影响的行数,若是回来1,阐明在表中并没有重复的记载,若是回来2,阐明有一条重复记载,体系主动先调用了DELETE删去这条记载,然后再记载用INSERT来刺进这条记载。若是回来的值大于2,那阐明有多个仅有索引,有多条记载被删去和刺进。

replace具备替换拥有唯一索引或者主键索引重复数据的能力,也就是如果使用replace into插入的数据的唯一索引或者主键索引与之前的数据有重复的情况,将会删除原先的数据,然后再进行添加。
语法:replace into table( col1, col2, col3 ) values ( val1, val2, val3 )
语义:向table表中col1, col2, col3列replace数据val1,val2,val3

2.2.2 操作

先查询:select * from word_count
# 结果显示:
1	a	9	2023-03-11
3	a	7	2023-03-10
12	c	4	2023-03-11
13	b	1	2023-03-11执行replace into 语句:
replace into word_count (word, count, date) values ('b',1,curdate());再次查询:select * from word_count
# 结果显示:
1	a	9	2023-03-11
3	a	7	2023-03-10
12	c	4	2023-03-11
14	b	1	2023-03-11

2.2.3 MySQL中特殊插入语法

MySQL中的INSERT句子和规范的INSERT不太相同,在规范的SQL句子中,一次刺进一条记载的INSERT句子只要一种办法。

INSERT INTO tablename(列名…) VALUES(列值);

而在MySQL中还有别的一种办法,如下的方法把列名和列值成对呈现和运用,如下面的句子将产生中样的作用

INSERT INTO tablename SET column_name1 = value1, column_name2 =
value2,;

2.3 INSERT IGNORE

MySQL中,可以使用INSERT IGNORE语句来忽略重复的记录。如果尝试插入的数据会导致重复键错误,那么INSERT IGNORE会跳过这条记录,而不是报错。

例如:

INSERT IGNORE INTO table (column1, column2) VALUES ('value1', 'value2');

在这个例子中,如果(‘value1’, ‘value2’)会导致重复键错误,那么这条插入语句就会被忽略,而不会插入数据。同时,这条SQL语句也不会报错,而是会继续执行下一条SQL语句(如果有的话)。

需要注意的是,INSERT IGNORE不仅会忽略重复键错误,还会忽略其他一些错误(例如数据溢出)。因此,应当确保要插入的数据确实是想要插入的,并且确实希望在出错时跳过插入,而不是报错。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

24年蓝桥杯及攻防世界赛题-MISC-3

21 reverseMe 复制图片&#xff0c;在线ocr识别&#xff0c;https://ocr.wdku.net/&#xff0c;都不费眼睛。 22 misc_pic_again ┌──(holyeyes㉿kali2023)-[~/Misc/tool-misc/zsteg] └─$ zsteg misc_pic_again.png imagedata … text: “$$KaTeX parse error: Undefined…

python基础(1)pyenv安装和对Django使用

pyenv安装 pyenv主要针对类 Unix 系统&#xff08;如 Linux、macOS&#xff09;用户&#xff0c;pyenv-win 是专为 Windows 开发的 pyenv 版本&#xff0c;允许您在不使用 WSL 的情况下管理多个 Python 版本和虚拟环境。 建议Git Bash&#xff1a; Powershell或Git Bash&…

功能测试干了三年,快要废了。。。

8年前刚进入到IT行业&#xff0c;到现在学习软件测试的人越来越多&#xff0c;所以在这我想结合自己的一些看法给大家提一些建议。 最近聊到软件测试的行业内卷&#xff0c;越来越多的转行和大学生进入测试行业&#xff0c;导致软件测试已经饱和了&#xff0c;想要获得更好的待…

Java键盘输入语句

编程输入语句 1.介绍:在编程中&#xff0c;需要接受用户输入的数据&#xff0c;就可以使用键盘输入语句来获取。 2.步骤&#xff1a; 1&#xff09;导入该类的所在包&#xff0c;java.util.* 2)创建该类对象&#xff08;声明变量&#xff09; 3&#xff09;调用里面的功能 3…

任务书与开题报告的区别与联系:如何让二者相辅相成

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 大家好&#xff01;今天咱们聊聊论文写作过程中两个让人又爱又恨的关键步骤&#xff1a;任务书和开题报告。 这两兄弟可是你毕业路上的第一关卡&#xff0c;搞不定它们&#xff0c;你后面别说论文了&#…

时序必读论文12|ICML22 FEDformer基于周期分解的长时序预测transformer架构

论文标题&#xff1a;FEDformer: Frequency Enhanced Decomposed Transformer for Long-term Series Forecasting 开源代码&#xff1a;https://github.com/DAMO-DI-ML/ICML2022-FEDformer 前言 FEDformer这篇文章发表于2022年的ICML。其实如果只比较性能的话&#xff0c;到…

微信如何发布学生查分?教师平台推荐!

学校和老师们都在面临着一个共同的问题&#xff1a;如何高效、便捷地发布学生成绩查询信息&#xff1f;在这个数字化时代&#xff0c;传统的纸质通知和口头传达方式已经无法满足家长和学生的需求。幸运的是&#xff0c;有了易查分这样的在线工具&#xff0c;发布学生查分变得简…

vitis Failed to create the part‘s controls解决方法

类似于 解决方法&#xff1a;重启vitis。 效果&#xff1a; 可以建立lab4了。

wallpaper engine壁纸提取

下载提取软件RavioliGameTools_v2.10.zip https://pan.baidu.com/s/14ZCVw3ucRERsB-GGGoCOqQ 2.运行RExtractor.exe 3.Input file(s)、Output directory填好 4.勾选Allow scanning of unkown files 5.点击Start

Ceph官方文档_01_Ceph简介

目录 Ceph介绍Ceph介绍 Ceph可用于向云平台提供Ceph对象存储,Ceph可用于向云平台提供Ceph块设备服务。Ceph可用于部署Ceph文件系统。所有Ceph存储群集部署开始都是先设置每个Ceph节点,然后再设置网络。 Ceph存储集群需要以下内容:至少一个Ceph监视器和至少一个Ceph管理器,…

vulnhub靶机:Breach 2.1详细过程

下载 下载地址&#xff1a;https://www.vulnhub.com/entry/breach-21,159/ 修改网络模式 根据靶机的描述得知该靶机适用于静态ip&#xff0c;即192.168.110.151&#xff1b;配置虚拟机的虚拟网络编辑器的仅主机模式&#xff0c;将其子网IP配置在110网段&#xff0c;并将攻击…

C++初阶学习第六弹------标准库中的string类

目录 一.标准库中的string类 二.string的常用接口函数 2.1string类对象的构造 2.2 string的容量操作 2.3 string类的访问与遍历 2.4 string类对象的修改 2.5 string类常用的非成员函数 三、总结 一.标准库中的string类 可以简单理解成把string类理解为变长的字符数组&#x…

2024.9.13 Python与图像处理新国大EE5731课程大作业,索贝尔算子计算边缘,高斯核模糊边缘,Haar小波计算边缘

1.编写一个图像二维卷积程序。它应该能够处理任何灰度输入图像&#xff0c;并使用以下内核进行操作&#xff1a; %matplotlib inline import numpy as np import matplotlib.pyplot as plt from scipy import linalg import random as rm import math import cv2# import and …

linux网络编程3

24.9.19学习目录 一.UDP&#xff08;续&#xff09;1.UDP编程2.注意点2.TFTPTFTP通信过程TFTP协议分析 一.UDP&#xff08;续&#xff09; 1.UDP编程 &#xff08;1&#xff09;sendto函数发送数据 向to结构体指针中指定的ip&#xff0c;发送UDP数据&#xff1b; 通过to和ad…

时间复杂度的常用符号+渐进时间复杂度分析

时间复杂度的常用符号 Θ \Theta Θ 如果 f ( n ) Θ ( g ( n ) ) f(n)\Theta(g(n)) f(n)Θ(g(n))&#xff0c;则 f ( n ) f(n) f(n) 与 g ( n ) g(n) g(n) 同阶。&#xff08;阶是指 f ( n ) f(n) f(n) 的指数&#xff0c;比如 n 2 n^2 n2 高于 n n n&#xff09; O O …

MacOS安装homebrew,jEnv,多版本JDK

1 安装homebrew homebrew官网 根据官网提示&#xff0c;运行安装命令 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装后&#xff0c;bash会提示执行两条命令 (echo; echo eval "$(/opt/homebrew/b…

海康威视摄像机和录像机的监控与回放

文章目录 海康威视摄像机和录像机的监控与回放1、海康威视监控设备简介1.1、摄像机二次开发1.1.1&#xff1a;协议选择 1.2&#xff1a;web集成1.2&#xff1a;标准协议对接1.2.1&#xff1a;ffmpeg软件转流1.2.2&#xff1a;开源监控软件shinobi1.2.3&#xff1a;使用nginx的R…

黑神话悟空mac可以玩吗

黑神话悟空mac上能不能玩对于苹果玩家来说很重要&#xff0c;那么黑神话悟空mac可以玩吗&#xff1f;目前是玩不了了&#xff0c;没有针对ios系统的版本&#xff0c;只能之后在云平台上找找了&#xff0c;大家可以再观望下看看。 黑神话悟空mac可以玩吗 ‌使用CrossOver‌&…

【海康威视面经】

海康威视面经 Java基础java常用集合 及其优缺点ArrayListVectorLinkedList Jvm调优监控发现问题工具分析问题 &#xff1a;性能调优GC频繁 出现内存泄漏 内存溢出CPU飙升 Synchronized和Volatile的比较反射线程池和new thread利弊高并发 集群 分布式 负载均衡 MySQL调优基础优化…

neo4j安装启动教程+对应的jdk配置

参考这位博主的视频教程&#xff1a;neo4j社区windows版下载 一、官网下载neo4j的安装包 &#xff08;1&#xff09;官网下载页面 &#xff08;2&#xff09;上一步 【download】之后&#xff0c;会自动下载&#xff0c;如果没有&#xff0c;点击【here】 这里可以看到一行字…