Db层治理:SQL精细化及并发更新数据丢失问题解决最佳实践 | 得物技术

字节客增慢 SQL 治理体系 动手点关注干货不迷路????项目概览背景慢 SQL 即执行时间超过 long_query_time 设定阈值的SQL语句,可通过 select @@long_query_time 查看数据库具体的慢查询阈值。另外慢 SQL 不仅仅包括 select 语句,也包括 delete,insert 等 DML 语句。慢查询 SQL 的危害包括:性能: 慢 SQL 的执行时间过长... 阅读详情

1.背景

1.1 概述

1.1.1 SQL精细化提出背景

目前使用比较广泛的数据库持久层框架有两个,JPA和Mybatis,先来简单比较一下这两种框架。

从选择上来看,和业务场景是有关系的,迭代比较频繁、复杂性较高,配合MYSQL数据库,我们的数据库持久层选用的是Mybatis,Mybatis的一个很重要的特性就是开发可以自己写SQL,或者借助自动生成工具生成SQL,在实际的开发工作中,没有统一的规范,我们习惯于SQL Mapper文件中的通用的或者万能的查询、更新、插入等方法上叠加自己的增删改查操作,随着业务的场景增多,SQL的复杂性也会随着上升,那么在开发完成开发之后,一个可以review的SQL是我们迫切需要的,大家在CR代码的时候,可以很快的发现SQL中可能存在的一些问题,比如慢SQL、是否走到索引、走了哪个索引等。SQL质量的好坏将会影响整体应用的性能以及整体链路的压力,所以对于SQL的精细化管理是很有必要的一项工作。

1.1.2 并发更新导致数据丢失问题

我们的数据库表结构设计的时候,往往会预留一个feature字段,很多的业务增值信息都会存放到这个字段,以一个大json存储,如果我们在各种场景对同一条记录的这个字段更新,如果没有做到并发控制,那么则会导致数据被覆盖,形成脏数据。

针对1.1.1和1.1.2两个问题,结合我们的业务,针对db层的治理,尝试给出一些建议。

1.2 SQL精细化管理的收益

SQL精细化管理作为解决慢SQL的一个重要组成部分,可以带来如下收益:

(1)如果Mybatis的SQL Mapper无法有效的进行review,那么其中存在的风险,我们第一时间是无法直观感知的,我们需要可review的SQL,将风险提前暴露

(2)解决慢SQL问题,提高查询效率,提升用户体验及提高系统吞吐

(3)避免潜在OOM风险,导致应用崩溃

(4)避免慢SQL问题(慢SQL消耗的资源往往比正常SQL要高几倍、几十倍、几百倍)导致MYSQL崩溃,拖垮整个数据库,降低CPU使用率

(5)解决代码及SQL缺陷问题,可以提升我们订单服务的稳定性

1.3  并发更新导致数据丢失问题现象产生的原因

例如有如下SQL更新feature字段:

<update id="update"
        parameterType="OrderEntity">
    update table_order
    set feature = #{feature,jdbcType=VARCHAR}
    where order_no = #{orderNo,jdbcType=VARCHAR}
</update>

当存在两个线程同时更新,则会出现以下情况:

我们最终的期望结果是:

JSON:

a=1;b=1;c=1;

那么随着Thread-1和Thread-2的先后顺序不同,我们得到的结果有可能会是:

a=1;b=1;

或:

a=1;c=1;

所以就出现了脏数据,并不是我们最终想要的。

2.SQL精细化最佳实践

2.1 不要使用工具自动生成的通用SQL

这种SQL是自动生成的,SQL条件也是拼接的,需要在程序中去拼接查询条件或者更新值,我们也看不出执行的SQL到底是什么样的,不能直观看到具体的查询SQL是什么,需要在代码中一层层往上找,找到赋值的地方,如:

<select id="selectByExample" parameterType="OrderExample" resultMap="BaseResultMap">
  select
  <if test="distinct">
    distinct
  </if>
  <include refid="Base_Column_List" />
  from table_order
  <if test="_parameter != null">
    <include refid="Example_Where_Clause" />
  </if>
  <if test="orderByClause != null">
    order by ${orderByClause}
  </if>
