数据库规范化设计案例解析
1.介绍
数据库规范化设计是数据库设计的一种重要方法,旨在减少数据库中的冗余数据,提高数据的一致性,确保数据依赖合理,从而提高数据库的结构清晰度和维护效率。规范化设计通过应用一系列的规范化规则(或称“范式”)来实现。
1.1.常见的几种范式:
-
第一范式(1NF): 数据库表的每一列都是不可分割的基本数据项,同一列中的每个数据项都必须是单一值,即表是一个二维表,在任何一个时间点,每个列都只能有一个值,不允许有重复的列。
-
第二范式(2NF): 在第一范式的基础上,所有非主属性完全依赖于主键,而不仅仅是依赖于主键的一部分(针对组合主键)。这要求实现了第一范式的表必须把那些部分依赖的列移出去,独立成表,通过外键与原表关联。
-
第三范式(3NF): 在第二范式的基础上,所有非主属性不仅完全依赖于主键,而且还必须是直接依赖于主键,而不是通过其他非主属性依赖(即消除传递依赖)。这意味着表中的非主属性不依赖于其他非主属性。
-
BCNF(博伊斯-科得范式): 比3NF更严格,要求表中的每一个决定因素都必须是候选键。这主要处理了一些特殊情况,在这些情况下即使表满足3NF标准,也可能存在冗余。
数据库规范化设计的目的是为了减少数据冗余和改善数据完整性,但是过度规范化可能会导致查询性能的下降和数据操作的复杂性增加。因此,在实际的数据库设计过程中,通常需要在规范化与性能之间做出权衡。
1.2.规范化设计的基本思想和准则
把一个低一级的关系模型分解为高一级关系模型的过程,称为关系模型的规范化。关系 模型分解必须遵守两个准则。
- 无损连接性:信息不失真(不增减信息)。
- 函数依赖保持性:不破坏属性间存在的依赖关系。
规范化的基本思想是逐步消除不合适的函数依赖,使数据库中的各个关系模型达到某种 程度的分离。规范化解决的主要是单个实体的质量问题,是对于问题域中原始数据展现的正 规化处理。
规范化理论给出了判断关系模型优劣的理论标准,帮助预测模式可能出现的问题,是数 据库逻辑设计的指南和工具,具体有:
- 用数据依赖的概念分析和表示各数据项之间的关系。
- 消除 E-R 图中的冗余联系。
2.为什么要遵循数据库规范化设计
数据库规范化设计的出现主要是为了解决数据库在设计和使用过程中可能遇到的几个关键问题,从而提高数据库的效率和可维护性。这些问题包括:
-
数据冗余: 在未规范化的数据库中,相同的信息可能在多个地方重复存储。这不仅浪费存储空间,还可能导致数据更新时的不一致性。如果某个数据项在一个地方被更新而在另一个地方没有更新,那么就会产生数据不一致的问题。
-
更新异常(Update Anomalies): 当数据库表结构设计得不合理时,可能会出现更新异常,包括插入异常、更新异常和删除异常。比如,如果某些数据需要被重复存储,在更新时就需要更改多个地方,如果忘记更新某些地方,就会导致数据不一致。
-
插入异常(Insertion Anomalies): 在某些情况下,因为表的设计不合理,可能无法仅插入需要的信息而不插入其他额外信息。例如,如果一个表设计成同时存储员工信息和部门信息,那么在没有新员工加入时就无法仅添加一个新部门。
-
删除异常(Deletion Anomalies): 类似地,如果一个表中存储了多种类型的信息,删除记录时可能会导致某些本应保留的信息被意外删除。比如,如果删除了最后一个属于某一部门的员工记录,也可能意外地删除了该部门的信息。
数据库规范化设计通过将数据结构分解成较小的、逻辑上互相独立的表来解决这些问题。每个表专注于一个主题,并通过关键字(主键和外键)相互关联。这样做有几个优点:
- 减少了数据冗余,节省存储空间。
- 通过减少冗余,降低了数据不一致的风险。
- 简化了数据的维护,使插入、更新和删除操作更加直接且不易出错。
- 可以提高查询效率,因为查询可以针对更小、更专注的表执行。
总之,数据库规范化设计是为了提高数据的完整性和降低数据冗余,从而提高数据库的性能和维护的效率。然而,在实际应用中,过度规范化可能会导致查询性能下降,因此在数据库设计时需要根据具体情况做出平衡。
3.为什么有时候要反规范化设计【不遵循数据库规范化设计】
数据库的反规范化设计是规范化设计的反向过程,主要目的是为了优化数据库查询性能、减少查询复杂度、提高数据读取速度。反规范化通过有意地引入数据冗余和组合多个表来达到这些目的。在某些情况下,尽管规范化设计可以提高数据一致性并减少数据冗余,但它也可能导致查询性能下降,尤其是在需要频繁执行大量联结操作的大型数据库系统中。因此,在实际应用中,为了平衡规范化带来的好处与性能需求,可能会采取反规范化的策略。
反规范化设计的常见策略包括:
-
合并表: 将多个相关的表合并为一个表,减少查询时需要的联结操作。这样做的缺点是可能会增加数据冗余和维护的复杂度。
-
添加冗余列: 在某个表中添加额外的列来存储经常一起查询的数据,以避免执行联结。这可以提高查询性能,但需要额外的空间来存储冗余数据,并且在数据更新时需要维护这些冗余列的一致性。
-
预计算汇总信息: 存储计算得出的汇总信息(如总和、平均值等),避免每次查询时都进行计算。这适用于数据更新频率较低而查询频率较高的情况。
-
使用物化视图: 物化视图是基于SQL查询结果的表,实质上是将查询结果存储起来以便快速访问。它们可以用于存储经常需要执行的复杂查询的结果,从而提高这些查询的性能。
-
使用索引: 尽管不是传统意义上的反规范化技术,但通过为数据库表添加适当的索引,可以显著提高查询性能。索引可以帮助数据库更快地定位数据,尤其是在大量数据的表中。
反规范化设计需要谨慎进行,因为它可能会引入数据一致性和维护的问题。在决定使用反规范化时,重要的是要权衡其带来的性能提升与潜在的数据冗余和一致性维护成本之间的关系。通常,在数据读取操作远远多于数据更新操作,且系统性能是一个关键考虑因素的场景中,反规范化可能是一个有益的选择。
3.案例说明数据库设计过程
3.1.建立一个基础的样例
我们先建立一张表,这张表是一张用户信息表,其中有用户的基本信息,包含用户名、年龄以及地址。
CREATE TABLE "public"."tb_userinfo" ("id" int4 NOT NULL,"loginname" varchar(10),"username" varchar(10),"age" int4,"address" varchar(255),PRIMARY KEY ("id")
)
;COMMENT ON COLUMN "public"."tb_userinfo"."id" IS 'ID';COMMENT ON COLUMN "public"."tb_userinfo"."loginname" IS '用户登录名称';COMMENT ON COLUMN "public"."tb_userinfo"."username" IS '用户名称';COMMENT ON COLUMN "public"."tb_userinfo"."age" IS '年龄';COMMENT ON COLUMN "public"."tb_userinfo"."address" IS '地址';
INSERT INTO "public"."tb_userinfo"("id", "loginname", "username", "age", "address") VALUES (1, 'xiaocai', '小菜', 18, '北京市石景山区鲁谷街道');
3.2.第一范式
我们在看数据库设计时,也要结合现实情况去考虑我们的表是否满足范式。如上的案例在使用中如果对地址信息没有更加细节的操作则是满足第一范式的。
我们先来看看第一范式的具体定义:
数据库表的每一列都是不可分割的基本数据项,同一列中的每个数据项都必须是单一值,即表是一个二维表,在任何一个时间点,每个列都只能有一个值,不允许有重复的列。
从中我们可以提取出:
- 唯一性,表中的数据有主键,表中的每一行都是唯一的。
- 原子性,表中的每一列都是不可分割的基础数据项。
3.2.1.不满足第一范式的场景
当实际生产中我们需要查询用户表中北京市或者北京市石景山行政区范围的数据时,则是不满足第一范式的场景的。应为address在这个场景中需要细化,是可以拆分的。
所以我们为了使表满足第一范式,新增表(不修改,为了对比)tb_userinfo_1nf
CREATE TABLE "public"."tb_userinfo_1nf" ("id" int4 NOT NULL,"loginname" varchar(10),"username" varchar(10),"age" int4,"province" varchar(10),"prefecture_city" varchar(10),"county" varchar(10),"details_address" varchar(255),PRIMARY KEY ("id")
)
;COMMENT ON COLUMN "public"."tb_userinfo_1nf"."id" IS 'ID';COMMENT ON COLUMN "public"."tb_userinfo_1nf"."loginname" IS '用户登录名称';COMMENT ON COLUMN "public"."tb_userinfo_1nf"."username" IS '用户名称';COMMENT ON COLUMN "public"."tb_userinfo_1nf"."age" IS '年龄';COMMENT ON COLUMN "public"."tb_userinfo_1nf"."province" IS '省名称';
COMMENT ON COLUMN "public"."tb_userinfo_1nf"."prefecture_city" IS '市名称';
COMMENT ON COLUMN "public"."tb_userinfo_1nf"."county" IS '县名称';
COMMENT ON COLUMN "public"."tb_userinfo_1nf"."details_address" IS '详细地址';
INSERT INTO "public"."tb_userinfo_1nf"("id", "loginname", "username", "age", "province", "prefecture_city", "county", "details_address") VALUES (1, 'xiaocai', '小菜', 18, '北京市', '北京市区', '石景山区', '鲁谷街道');
3.2.1.1.后续影响
在上面的表结构调整中,我们有正面的作用也有负面的影响
3.2.1.1.1.正面作用
当我们需要按照行政区查询时,我们可以基于如下方式进行查询
select * from tb_userinfo_1nf where province='北京市' and prefecture_city='北京市区' and county='石景山区'
3.2.1.1.2.负面影响
在上面的满足第一范式的情况下,我们将address信息进行了拆解,但是造成了很多重复的操作,当我们需要修改行政区信息时,需要修改4个字段,分别为:province
、prefecture_city
、county
、details_address
,会造成:
- 遗漏修改导致数据库错误
- 更新字段多,数据操作效率降低
3.3.第二范式
在第一范式的修改中我们发现经过拆解之后,冗余字段多了。而且如果我们需要查询行政区树,得到的结果只能是tb_userinfo_1nf
表中可以查询到的数据,但是实际上北京市的行政区数据不以数据为转移,他就在那。
所以我们优化之前的表设计到第二范式如下:
CREATE TABLE "public"."tb_userinfo_2nf" ("id" int4 NOT NULL,"loginname" varchar(10),"username" varchar(10),"age" int4,"xzqdm" varchar(10),"details_address" varchar(255),PRIMARY KEY ("id")
)
;COMMENT ON COLUMN "public"."tb_userinfo_2nf"."id" IS 'ID';COMMENT ON COLUMN "public"."tb_userinfo_2nf"."loginname" IS '用户登录名称';COMMENT ON COLUMN "public"."tb_userinfo_2nf"."username" IS '用户名称';COMMENT ON COLUMN "public"."tb_userinfo_2nf"."age" IS '年龄';COMMENT ON COLUMN "public"."tb_userinfo_2nf"."xzqdm" IS '县级行政区代码';COMMENT ON COLUMN "public"."tb_userinfo_2nf"."details_address" IS '详细地址';
CREATE TABLE "public"."tb_xzqinfo" ("id" int4 NOT NULL,"pid" int4,"xzqdm" varchar(10),"xzqmc" varchar(50),PRIMARY KEY ("id")
)
;INSERT INTO "public"."tb_xzqinfo"("id", "pid", "xzqdm", "xzqmc") VALUES (1, NULL, '11', '北京市');
INSERT INTO "public"."tb_xzqinfo"("id", "pid", "xzqdm", "xzqmc") VALUES (2, 1, '1101', '北京市区');
INSERT INTO "public"."tb_xzqinfo"("id", "pid", "xzqdm", "xzqmc") VALUES (3, 2, '110101', '东城区');
INSERT INTO "public"."tb_xzqinfo"("id", "pid", "xzqdm", "xzqmc") VALUES (4, 2, '110107', '石景山区');
3.4.第三范式
如果在这个时候我们有很多的详细地址都在鲁谷街道
。则就需要我们再次修改改进
CREATE TABLE "public"."tb_userinfo_3nf" ("id" int4 NOT NULL,"loginname" varchar(10),"username" varchar(10),"age" int4,"address_id" int4,PRIMARY KEY ("id")
)
;COMMENT ON COLUMN "public"."tb_userinfo_3nf"."id" IS 'ID';COMMENT ON COLUMN "public"."tb_userinfo_3nf"."loginname" IS '用户登录名称';COMMENT ON COLUMN "public"."tb_userinfo_3nf"."username" IS '用户名称';COMMENT ON COLUMN "public"."tb_userinfo_3nf"."age" IS '年龄';COMMENT ON COLUMN "public"."tb_userinfo_3nf"."address_id" IS '详细地址ID';INSERT INTO "public"."tb_userinfo_3nf"("id", "loginname", "username", "age", "address_id") VALUES (1, 'xiaocai', '小菜', 18, 1);
CREATE TABLE "public"."tb_address_info" ("id" int4 NOT NULL,"xzqdm" varchar(10),"details_address" varchar(50),PRIMARY KEY ("id")
)
;INSERT INTO "public"."tb_address_info"("id", "xzqdm", "details_address") VALUES (1, '110107', '鲁谷街道');
如此便形成如下结构
3.5.BC范式
让我们通过一个具体的例子来说明如何从第三范式(3NF)优化到博伊斯-科得范式(BCNF)。这个过程主要涉及识别并解决非候选键决定候选键的情况,从而确保数据库结构中的每个决定因素都是候选键。
假设有一个学校的课程安排表CourseSchedule
,包含以下字段:
RoomID
(教室ID)CourseID
(课程ID)TimeSlot
(上课时间)InstructorID
(授课教师ID)
这个表设计满足3NF:每个非主属性都直接依赖于主键,并且不存在非主属性依赖于其他非主属性的情况。但我们假设在这个学校中,一个教师在同一个时间段只能教授一个课程,而且这个课程只能在一个教室进行。这意味着InstructorID
和TimeSlot
联合起来可以唯一确定RoomID
和CourseID
。
这里,虽然InstructorID
和TimeSlot
不是整个表的主键,但它们作为一个组合却能决定其他字段,这违反了BCNF的原则,因为存在一个非候选键的组合决定了候选键。
3.5.1.解决步骤
为了将这个表结构优化到BCNF,我们可以将表分解为两个表:
-
课程安排表(
CourseSchedule
):CourseID
(课程ID,主键)RoomID
(教室ID)TimeSlot
(上课时间)
-
教师授课时间表(
InstructorTeachingSchedule
):InstructorID
(授课教师ID,主键的一部分)TimeSlot
(上课时间,主键的一部分)CourseID
(课程ID)
在这种分解后的设计中,CourseSchedule
表中的RoomID
完全依赖于CourseID
和TimeSlot
,而InstructorTeachingSchedule
表确保了InstructorID
和TimeSlot
的组合唯一确定了CourseID
,满足BCNF的要求。这样,每个表都确保了它的所有决定因素都是候选键,解决了原设计中的问题。
3.6.反规范化
上面的规范化都是建立在数据数据统一维护的思想上,这样在运维时本质上只需要修改一处就可以达到应对需求的变动,但是数据想要获取更加完全的信息则需要频繁的表关联才可以,如第三范式中,我们想要知道某个人的地址,并且需要显示其省名称、市名称则需要编写如下sql。
select tb_userinfo_3nf.*,tb_xzqinfo.xzqdm,tb_xzqinfo.xzqmc,tb_address_info.details_address from tb_userinfo_3nf
left join tb_address_info on tb_userinfo_3nf.address_id=tb_address_info.id
left join tb_xzqinfo on tb_xzqinfo.xzqdm=tb_address_info.xzqdm
在这个例子中,如果我们的数据体谅增加,更多的连接操作,必然影响查询速度,所以为了提高某些查询,我们会做一些破坏规范的行为,我们称之为(反规范化处理)。
3.6.1.增加冗余列
对于上述的案例中,我们在日常业务场景中,行政区信息的变化是非常罕见的,但是我们在查询时是需要关联的,所以我们可以将行政区信息中一些不会频繁(比如半年、一年以上才有可能变化,甚至永远不变)的信息添加到表中。如这个案例中我们将行政区名称写入到表中,形成如下表:
CREATE TABLE "public"."tb_address_info_fnf" ("id" int4 NOT NULL,"xzqdm" varchar(10),"xzqmc" varchar(10),"details_address" varchar(50),PRIMARY KEY ("id")
)
;INSERT INTO "public"."tb_address_info_fnf"("id", "xzqdm", "xzqmc", "details_address") VALUES (1, '110107', '石景山区', '鲁谷街道');
如此我们的查询便可以优化为如下查询:
select tb_userinfo_3nf.*,tb_address_info_fnf.xzqdm,tb_address_info_fnf.xzqmc,tb_address_info_fnf.details_address from tb_userinfo_3nf
left join tb_address_info_fnf on tb_userinfo_3nf.address_id=tb_address_info_fnf.id
3.6.2.重新组表或物化视图
在增加冗余列中我们看到了如果我们需要查询县级行政区,可以增加冗余字段,如果我们现在需要查询市级、省级呢?
我们可以将前面的树表行政区,重新构建为一张详情表,从叶子节点开始组织。
create materialized view mvw_xzq_hierarchy
as
WITH tb_xzqinfo_county AS (SELECT txc.id,txc.xzqmc,txc.xzqdm,txc.pidFROM tb_xzqinfo txcwhere txc.id not in (select pid from tb_xzqinfo tx where tx.id!=txc.id AND tx.pid is not null))
select
tb_xzqinfo_county.xzqdm as county_code,tb_xzqinfo_county.xzqmc as county_name,
tx_city.xzqdm as city_code,tx_city.xzqmc as city_name,
tx_p.xzqdm as province_code,tx_p.xzqmc as province_namefrom tb_xzqinfo_county
left join tb_xzqinfo tx_city on tx_city.id=tb_xzqinfo_county.pid
left join tb_xzqinfo tx_p on tx_p.id=tx_city.pid
3.6.3.辅助字段,减少复杂度
在上面重新组表的代码中我们发现以下sql的可读性、运行效率都好
WITH tb_xzqinfo_county AS (SELECT txc.id,txc.xzqmc,txc.xzqdm,txc.pidFROM tb_xzqinfo txcwhere txc.id not in (select pid from tb_xzqinfo tx where tx.id!=txc.id AND tx.pid is not null))
这个里面是通过id信息下是否存在子节点便判定其为叶子节点,如果我们在数据库表上增加一个字段,其便可以变为:
create materialized view mvw_xzq_hierarchy_fzzd
as
WITH tb_xzqinfo_county AS (SELECT txc.id,txc.xzqmc,txc.xzqdm,txc.pidFROM tb_xzqinfo txcwhere txc.xzq_type='county')
select
tb_xzqinfo_county.xzqdm as county_code,tb_xzqinfo_county.xzqmc as county_name,
tx_city.xzqdm as city_code,tx_city.xzqmc as city_name,
tx_p.xzqdm as province_code,tx_p.xzqmc as province_namefrom tb_xzqinfo_county
left join tb_xzqinfo tx_city on tx_city.id=tb_xzqinfo_county.pid
left join tb_xzqinfo tx_p on tx_p.id=tx_city.pid
相关文章:

