数据库系统原理与实践 笔记 #12

news2024/9/20 1:09:05

文章目录

  • 数据库系统原理与实践 笔记 #12
  • 事务管理和并发控制与恢复(续)
    • 并发控制
      • SQL-92中的并发级别
      • 基于锁的协议
      • 基于锁的协议的隐患
      • 锁的授予
      • 封锁协议
      • 两阶段封锁协议
      • 多粒度
      • 粒度层次的例子
      • 意向锁类型
      • 相容性矩阵
      • 多粒度封锁模式
      • 基于时间戳的协议
      • 基于时间戳协议的正确性
      • 基于有效性检查的协议
      • 事务Ti的有效性检测
    • 恢复系统
      • 故障分类
      • 恢复机制
      • 数据访问
      • 恢复和原子性
      • 基于日志的恢复机制
      • 数据库修改
      • 事务提交
      • 并发控制和恢复
      • Undo和Redo操作
        • 事务的Undo和Redo
      • 从故障中恢复的Undo和Redo
        • 从故障中恢复时
      • 检查点

数据库系统原理与实践 笔记 #12

事务管理和并发控制与恢复(续)

并发控制

  • 数据库必须提供一种机制来保证所有调度(目标)是:
    • 冲突可串行化
    • 可恢复性,最好是无级联
  • 一个策略是一个时间只允许一个事务,即产生一个串行调度,但是并发性能差
  • 目标:建立一个能够保证串行化的并发控制协议

SQL-92中的并发级别

  • 可串行化(serializable)—通常保证可串行化的执行
  • 可重复读(repeatable read)—只允许读取已提交数据,一个事务对相同数据的重复读取要返回相同的值(其他事务不得更改该数据)
  • 已提交读(read committed)—(默认)只允许读取已提交的数据,但不要求可重复读
  • 未提交读(read uncommitted)—允许读取未提交数据
  • 以上所有隔离性级别都不允许脏写:即如果一个数据项已经被另外一个尚未提交或中止的事务写入,则不允许对该数据项执行写操作
  • 通过命令显式设置隔离性级别:
set transaction isolation level serializable

基于锁的协议

  • 是用来控制对数据项的并发访问的一种机制
  • 给数据加锁有两种方式:
    • 排他锁(X):对数据项即可写又可读,使用lock-X指令
    • 共享锁(S):对数据项只能读,使用lock-S指令
  • unlock指令释放锁
  • 申请锁请求发送给并发控制管理器,只有在并发控制管理器授予所需锁之后,事务才能继续其操作
  • 锁相容性矩阵
      表示为comp(A, B)
SX
Struefalse
Xfalsefalse
  • 指令之间的冲突对应于锁类型之间的不相容性

  • 如果被请求所与数据项上已有的锁相容,那么事务可以被授予该锁:

    • 一个数据项可以同时有多个共享锁
    • 如果一个事务在某个数据项上拥有排他锁,那么其他事物不能再在这个数据项上加任何锁
  • 如果一个锁不能被授予,那么请求该锁的事务必须等待,直到该数据项上的其他不相容锁全部释放,然后再授予锁

  • 事务执行锁的例子:
    T 2 : l o c k − S ( A ) ; r e a d ( A ) ; u n l o c k ( A ) ; l o c k − S ( B ) ; r e a d ( B ) ; u n l o c k ( B ) ; d i s p l a y ( A + B ) ; T_2:lock-S(A);\\ read(A); \\ unlock(A); \\ lock-S(B); \\ read(B);\\ unlock(B); \\ display(A+B); T2:lockS(A);read(A);unlock(A);lockS(B);read(B);unlock(B);display(A+B);

  • 上述锁无法有效地保证可串行化—如果A在read B的时候被其他事务更新了,那么最后的和将会是错误的答案

  • 需指定合理的封锁协议:一组规定事务何时对数据项进行加锁、解锁的规则。封锁协议限制了可能的调度数目