</select>

2.2 必须清晰看到索引情况

为了避免我们的SQL执行全表扫描(对于InnoDB来说就是直接扫描全部的聚簇索引记录),我们需要让我们的SQL走到我们设定的索引上,减少执行查询时遍历的数据行数,提升查询性能。SQL map里面要能一眼看出这条SQL是否走了索引,具体走了哪些索引。比如下面的SQL,就不能明确看出走了哪个索引。

<select id="selectOrderList"
            parameterType="OrderEntity"
            resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List_2_Report"/>
        from table_order ro
        <where>
            <if test="orderNo != null">
                and ro.order_no = #{orderNo}
            </if>
            <if test="subOrderNo != null">
                and ro.sub_order_no = #{subOrderNo}
            </if>
            <if test="refundOrderNo != null">
                and ro.refund_order_no = #{refund_order_no}
            </if>
            <if test="startTime != null and endTime != null">
                and ro.create_time between #{startTime} and #{endTime}
            </if>
        </where>
        order by ro.create_time asc
        LIMIT #{offSet},#{limit}
    </select>

2.3 非必需不要使用动态SQL

因为Mybatis提供的动态SQL功能,可以很便捷的拼装SQL,但也有弊端:

(1)同时也会将查询数据库的参数交易后置到Mapper中,如果出现遗漏,或者校验不正确,使用动态SQL极有可能存在内存溢出隐患,导致OOM

(2)代码可读性差。

要求:在新增的代码不要出现动态SQL,索引字段不要动态,需要明确,例如下面一种场景就是索引不明确,refund_no、sub_order_no、order_no三个字段都可能走索引:

<select id="getDetail"  parameterType="OrderEntity" resultMap="BaseResultMap">
  select <include refid="Base_Column_List" />
  from table_order
  <where>
    <if test="refund_No != null and refundNo != ''">
      and refund_No =#{refundNo}
    </if>
    <if test="subOrderNo != null and subOrderNo != ''">
      and sub_order_no =#{subOrderNo}
    </if>
    <if test="orderNo != null and orderNo != ''">
      and order_no =#{orderNo}
    </if>
  </where>
</select>

(3)因为订单都是比较重数据的需要提供一些查询类的接口给到外部,比如客服、商家后台等,这类偏向于B端的查询,很多时候查询条件是很多的,也是可选的,为了支持这些查询接口,我们需要明确哪些是必传字段,必传字段在dao层就需要强制校验,mapper层不再做校验。例如我们针对商家接口查询,一般要求卖家id、时间范围都是必须传值的。

2.4 update操作,需要明确更新字段,

不要传po对象作为参数,

在SQL mapper中进行if判断

更新字段要明确,不要在mapper中做if判断,正例:

<update id="update"
        parameterType="OrderEntity">
    update table_order
    set feature = #{feature,jdbcType=VARCHAR}
    where order_no = #{orderNo,jdbcType=VARCHAR}
</update>

反例:

<update id="update"
        parameterType="OrderEntity">
    update table_order
    <set>
        <if test="orderNo != null">
            order_no = #{orderNo,jdbcType=VARCHAR},
        </if>
        <if test="subOrderNo != null">
            sub_order_no = #{subOrderNo,jdbcType=VARCHAR},
        </if>
        <if test="bizType != null">
            biz_type = #{bizType,jdbcType=VARCHAR},
        </if>
        <if test="refundType != null">
            refund_type = #{refundType,jdbcType=TINYINT},
        </if>
        <if test="orderStatus != null">
            order_status = #{orderStatus,jdbcType=INTEGER},
        </if>
    </set>
    where order_no = #{orderNo,jdbcType=VARCHAR}
</update>

2.5 order by排序问题

需要注意两点:

① 如果业务对记录结果是否排序无要求,尽量不要用order by排序,排序比较耗时。

② 因为innodb的索引结构是B+树,索引中的数据是按照一定顺序进行排列的,在排序查询过程中,需要利用索引,避免额外的排序,即order by字段需要走到索引。

2.5.1 order by join查询