数据库规范化设计案例解析
1.介绍 数据库规范化设计是数据库设计的一种重要方法,旨在减少数据库中的冗余数据,提高数据的一致性,确保数据依赖合理,从而提高数据库的结构清晰度和维护效率。规范化设计通过应用一系列的规范化规则(或称“范式”&a…...

服务器段的连接端口和监听端口编程实现
new ServerSocket(int)是开启监听端口,并不是连接端口。真正的连接端口是随机开辟的空闲端口,当连接创建完成后,监听关口可以继续等待下一次连接请求,处于空闲等待状态。 编程实现方式 1 、主线程一直处于阻塞等待状态,…...
用“定时执行专家”武装你的电脑,做时间管理大师!
简介 你是否厌倦了重复繁琐的电脑操作?你是否希望能够解放双手,提高工作效率?“定时执行专家”是一款功能强大的定时任务执行软件,可以帮你轻松实现自动化办公,让你成为时间管理大师! 软件功能 支持25种任…...

css3实现3D立方体旋转特效源码
源码介绍 CSS3自动旋转正方体3D特效是一款基于css3 keyframes属性制作的图片相册自动旋转立方体特效 效果展示 下载地址 css3实现3D立方体旋转特效代码...
计算器系统基础知识-校验码
1.奇偶校验码 通过在编码中增加一位奇数校验位来使编码中1的个数为奇数(奇校验)或者为偶数(偶校验),从而使码距变为2。 常见的奇偶校验码有三种:水平奇偶校验码、垂直奇偶校验码和水平垂直校验码。 以下是奇偶校验码的示例: public …...

springboot换日志框架后爆SLF4J: Class path contains multiple SLF4J bindings的解决办法
sringboot原本使用的是logback日志框架,将它去掉,修改为log4j2日志框架后,往往会出现以下错误: SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/C:/Users/admin/.m2/repository/ch/qos…...

k8s+zabbix
一,环境: 1),k8s部署,master和node节点都部署成功 二,部署: 1),安装python3(资源中有) wget https://www.python.org/ftp/python/3.7.4/Python-…...