基于锁的协议的隐患

  • 考虑下面的调度:
    在这里插入图片描述

  • T 3 T_3 T3 T 4 T_4 T4都无法被处理—排他锁lock-S(B)导致 T 4 T_4 T4等待 T 3 T_3 T3释放其在B上的锁,而排他锁lock-X(A)导致 T 3 T_3 T3等待 T 4 T_4 T4释放其在A上的锁

  • 这样的情况称为死锁(deadlock):要处理 T 3 T_3 T3 T 4 T_4 T4其中一个死锁,必须回滚并释放锁

  • 大多数封锁协议都会产生死锁

  • 如果并发控制管理器设计得差也有可能导致饿死(starved)

  • 并发控制协议可以通过良好的设计,能够避免事务饿死

锁的授予

  • 避免事务饿死的授权加锁方式:当事务 T i T_i Ti申请对数据项Q加M型锁时,并发控制管理器授权加锁的条件需满足:
    • 1.不存在在数据项Q上持有与M型锁冲突的锁的其他事务
    • 2.不存在等待对数据项Q加锁且**先于 T i T_i Ti申请加锁的事务
  • 这样,一个加锁申请就不会被其后的加锁申请阻塞

封锁协议

  • { T 0 , T 1 , . . . , T n } \{T_0, T_1, ..., T_n\} {T0,T1,...,Tn}是参与调度S的一个事务集,如果存在数据项Q,使得 T i T_i Ti在Q上持有A型锁。后来, T j T_j Tj在Q上持有B型锁,且comp(A,B)=false,则我们称 T i T_i Ti先于 T j T_j Tj,记为 T i → T j T_i\rightarrow T_j TiTj
    • 如果 T i → T j T_i\rightarrow T_j TiTj,这一优先意味着在任何等价的串行调度中, T i T_i Ti必须出现在 T j T_j Tj之前
  • 如果调度S是那些遵从封锁协议规则的事务集的可能调度之一,我们称调度S在规定的封锁协议下是合法的
  • 一个封锁协议当且仅当其所有合法的调度为冲突可串行化时,我们称它保证冲突可串行性
  • 换句话说,对于任何合法的调度,其关联的事务优先关系是无循环