在join查询中,oder by排序,查看执行计划,避免Extra 字段有“Using filesort”出现,“Using filesort”表示的就是需要文件排序,如果排序数据量太大,内存放不下,则不得不利用磁盘临时文件辅助排序。要尽量避免这种Using Sort出现。

2.5.2 order by 多个条件排序查询

当odrer by多个字段的时候,容易导致使用文件排序,不要轻易的写order by 多个字段这样的SQL,去掉不需要的order by字段,只保留一个必须的。

2.6 limit的使用

当我们的查询SQL,没有走到唯一索引或者主键索引,或者传入空参数,那么返回极有可能是多条数据,甚至几十万,几百万条数据,这时候,我们需要加limit限制,一定要有兜底,避免发生大批量的数据查询,全表扫描情况出现,造成查询超时,或者查询返回大量数据,使应用内存急剧上升,导致oom。如果条件中带有主键查询的,直接使用limit 1 。

2.7 不允许select *全部字段

我们尽量查询我们需要输出的字段或者需要用到字段,不要查询没必要输出的字段,需要查询的字段可以单独的列出来,一律不允许用select *查询。

HTML:

<SQL id="Base_Column_List">
  order_no, sub_order_no, user_id, biz_type, pay_tool, pay_status, out_pay_no
</SQL>

有三个方面原因:

① 一个是查询只需要的字段如果是索引,那么可以直接使用index里面的数据就可以返回,不用做回表查询

② 数据量大的场景会影响网络io传输性能

③ 可能会造成大对象

2.8 join查询

① 能不能join查询,尽量不要要join查询

② 必须用join查询的,在做join查询的时候,要注意驱动表的选择,一般我们选用小表作为驱动表,被驱动表可以走索引。

2.9 范围查询

对于需要提供一段时间范围查询的接口,我们需要对这个时间范围进行限制,不能过大,如果超出范围,要提前抛异常,一定要进行强制校验,比如针对时间范围的数据查询,一般根据数据量,确定一个查询时间范围,范围太大,会造成慢SQL。

2.10 联合索引问题

对于使用到联合索引查询SQL的时候,我们需要注意联合索引的顺序,一般情况下,SQL执行的时候,会根据在前面顺序在前面的先进行过滤,我们的期望是顺序越在前面的索引可以过滤掉越多的数据,这样层层推进,各列应按按量排序。

我们希望排在前面的字段可以过滤掉绝大部分数据。联合索引选择性高的索引排在前面,减少扫描行数。

2.11 in查询

in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控制在 1000 个之内。一定要加强制校验。如下面的查询条件中的subOrderNoList需要在外层做大小校验。特别是在分库分表场景下,为了提升查询效率,很有必要对in查询条件数量做限制,因为分库分表场景下,数据是散落在不同,需要去对应数据库中读取数据再做聚合返回,效率比较低。

HTML:


<select id="queryDetail" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from table_order
    where order_no in
    <foreach collection="orderNoList" open="(" close=")" separator="," item="orderNo" index="i">
        #{orderNo}
    </foreach>
    order by create_time desc
    limit 20
</select>

2.12 update操作之前做select查询

在做update操作之前尽量先查询以下,避免不必要的数据库交互操作。

2.13 分页查询大小限制

分页查询pagesize大小要加强制校验,超过限定值,直接异常返回。

2.14 超大分页场景

MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回 N 行,那当 offset 特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行控制,offset和pageSize需要做限制

select * from table_order LIMIT #{offset}, #{pageSize};

2.15 批量插入

对于批量插入数据操作,我们希望可以一次执行,避免多次重复数据库交互操作。

反例:

Java:


public void batchSave(List<TableOrder> orderEntityList) {
    if (CollectionUtil.isEmpty(orderEntityList)) {
        return;
    }
    for (OrderEntity orderEntity : orderEntityList) {
        save(orderEntity);
    }
}

正例:

SQL:

INSERT into table_order(cloum1,cloum2,....cloumx) values('?','?',....'?'),('?','?',....'?'),('?','?',....'?');

2.16 like 语句的优化

%%这种匹配方式完全无法使用索引,从而进行全表扫描导致效率极低,需要通过走到索引查找数据

2.17 不要在程序中拼接查询条件