k8s-生产级的k8s高可用(2) 25
部署containerd k8s2、k8s3、k8s4在配置前需要重置节点(reset)在上一章已完成 禁用所有节点docker和cri-docker服务 所有节点清除iptables规则 重置后全部节点重启 由于之前部署过docker,因此containerd默认已安装 修改配置 启动containe…...
ubuntu20.04 创建ros环境、创建rospackage
roswiki教程:https://wiki.ros.org/cn/ROS/Tutorials 环境准备 安装ros环境 这里选择noetic版本的ros,安装步骤参考:https://zhuanlan.zhihu.com/p/662284005 创建工作空间 这里我在用户目录下创建catkin的工作目录catkin_ws ࿰…...
QT进阶---------pro项目文件中的常用命令 (第三天)
1、命令一 决定exe可执行程序的生成路径CONFIG 作用:不使用默认路径,方便移植 CONFIG(debug, debug|release) {DESTDIR $$_PRO_FILE_PWD_/../../../debugXXXsystem } else {DESTDIR $$_PRO_FILE_PWD_/../../../realeaseXXXsystem } 是用于 Qt 项目…...
php常用设计模式应用场景及示例
单例模式 含义描述 应用程序中最多只有该类的一个实例存在 应用场景 常应用于数据库类设计,采用单例模式,只连接一次数据库,防止打开多个数据库连接。 代码示例 class Singleton {private static $instance; // 定义一个私有的静态变量保存…...

浏览器与服务器通信过程(HTTP协议)
目录 1 概念 2 常见的 web 服务器有 3 浏览器与服务器通信过程 3.1 DNS 3.2 URL 4 HTTP请求方法和应答状态码 4.1 HTTP请求报文段实例 4.2 HTTP请求方法 5 HTTP应答报头和应答状态 5.1 HTTP的应答报头结构 5.2 HTTP的应答状态 1 概念 浏览器与 web 服务器在应用层通…...

Pytorch搭建AlexNet 预测实现
1.导包 import torch import matplotlib.pyplot as plt import json from model import AlexNet from PIL import Image from torchvision import transforms 2.数据预处理 data_transform transforms.Compose([transforms.Resize((224, 224)), # 将图片重新裁剪transform…...
笔记:使用parfile进行的数据导入导出
expdp ‘username/password’ parfileE:\dmp_tmp\par.txt DIRECTORYdmptmp LOGFILESYS_SEND_LOG.log DUMPFILESYS_SEND_LOG.dmp tablesSYS_SEND_LOG_BAK query“where send_dt>TO_DATE(‘2024-03-13’,‘yyyy-mm-dd’)” impdp ‘username/password’ directorydmptmp dum…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的行人跌倒检测系统(深度学习+UI界面+完整训练数据集)
摘要:开发行人跌倒检测系统在确保老年人安全方面扮演着至关重要的角色。本篇文章详尽地阐述了如何利用深度学习技术构建一个行人跌倒检测系统,并附上了完整的代码实现。该系统采用了先进的YOLOv8算法,并对YOLOv7、YOLOv6、YOLOv5等先前版本进…...

Ubuntu 14.04:PaddleOCR基于PaddleServing的在线服务化部署(失败)
一、 二、安装 注: 安装 PaddleOCR 2.3 。 因为 PaddleOCR 2.4 的 推荐环境 PaddlePaddle > 2.1.2。 https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.4/doc/doc_ch/environment.md 安装前的环境准备 在使用Paddle Serving之前,需要完…...

Java JUC 笔记(2)
Java JUC 笔记(2) 锁框架 JDK5以后增加了Lock接口用来实现锁功能,其提供了与synchronized类似的同步功能,但是在使用时手动的获取和释放锁 Lock和Condition锁 这里的锁与synchronized锁不太一样,我们可以认为是Loc…...
webpack5高级--02_提升打包构建速度
提升打包构建速度 一、HotModuleReplacement 为什么 开发时我们修改了其中一个模块代码,Webpack 默认会将所有模块全部重新打包编译,速度很慢。 所以我们需要做到修改某个模块代码,就只有这个模块代码需要重新打包编译,其他模…...

MAC M芯片 Anaconda安装
Anaconda安装 1.M芯片下载AnaConda 1.M芯片下载AnaConda https://www.anaconda.com/download 安装完成 conda的版本是24.1.2...
【JS】自动下拉网页刷新,当出现指定关键字,就打印出来
批量检查域名是否可以注册 1、有的网站数据是通过下拉发生请求,间隔x毫秒自动下拉 2、查找某个关键字,找到就打印出来 3、打印数据自动去重 4、当连续n次下拉,没有新div元素出来,就停止该循环 var map {}; var count 0; var l…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...