两阶段封锁协议

  • 这是一个能够保证冲突可串行化调度的协议
  • 阶段1:增长阶段
    • 事务可以获得锁
    • 事务不能释放锁
  • 阶段2:缩减阶段
    • 事务可以释放锁
    • 事务不能获得新锁
  • 封锁点:在调度中该事务获得其最后加锁的位置(增长阶段结束点)
  • 两阶段封锁协议保证可串行化:可以证明事务可以按照封锁点来排序(一种可串行化次序)
  • 两阶段封锁不能保证不发生死锁
  • 两阶段封锁下很有可能发生级联回滚
    • 为了避免这个问题,将该协议修改为严格两阶段封锁协议
  • 严格两阶段封锁协议要求未提交事务所写的热河数据在该事务提交之前均以排他方式加锁,防止其他事务读取这些数据
  • 强两阶段封锁协议更加严格:要求是提交之前不得释放任何锁(在这个协议下,事务可以按其提交顺序串行化

多粒度

  • 将多个数据聚成一组,作为同步单元,无需单独对单个数据项进行加锁
  • 多粒度:允许各种大小的数据项,并定义数据粒度的层次结构,可以图形化的表示为树
  • 如果一个事务显式地对树中的某个节点加了锁,那么它也给所有统一模式下的该节点的子节点隐式地加了锁
  • 锁的力度
    • 细粒度(树的低层):高并发性,锁开销多
    • 粗粒度(树的高层):低并发性,锁开销少

粒度层次的例子

  • 如事务 T i T_i Ti需判定某个节点(如 r b 1 r_{b_1} rb1)是否可以加锁,必须从根结点进行遍历至该节点(开销大)

在这里插入图片描述

意向锁类型

  • 除了排他锁及共享锁类型,多粒度下还有其他三种锁类型:
    • 共享型意向锁(IS):将在树的较低层进行显式封锁,但只能加共享锁
    • 排他型意向锁(IX):将在树的较低层进行显式封锁,可以加排他锁共享锁
    • 共享排他型意向锁(SIX):以该节点为根的子树显式地加了共享锁,并且在树的更底层显式地加排他锁
  • 意义:意向锁允许较高层的节点被加上共享锁或排他锁,而无需从树根遍历到子孙节点来检验锁的相容性,提升锁相容检验的效率

相容性矩阵

  • 所有所类型的相容性矩阵
    在这里插入图片描述

多粒度封锁模式

  • 事务 T i T_i Ti按如下规则对数据项Q加锁:
    • 1.必须遵从锁类型相容函数
    • 2.必须首先是封锁树的根节点,并且可以加任意类型的锁
    • 3.仅当事务 T i T_i Ti当前对Q的父节点具有IX或IS时,对结点Q可加S或IS锁
    • 4.仅当事务 T i T_i Ti当前对Q的父节点具有IX时,对节点Q可加X、SIX或IX锁
    • 5.仅当 T i T_i Ti未曾对任何节点解锁时, T i T_i Ti可对节点加锁(满足两阶段封锁)
    • 6.仅当 T i T_i Ti当前不持有Q的子节点的锁时, T i T_i Ti可对节点Q解锁
  • 加锁按自顶向下的顺序,锁的释放按自底向上的顺序

基于时间戳的协议

  • 对于系统中每个事务 T i T_i Ti,我们把一个唯一的固定时间戳和它联系起来,此时间戳记为 T S ( T i ) TS(T_i) TS(Ti);该时间戳是在事务 T i T_i Ti开始执行前由数据库系统赋予的。若事务 T i T_i Ti已被赋予时间戳 T S ( T i ) TS(T_i) TS(Ti),并且有一新事务 T j T_j Tj进入系统,则 T S ( T i ) < T S ( T j ) TS(T_i)<TS(T_j) TS(Ti)<TS(Tj)
  • 事务的时间戳决定了串行化顺序
  • 每个数据项Q需要与两个时间戳值相关联
    • W-timestamp(Q)表示成功执行write(Q) 的所有事务的最大时间戳
    • R-timestamp(Q)表示成功执行read(Q) 的所有事务的最大时间戳
  • 时间戳排序协议保证任何有冲突的readwrite操作按照时间戳顺序执行
  • 假设事务 T i T_i Ti发出指令read(Q)
    • 1.若 T S ( T i ) TS(T_i) TS(Ti) < W-timestamp(Q),则 T i T_i Ti需要读入的Q值已被覆盖:read操作被拒绝, T i T_i Ti回滚
    • 2.若 T S ( T i ) ≥ TS(T_i)\ge TS(Ti)W-timestamp(Q):执行read操作,R-timestamp(Q)被设置为max(R-timestamp(Q), T S ( T i ) TS(T_i) TS(Ti))
  • 假设事务 T i T_i Ti发出指令write(Q)
    • 1.若 T S ( T i ) TS(T_i) TS(Ti) < R-timestamp(Q),则 T i T_i Ti所需更新Q的值已过时:write操作被拒绝, T i T_i Ti回滚
    • 2.若 T S ( T i ) TS(T_i) TS(Ti) <W-timestamp(Q),则 T i T_i Ti试图写入的Q值已过时:write操作被拒绝, T i T_i Ti被饿死
    • 3.其他情况:执行write操作,将W-timestamp(Q)设置为 T S ( T i ) TS(T_i) TS(Ti)

基于时间戳协议的正确性

  • 时间戳排序协议保证冲突可串行化:冲突操作按时间戳的顺序来处理
  • 保证无死锁:不存在等待,可能有长事务饿死
  • 可能产生不可恢复的调度:事务可恢复性与事务提交顺序有关

基于有效性检查的协议

  • 有效性检查协议(适用于大部分只读事务的情况) 要求每个事务 T i T_i Ti在其生命周期中按两个或三个阶段执行:
    • 1.读阶段:事务 T i T_i Ti的所有write操作都是对局部临时变量进行的
    • 2.有效性检查阶段:事务 T i T_i Ti进行有效性检查,判断是否可以write操作而不违反可串行性
    • 3.写阶段:如果 T i T_i Ti已通过有效性检查,则保存任何写操作结果的临时局部变量值被复制到数据库中。只读事务不进入此阶段
  • 每个事务必须按照以上顺序经历这些过程。然而,并发执行的事务三个阶段可以是交叉执行
  • 每个事务 T i T_i Ti都有三个不同的时间戳:
    • Start( T i T_i Ti):事务 T i T_i Ti开始执行的时间
    • Validation( T i T_i Ti):事务 T i T_i Ti完成读阶段
  • 利用时间戳Validation( T i T_i Ti)的值,通过时间戳排序技术决定可串行化顺序,以增加并发性:即 T S ( T i ) = V a l i d a t i o n ( T i ) TS(T_i) = Validation(T_i) TS(Ti)=Validation(Ti)

事务Ti的有效性检测

  • 对于任何满足 T S ( T k ) < T S ( T i ) TS(T_k) <TS(T_i) TS(Tk)<TS(Ti)的事务 T k T_k Tk必须满足下面两条件之一
    • F i n i s h ( T k ) < S t a r t ( T i ) Finish(T_k) < Start(T_i) Finish(Tk)<Start(Ti)
    • S t a r t ( T i ) < F i n i s h ( T k ) < V a l i d a t i o n ( T i ) Start(T_i) < Finish(T_k) < Validation(T_i) Start(Ti)<Finish(Tk)<Validation(Ti)并且需保证 T k T_k Tk锁写的数据项集与 T i T_i Ti所读数据项集不想交;即 T k T_k Tk的写操作不会影响到 T i T_i Ti的读操作
  • 则有效性检测通过, T i T_i Ti可以进入写阶段并提交,否则测试失败 T i T_i Ti中止
  • 有效性检查协议能够自顶预防级联回滚,保证无死锁

恢复系统

故障分类

  • 事务故障
    • 逻辑错误:由于某些内部条件而无法继续正常执行
    • 系统错误:系统进入一种不良状态(如死锁),结果事务无法继续正常执行
  • 系统崩溃:硬件故障,或者是数据库软件或操作系统的漏洞,导致易失性存储器内容丢失,并使得事务处理停止
  • 磁盘故障:由于磁头损坏或故障造成磁盘块上的内容丢失:
    • 毁坏是可探测的:磁盘驱动器用校验和来检测故障

恢复机制

  • 保证数据库一致性以及事务的原子性的算法称为回复算法:
    • 正常事务处理时采取措施,保证有足够的信息可用于故障恢复
    • 故障发生后采取措施,将数据库内容恢复到某个保证数据库一致性、事件原子性及持久性的状态
  • 存储器类型:
    • 易失性存储器(volatile storage):易失性存储器中的信息在系统崩溃时通常无法保存下来
    • 非易失性存储器(nonvolatile storage):非易失性存储器中的信息在系统崩溃时可以保存下来
    • 稳定存储器(stable storage):稳定存储器中的信息永不丢失

数据访问

  • 物理块是位于磁盘上的块

  • 缓冲块是临时位于主存的块

  • 磁盘和主存间的块移动是由下面两个操作引发的:**input(B)**传送物理块B到主存,**output(B)**传送缓冲块B至硬盘,并替换磁盘上相应的物理块

  • 例子
    在这里插入图片描述

  • 每个事务 T i T_i Ti有一个私有工作区,用于保存 T i T_i Ti所访问及更新的所有数据项的拷贝: T i T_i Ti的工作区中保存的每一个数据项X记为 x i x_i xi

  • 使用下面两个操作里完成数据在工作区和系统缓冲区之间的传递:

    • read(X) 将数据项X的值赋予局部变量 x i x_i xi
    • write(X) 将局部变量 x i x_i xi的值赋予缓冲块中的数据项X
    • 注意: output( B x B_x Bx) 不需要立刻在write(X)后执行。系统会在它认为合适的时候执行output操作
  • 事务:必须在第一次访问X之前执行read(X);**write(X)**可以在事务被提交前的任意时刻执行

恢复和原子性

  • 为保证原子性,我们必须在修改数据库本身之前,首先向稳定存储器输出信息,描述要做的修改
  • 目的:确保由中止事务所做的修改不会持久保存与数据库中,即回滚该中止事务
  • 基于日志的恢复系统

基于日志的恢复机制

  • 日志保存于稳定存储器中:日志是日志记录的序列它记录数据库中的所有更新活动
  • 当一个事务 T i T_i Ti开始时,它记录 < T i   s t a r t > <T_i \ start> <Ti start>
  • 事务 T i T_i Ti执行write(X) 前,日志记录: < T i   X , V 1 , V 2 > <T_i\ X, V_1, V_2> <Ti X,V1,V2> V 1 V_1 V1是在write之前X的值(旧值), V 2 V_2 V2是需要写入X的值(新值)
  • T i T_i Ti结束了最后一条指令时, < T i   c o m m i t > <T_i\ commit> <Ti commit>写入日志
  • 当事 T i T_i Ti中止时,日志记录 < T i   a b o r t > <T_i\ abort> <Ti abort>
  • 使用日志的两种方法:延迟的数据库修改(事务提交后还未修改),立即的数据库修改(事务提交前已修改)

数据库修改

  • 立即修改模式允许在事务提交前,将未提交的事务更新至缓冲区或磁盘
  • 延迟修改模式直到事务提交时都没有更新到缓冲区/磁盘:简化了恢复,但是多了存储本地副本的开销
  • 日志记录的更新必须在数据项被write(数据库修改)之前完成

事务提交

  • 当事务将其关于提交的日志记录输出到稳定存储器时,该事务被认为已提交:之前的所有日志记录必须都已经输出
  • 事务提交时,由该事务执行的write操作结果可能仍在缓冲区,随后被输出

并发控制和恢复

  • 在并发事务中,所有事务共享一个磁盘缓冲区和日志:一个缓冲块中的数据项可以来自多个事务的更新
  • 假设如果一个事务 T i T_i Ti习概了一个数据项,那么在 T i T_i Ti提交前,其他事务不能修改同一个数据项(即不允许脏写):
    • 未提交事务的更新不能被其他事务所见
    • 可以通过在被更新数据项上获取排他锁,并持有该锁直到事务提交位置来保证(严格两阶段封锁
  • 不同事务的日志记录在日志中穿插(interspersed)存储

Undo和Redo操作

  • 对日志记录 < T i , X , V i , V 2 > <T_i, X, V_i, V_2> <Ti,X,Vi,V2>Undo操作将旧值 V 1 V_1 V1写入X
  • 对日志记录 < T i , X , V 1 , V 2 > <T_i, X, V_1, V_2> <Ti,X,V1,V2>Redo操作将新值 V 2 V_2 V2写入X
事务的Undo和Redo
  • undo( T i T_i Ti) 将事务 T i T_i Ti所更新的所有数据项的值恢复成旧值,回到 T i T_i Ti的最后一条日志记录:
    • 每次数据项X被恢复成旧值,日志记录 < T i , X , V > <T_i, X, V> <Ti,X,V>会被写入
    • 当事务的undo操作完成时,日志记录 < T i   a b o r t > <T_i \ abort> <Ti abort>被写入
  • redo( T i T_i Ti) 将事务 T i T_i Ti所更新的所有数据项的值置为新值,从 T i T_i Ti的第一条日志记录开始执行(这个情况下没有任何日志记录)

从故障中恢复的Undo和Redo

从故障中恢复时
  • 当日志是以下状态时,事务 T i T_i Ti需要undo操作:
    • 有日志 < T i   s t a r t > <T_i\ start> <Ti start>
    • 没有日志 < T i   c o m m i t > <T_i\ commit> <Ti commit> < T i   a b o r t > <T_i\ abort> <Ti abort>
  • 当日志是以下状态时,事务 T i T_i Ti需要进行redo操作:
    • 有日志 < T i   s t a r t > <T_i\ start> <Ti start>
    • 日志 < T i   c o m m i t > <T_i\ commit> <Ti commit> < T i   a b o r t > <T_i\ abort> <Ti abort>
  • 如果事务 T i T_i Ti之前执行了undo操作, < T i   a b o r t > <T_i\ abort> <Ti abort>被写入到日志,接着故障发生。为了从故障中恢复, T i T_i Ti要执行redo操作
  • 这样的redo操作重新执行了原先的所有操作,包括重新存储旧值:称为重复历史,看起来很浪费,但是最大程度地简化了恢复

检查点

  • 对于日志中的所有事务做Redo/Undo
    • 1.如果系统已经运行了很长一段时间,那么处理整个日志很浪费时间
    • 2.那些已经将输出更新到数据库的事务没必要redo
  • 流线型恢复过程周期性地执行检查点
    • 1.将当前位于主存的所有日志记录输出到稳定存储器上
    • 2.将所有修改了的缓冲块输出到磁盘上
    • 3.将一个日志记录 < c h e c k p o i n t   L > <checkpoint\ L> <checkpoint L>输出到稳定存储器
    • 执行检查点时,所有数据更新都停止
  • 恢复时,我们仅考虑在检查点前最近开始的事务 T i T_i Ti,及在 T i T_i Ti后开始的事务:
    • 从日志末尾反向扫描,找到最近的 < c h e c k p o i n t   L > <checkpoint\ L> <checkpoint L>记录
    • 只要在L未提交/中止的事务或者在检查点后开始的事务需要redo或undo
    • 检查点之前的已提交或者中止的事务已经将其更新输出到了稳定存储器
  • undo操作可能需要一些早期的日志
    • 继续从日志末尾反向扫描直到找到在L的每个事务 T i T_i Ti的记录 < T i   s t a r t > <T_i\ start> <Ti start>

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

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

相关文章

mysql:用SHOW CREATE TABLE tbl_name查看创建表的SQL语句

https://dev.mysql.com/doc/refman/8.2/en/show-create-table.html 可以用SHOW CREATE TABLE tbl_name查看创建表的SQL语句。 例如&#xff0c;SHOW CREATE TABLE test_table;表示查询创建test_table表的SQL语句&#xff1a;

关于电动机智能综合保护器在煤矿内的应用分析-安科瑞 蒋静

摘要 &#xff1a;介绍了矿用电动机智能综合保护器系统的总体结构&#xff0c;采用直接将交流信号整流、滤波、调理、采样的方式变为微控制器能够识别的直流信号&#xff0c;通过对微控制器采集到的直流信号编程判断来实现对电动机的相关保护控制、故障显示与报警以及与上位机的…

Jmeter性能测试:ForEach控制器的用法解析(含视频讲解)

引言 最近我在进行JMeter性能测试时遇到了一些问题&#xff0c;特别是在使用ForEach控制器时感到有点棘手。 但是经过不断地摸索和实践&#xff0c;终于成功地掌握了这个神奇的工具&#xff0c;提高了我的测试效率。因此&#xff0c;今天我想和大家分享我的经验&#xff0c;让…

优思学院|如何建立公司运营指标体系?如何推行六西格玛改进运营指标?

关键绩效指标 (KPI) 是测量您团队或组织朝重要商业目标进展表现如何的量化指标&#xff0c;组织会在多个层面使用 KPI&#xff0c;这视乎您想要追踪何指标而定&#xff0c;您可以设定全组织的、特定团队的、或甚至是个人 KPI。 良好的KPI能让公司管理者掌握组织的营运是否进度…

【(较大规模)作业车间调度JSP】通过OR-Tools的区间变量建模求解的效率对比实验

文章目录 问题描述Python调用OR-Tools建模求解&#xff08;实验一&#xff09;1. 声明问题的模型2. 创建区间变量3. 创建约束条件4. 求解模型5. 基于 plotly 展示甘特图 不同场景下的求解效率对比实验二&#xff1a;工件的工序数有差异实验三&#xff1a;消除工件的加工时长差异…

php实现个性化域名(短网址)和个性化登录模版的解决方案

在PHP中&#xff0c;个性化域名通常指的是根据用户或业务需求动态生成具有特定规律的子域名。实现个性化域名的方法主要依赖于服务器配置和路由规则。下面是一些基本的步骤和考虑因素&#xff0c;以帮助你了解如何个性化域名&#xff0c;并了解这样做的好处。 如何实现个性化域…

Cohort Analysis是什么

Cohort Analysis 什么是Cohort Analysis Cohort Analysis 可以翻译成 群体分析 或 分组分析&#xff0c;其实是一种通过细分来研究数据的方法。如下表就是一个从每日新增维度细分的 Cohort Analysis 表格。 第一列是分组的维度&#xff0c;下表以用户新增的日期作为细分的维…

Docker安装与使用

Docker 1.初识Docker Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题&#xff1f; Docker允许开发中将应用、依赖、函数库、配置一起打包&#xff0c;形成可移植镜像Docker应用运行在容器中&#xff0c;使用沙箱机制&#xff0c;相互隔离 Docker…

“未来医疗揭秘:机器学习+多组学数据,开启生物医学新纪元“

在当今的数字化时代&#xff0c;科技正在不断地改变着我们的生活&#xff0c;同时也为医疗领域带来了巨大的变革。随着机器学习的快速发展&#xff0c;以及多组学数据在生物医学中的应用&#xff0c;我们正开启一个全新的医疗纪元。这个纪元以精准诊断、个性化治疗和高效康复为…

体验即营销,如何用体验家实现高效的线索细分?

什么是线索细分&#xff1f; 线索细分&#xff0c;指的是将收集而来的线索根据用户行为、特征等信息划分成若干个小组&#xff0c;从而方便市场、运营等部门开展更精细化的营销动作。 为什么要进行线索细分&#xff1f; 不同的客户为企业带来的价值不同。许多情况下&#xff0c…

智能无人零售:革新零售消费体验的未来

智能无人零售&#xff1a;革新零售消费体验的未来 在当今数字化时代&#xff0c;智能无人零售正以惊人的速度改变着我们的购物方式和消费体验。这一新兴领域的发展&#xff0c;为消费者带来了前所未有的便利和个性化选择。 智能无人零售是指利用先进的智能技术和自动化系统&…

(十六)Flask之蓝图

蓝图 Flask蓝图&#xff08;Blueprint&#xff09;是Flask框架中用于组织和管理路由、视图函数以及静态文件的一种机制。它提供了一种将应用程序拆分为更小、可重用组件的方式&#xff0c;使得项目结构更清晰&#xff0c;代码更易于维护。 使用Flask蓝图&#xff0c;可以将相…

git强制回滚,远程强制更新,git pull强制更新

注意&#xff1a;这里是强制回滚&#xff0c;回滚后&#xff0c;之后历史的就没有了&#xff0c;慎用。 本地强制回滚 强制回滚到上一个版本 git reset --hard HEAD^强制回滚上上个版本 git reset --hard HEAD^^git log查看版本 git log --prettyonelinegit log --prettyf…

系列十、SpringBoot + MyBatis + Redis实现分布式缓存(基于注解方式)

一、概述 上篇文章 系列九、SpringBoot MyBatis Redis实现分布式缓存 介绍了基于xml方式实现分布式缓存的效果&#xff0c;当前大家使用的技术栈基本是springboot各种框架的组合&#xff0c;而springboot显著的一个特点就是去xml配置&#xff0c;那么在无xml配置的情形下&…

Java实现选择排序及其动图演示

选择排序是一种简单直观的排序算法。它的基本思想是每次从未排序的元素中选出最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放到已排序的序列的末尾。具体步骤如下&#xff1a; 首先&#xff0c;找到未排序序列中的最小&#xff08;或最大&#xff09;元素&a…

关于代码质量度量和分析的一些总结

最近团队做CMMI3认证&#xff0c;这期间涉及到了代码质量度量。花了点时间做了总结&#xff0c;分享给大家。 先看一张整体的图&#xff0c;然后逐个指标展开说明。 一、单元测试覆盖率 单元测试覆盖率&#xff08;Coverage&#xff09;是一个度量单元测试覆盖了多少代码的指标…

Ubuntu系统关闭防火墙的正确方式

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

调用Win10隐藏的语音包

起因 在做一个文本转语音的Demo的时候&#xff0c;遇到了语音包无法正确被Unity识别的问题。明明电脑上安装了语音包但是代码就是识别不出来 原因 具体也不是非常清楚&#xff0c;但是如果语言包是在的话&#xff0c;大概率是Win10系统隐藏了。 确定语言包 首先查看%windi…

MATLAB运动学之蒙特卡罗法求积分与机器人工作域分析

蒙特卡罗法又叫做统计模拟法、随机抽样技术&#xff0c;是一种随机模拟方法以概率和统计理论方法为基础的一种计算方法&#xff0c;通俗来说是可以使用随机数来解决很多计算问题的一种方法&#xff0c;很直观简单&#xff0c;尤其对于一些求解积分无解的情况&#xff0c;非常好…

数据挖掘分析过程中,常见的数据处理方法有哪些?

在进行数据挖掘分析的时候&#xff0c;数据处理是非常重要的一环。数据处理一般是要结合实际业务做相应的数据处理&#xff0c;为后续机器学习建模做好准备。比如数据存在缺失值&#xff0c;就要做相应的缺失值的填充或删除操作&#xff1b;数据建模需要的数据存储在不同的表或…