Java:

public Criteria andBizTypeIn(List<String> values) {
    addCriterion("biz_type in", values, "bizType");
    return (Criteria) this;
}

2.18 select count问题

统计查询一律使用select count(*),按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*)

2.19  删除mapper中不需要的操作

例如一些delete物理删除这些操作方法可以清理掉。这些方法都是通过自动生成工具生成的,因为正常情况下,我们一般不会对数据库数据做物理删除。

2.20  影响行数结果判断

对于任何update更新操作,都需要判断返回值,即影响行数。在进行update操作的时候,正常情况下,数据库返回影响行数,如果数据库中没有需要进行update的数据,也是不报错的,这就需要我们在应用层自己进行判断,如果更新行数是0,或者多于1条,我们的业务处理逻辑该怎么走。

Java:


int effect = repository.update(param1,param2)
if (effect < 1){
    throw new Exception("update操作执行失败");
}

2.21 list.get(0)

对于任何list.get(0),都需要是排序之后的结果。例如我们在dao层查询的时候,是用list查询,返回列表,也没有进行排序,在controller层直接get(0),很容易取错数据。

2.22 list返回

对于任何查询,只要是where条件中没有主键或唯一健,都需要用list返回,不能简单的根据场景来认为数据库中只可能有一条记录,容易引起Too Many results error。存在一些场景,比如,创建退货,然后取消退货,再创建退货,再取消退货,根据订单号来查询可以查询多条记录,但我们只需要最新的一条,没有做limit限制,就会异常。

3.并发更新覆盖数据解决最佳实践

一般解决这种并发导致数据的方法有悲观锁和乐观锁两种机制。

3.1 悲观锁

使用悲观锁的原理就是,当我们在查询出feature信息之后,就会把当前行数据进行锁定,然后去修改feature字段,直到我们修改数据提交完毕之后,其他事物才可以进行修改,前提是我们需要将执行的SQL放在同一个事物中,否则达不到锁定行数据的目的。

start transaction
select feature from table_order where order_no = '100' for update;
update table_order set feature = new_feature where order_no = '100';
commit

select...for update是MySQL提供的实现悲观锁的方式。此时在refund_order表中,refund_no为100的那条数据就被我们锁定了,其它的要执行 的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。

select feature from table_order where order_no = '100' for update;

悲观锁虽然可以强保证数据不会被覆盖,但也存在一些问题,比如:

(1)事物粒度控制不好的情况下,容易产生死锁

(2)InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。如果SQL未走到索引,将会带来灾难性事件。

(3)悲观锁依赖数据库,效率较低,但更新失败的概率也较低,一般在金融、支付行业中使用相对较多。在目前行业内的高并发架构中,倾向于fail-fast模式,悲观锁相对使用较少。

3.2 乐观锁

乐观锁相对于悲观锁而言,认为数据在一般情况下不会造成冲突,在数据进行提交更新的时候,才会正式对数据的冲突进行检测,如果冲突,则失败返回。

3.2.1 全局version乐观锁

乐观锁一般常用的实现机制是利用版本号(version)来实现。一般通过为数据库表增加一个数字类型的 “version” 字段,当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值+1。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据,返回更新失败。

执行过程如下:

SQL:


select (feature,version) from table_order where refund_no='100';
update table_order set feature=new_feature,version=version+1 where table_order ='100' and version= version;

我们可以看到若采用版本号version作为乐观锁,则每次只有一个事务能更新成功,业务感知上就是大量操作失败。

3.2.2 feature_version版本字段

因为version字段是全局的,利用全局字段version进行处理,则会发现refund_order表的其他字段变更也会失败。那么如何解决这个问题?业内的做法是从锁的粒度上进行优化,比如针对feature字段专门新增一个feature_version字段,表示feature的版本号,很好的避免了version对所有字段变更的冲突。执行SQL如下:

update    
    table_order
set    
    features=#features#,    
    features_version= features_version +1,
    version = version +1
where    
    order_no=#order_no#    
    and features_version =#ori_features_version#

通过3.2.1和3.2.2对比,我们可以清晰的发现,3.2.2中方案是较优的,在我们的实际业务中也是采取这一方式进行了改造。

4.总结与展望

前面已经谈到,对于订单系统的核心来说就是数据,那么对于我们应用来说,就是对这些数据进行增删改查操作,对Db层进行梳理和改造,对我们业务数据的正确性以及应用性能提升是有很大帮助的,然而,Db层的治理工作,对于一个应用来说,有牵一发而动全身的影响,针对这方面的改造需要关注以下几个点:

(1) 测试需要充分,测试的场景需要梳理全面,可以从Mapper层反推涉及的场景接口,因为涉及Mapper层的改动,是没办法进行对比的。

(2)在没有全流量对比工具的前提下,需要做好灰度切流工作,在灰度粒度上,可以选择按接口维度,或者按机器维度,也可以开始按接口维度,等所有场景覆盖全之后,再按照机器灰度。如果订单在夜间、白天处理逻辑不一样,我们灰度需要考虑到隔夜观察,也可以利用一些辅助工具例如对账等。

(3)Db层治理工作一直在路上,完成全面梳理改造只是迈出的第一步,一个好的规范如何进行推进下去,让大家保持统一的规范,随着时间的推移,这种规范能够继续保持不走样,是我们需要思考的问题。

慢SQL治理方法论 本文介绍了慢SQL治理的方法论1. 发现:如何发现慢SQL2. 定位:如何定位到慢SQL出现在什么地方3. 分析:遇到慢SQL时的分析思路4. 解决:慢SQL的解决思路SQL优化本身是一个比较复杂的问题,上面所列举的,只是部份优化的案例,但所有优化的思路都是尽可能的减少SQL在执行中过程中扫描数据块的次数。 阅读详情

相关推荐

慢SQL治理

监控收集(慢日志、sys库) ->定位目标(耗时TOP SQL、全表扫描SQL)->深入分析EXPLAIN解读,找出type=ALL等问题) ->根因判断(索引缺失、设计不当、SQL写法问题) ->实施优化(增/改索引、改写SQL) ->验证监控(再次EXPLAIN,观察慢日志)。一切以执行计划为准,结合业务逻辑和数据特征进行决策,避免盲目添加索引。

猪猪 1008

oracle sqla工具,Oracle SQL自动化审核工具的实现

作者介绍梁铭图,新炬网络首席架构师,十多年数据库运维、数据库设计、数据治理以及系统规划建设经验,拥有Oracle OCM、Togaf企业架构师(鉴定级)、IBM CATE等认证,曾获dbaplus年度MVP以及华为云MVP等荣誉,并参与数据资产管理国家标准的编写工作。在数据库运维管理和架构设计、运维体系规划、数据资产管理方面有深入研究。一、背景我们客户现场的Oracle运维团队需要对开发团队提交上...

weixin_31182871的博客 1223

数据分析、数据治理面试总结

数据分析、数据治理、sqlboy面试指南

ASD50920的博客 3669

数据库治理的探索与实践

本文是 MSE 即将推出的一个数据库治理能力的预告,我们从应用的视角出发整理抽象了我们在访问、使用数据库时场景的一些稳定性治理、性能优化、提效等方面的实战经验,对于每一个后端应用来说,数据库无疑是重中之重,我们希望通过我们的数据库治理能力,可以帮助到大家更好地使用数据库服务。

数据库技术 380

BigQuery数据仓库实战:分层建模、成本治理与权限管控全链路

数据仓库是现代企业数据分析的核心基础设施,其本质是面向主题、集成性、非易失且随时间变化的决策支持系统。BigQuery作为Google Cloud原生的无服务器数据仓库,依托Dremel列式执行引擎与Colossus存储架构,实现了计算与存储分离、按扫描字节计费、自动分层冷热数据管理等关键能力。相比传统MPP数据库,它无需运维节点、不依赖索引优化,而将性能与治理重心转向SQL写法、表分区聚簇设计、分层建模规范及IAM细粒度权限控制。本文围绕ODS/DWD/DWS/ADS四层建模体系,结合真实金融与SaaS场

leonard61306500的专栏 390

SQL注释实战指南:从语法规范到元数据治理

SQL注释是数据库开发中基础却常被低估的关键实践,它虽不参与执行,却深刻影响代码可读性、团队协作效率与线上稳定性。其底层原理涉及词法解析阶段的标记剥离,不同数据库(MySQL/PostgreSQL/Snowflake/Databricks)在注释语法、嵌套支持、字符串内行为及存储过程兼容性上存在显著差异,直接关系到跨环境迁移与动态SQL安全。在工程实践中,注释已超越简单说明,演进为结构化元数据载体——通过SQL-Doc规范可自动生成API文档、驱动数据血缘分析,并与Git版本、CI/CD流水线、DataHu

weixin_33829657的博客 330

慢SQL的治理经验

在当今的数字化时代,数据库已经成为企业不可或缺的核心组件。然而,随着数据量的不断增加和查询的复杂性提高,慢查询成为了数据库性能的瓶颈之一。慢SQL不仅会影响系统的响应速度,还可能导致数据丢失或损坏,给企业带来巨大的损失。因此,慢SQL的治理成为了数据库管理的重要任务之一。本文将分享一些慢SQL的治理经验,包括如何识别、分析和优化慢查询。通过了解慢查询的原因和解决方法,我们可以提高数据库的性能和稳定性,为企业的业务发展提供更好的支持。

船到桥头自然直 1896

【面试系列】数据工程师高频面试题及详细解答

本文针对数据工程师岗位,提供了详尽的面试题库和解答,分为初级、中级和高级三个层次。初级面试题主要涉及基本的数据处理和ETL工具的使用,如SQL查询、数据清洗和基本的数据建模。中级面试题重点考察数据管道设计、数据库优化和大数据平台的应用。高级面试题则深入探讨高级数据处理技术、分布式系统架构和数据湖的实现。通过这些问题和解答,候选人可以全面了解数据工程师岗位所需的技能,帮助其更好地准备面试。常考知识点总结部分则系统归纳了数据工程师岗位的关键技能领域。

在路上的专栏 2375

数据仓库和数据库的区别

数据仓库(Data Warehouse)是一种专门设计用于报告和分析的数据库系统,它允许将来自一个或多个数据源的数据集成、存储和分析。数据仓库的主要目的是支持决策制定,通过提供快速访问历史数据和进行复杂查询的能力。以下是数据仓库的一些关键特性和概念:1. 主题导向:数据仓库围绕特定的业务主题构建,如销售、客户或财务,而不是围绕应用程序的功能。2. 集成性:数据仓库集成了来自不同源系统的数据,这些数据可能包括事务系统、应用程序和其他企业数据源。

pxyxyxy的博客 1280

RK3588上rknn_toolkit_lite2报错解决:手把手教你更新librknnrt.so的正确姿势

本文针对在RK3588平台上使用rknn_toolkit_lite2时遇到的“Invalid RKNN model version”等常见错误,提供了完整的诊断与解决方案。文章深入剖析了RKNN生态系统各组件(如librknnrt.so、RKNN Server)版本不兼容的根源,并手把手指导如何安全、正确地更新librknnrt.so运行时库,确保AI模型在RK3588 NPU上实现高效推理。

weixin_29189003的博客 520

Python-OpenCV及cv2,numpy库最新安装教程[最全步骤]

安装教程目录前言OpenCV-Python安装教程报错解决cv2安装numpy安装opencv安装(附加)总结 前言 首先,我知道一些看到我的Blog的人已经在网上找了很多歪路子,现在已经火冒三丈了(我也是这样过来的hhhh),那么现在,深呼吸,跟着我的教程,不要着急,每一步都要读一遍。完整安装过程需要1个小时左右(仅供参考,本人第一次安装python花了一天(确信)) OpenCV-Python...

qq_45425286的博客 7431

数据库计算机三级等级考试--数据库技术相关知识点和笔记

计算机三级等级考试笔记,是博主通过计算机三级数据库技术考试的相关笔记,此篇博客,不仅适合需要考计算机三级考试的各位考生,也适合在职场处理关于数据库的部分操作,个人认为算是一篇使用性比较强的文档,我个人认为,我目前所在开发岗位,在回顾去看这篇文档,我都会再次有收获,对了,如果你需要计算机三级的刷题软件,可以一键三连,留下评论,然后私聊博主。总结不易,如果有收获可以在下方评论。

好看的皮囊千篇一律,有趣的灵魂万里挑一。 7208

Codex本地部署指南:从环境配置到API集成实战

Codex作为OpenAI推出的代码生成模型,能够根据自然语言描述自动生成代码片段,大幅提升开发效率。这次我们重点分析Codex的本地部署方案、硬件门槛、接口调用方式和实际使用效果,帮助开发者判断是否值得投入时间部署。 从技术架构看,Codex基于GPT-3模型微调,专门针对代码生成任务优化。最新版本支持多种编程语言,包括Python、JavaScript、Java、C++等主流语言。对于国内开发者来说,最关心的是能否在本地环境稳定运行,以及是否需要特殊网络配置。 1. 核心能力速览 能力项 技术说明 模型

weixin_33309048的博客 524

高并发网关调优指南:Chat API 内存缓存、批量更新与 SQLite 锁问题的终极解决方案

Chat API 是一个开源的 OpenAI 接口聚合管理与高并发网关项目,支持将 Gemini、Claude、OpenAI 等多厂商 AI 模型统一接入。当你的网关同时承接成百上千个并发请求时,性能瓶颈往往不是网络,而是数据库。本文带你掌握 Chat API 高并发网关调优的三大核心手段:内存缓存、批量更新与 SQLite 锁规避,帮助新手快速把响应时间压到毫秒级。 [![Chat API 高

gitblog_00340的博客 853

真双口RAM---Quartus与Vivado开发环境区别对比

2、写和写冲突:表示两个端口写使能同时有效且写地址相同,此时需要关断一个写,把两个写端口都需要更新的值处理到一个写端口上面,任何的DP RAM 都不支持写和写冲突。以上述直方图统计使用为例,博主在仿真过程中发现,vivado真双口RAM--B端口读写延迟2个clk;1、读和写冲突:如果读和写同时有效,且读和写是同一个地址时,发生RAM读写冲突,此时会把最新的写数据直接赋给读数据,称为写穿通到读。

weixin_54470733的博客 3582

使用freesurfer和3Dslicer进行脑区分割和电极定点(详细版)

1、安装好matlab和freesurfer2、在目标位置创建文件夹3、开放权限4、将需要计算的nii文件放入文件夹。

zQIANYUN的博客 5629

什么是数据仓库?数据仓库的特点与架构演进

1.为什么需要数据仓库? 在没有数仓之前我们做数据分析到报表展示,依赖的都是从业务数据库中取数据来做分析。业务数据库主要是为业务操作服务,虽然可以用于分析,但需要做很多额外的调整,会存在以下几个问题: ① 表结构关联关系错综复杂 业务数据库通常是根据业务操作需求进行设计的,遵循3NF范式,尽可能减少数据冗余节省存储空间。这就造成表与表之间关系错综复杂。在分析业务状况时,存储业务数据的表与存储待分析的角度表,很可能不会存在直接关联,而是需要通过多表关联来达到需求分析,很明显提高了需求分析的SQL复杂度及

程序猿丶HLK 1616

Codex 100个真实案例 - 用AI做股票K线分析工具(技术指标全自动)

本案例将用 Codex 从零搭建一个完整的股票 K 线分析工具。通过自然语言驱动,我们让 AI 自动完成股票数据获取(akshare)、K 线图绘制(mplfinance + ECharts)、技术指标计算(MA/EMA/MACD/RSI/KDJ/布林带)、买卖信号提示(金叉/死叉、超买超卖)、多股对比分析、Web 可视化界面(Flask + ECharts)、PDF 报告生成以及定时监控邮件推送等全套功能。全程用自然语言指令驱动 Codex,零手写代码实现专业级量化分析平台!

yueyeguzhuo的专栏 870

数据架构实战:数据库、数据仓库与数据湖的核心区别与选型指南

在数据驱动的技术架构中,理解数据处理的核心组件是构建高效系统的关键。从基础概念来看,数据库作为在线事务处理的基石,通过关系模型和ACID特性保障业务数据的强一致性与实时性,其核心价值在于支撑高并发、低延迟的业务操作。随着分析需求的增长,数据仓库应运而生,它通过ETL流程和维度建模,整合多源数据,为复杂的聚合分析与商业智能提供优化环境,其技术价值在于实现性能隔离与历史数据分析。而面对海量非结构化数据,数据湖采用存储与计算分离、读时模式的架构,以低成本容纳原始数据,为机器学习和探索性分析提供灵活空间。在实际应用

weixin_33896726的博客 378

飞牛fnNAS同步微信微信聊天记录

微信聊天记录如何备份到NAS?本文介绍了利用NAS虚拟机和同步工具实现微信记录自动备份的方法。通过在NAS上搭建"云电脑"长期运行微信PC端,并配置微力同步将聊天记录文件夹自动同步到NAS存储,解决了传统电脑备份的安全性问题。操作步骤包括:1)在NAS上安装虚拟机系统;2)登录微信PC端并同步手机记录;3)配置同步工具将微信记录文件夹同步到NAS。该方法尤其适合不常使用PC微信的用户,可实现记录永久保存和远程查看,更换手机时也能快速恢复历史记录。

dgnankai的专栏 4306

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

企业数据治理中YashanDB数据库的应用策略及价值

共享集群部署:基于Shared-Disk架构,依赖共享存储和崖山集群内核(YCK),通过全局缓存和资源协调实现多实例并发读写的强一致性访问,具备极高的可用性、扩展性和性能,适用于多实例多写的核心交易场景。在数据治理场景中,针对数据冷热分层管理,YashanDB通过混合使用MCOL和SCOL,结合后台转换作业,实现热数据的高频更新与冷数据的高效查询,最大化资源效率。SCOL(稳态列式存储):基于切片式对象存储,支持高效压缩、编码及排序,针对海量冷数据的分析查询做性能优化,适用联机分析处理(OLAP)场景。

weixin_69469157的博客 950

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

数据仓库ADS层实战指南:构建高效业务分析引擎的关键策略

本文深入探讨了数据仓库ADS层的核心价值与构建策略。ADS层作为面向业务的“总装车间”,其核心在于将加工后的数据快速组装成可直接驱动决策的业务洞察。文章从业务场景出发,详细阐述了星型模型设计、预聚合策略、分区分桶与索引优化等关键技术,并强调了数据质量、安全与元数据治理的重要性,旨在帮助企业构建高效、稳定、易用的业务分析引擎。

weixin_29231263的博客 326

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

数据仓库从理论到实践

数据仓库从理论到实践

木鱼时刻的专栏 1175

企业数据治理中YashanDB数据库的角色与策略

数据安全是企业治理的核心要求。部署的灵活性使企业能够根据业务规模和技术需求,选择适合的数据管理架构,提升系统可用性和数据一致性,为数据治理奠定坚实基础。YashanDB,作为一款具备多样部署形态和先进存储引擎的数据库系统,为企业提供了强大的数据治理能力和灵活的部署策略,满足从在线事务处理到海量分析处理的多元化需求。随着企业数据规模的不断增长和业务场景的多样化,YashanDB凭借其灵活的部署架构、丰富的存储结构、多版本并发控制、高可用性和完善的安全体系,成为企业数据治理的重要支撑平台。

weixin_69469157的博客 506

数据治理成熟度模型:GitHub_Trending/db/dbt-utils评估框架

你是否还在为数据质量监控繁琐、跨数据库兼容性差、团队协作效率低而烦恼?本文将介绍如何利用GitHub_Trending/db/dbt-utils项目构建数据治理成熟度评估框架,帮助你系统性地提升数据治理水平。读完本文,你将能够: - 了解数据治理成熟度的五个阶段 - 掌握使用dbt-utils工具进行数据质量监控的方法 - 学会构建跨数据库兼容的数据治理流程 - 提升团队协作效率,降低数据治理成

gitblog_00392的博客 436
上一篇: 一个月后,我们又从 MySQL 双主切换成了主-从!
下一篇: 4种 Redis 集群方案及优缺点对比
程序员职业指南
博客等级 码龄4年 2136粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值