`
simonhoo
  • 浏览: 70355 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Oracle高水位线(HWM)及性能优化

 
阅读更多

说到HWM,我们首先要简要的谈谈ORACLE的逻辑存储管理.我们知道,ORACLE在逻辑存储上分4个粒度:表空间,,区和块.

 

(1):是粒度最小的存储单位,现在标准的块大小是8K,ORACLE每一次I/O操作也是按块来操作的,也就是说当ORACLE从数据文件读数据时,是读取多少个块,而不是多少行.

 

(2):由一系列相邻的块而组成,这也是ORACLE空间分配的基本单位,举个例子来说,当我们创建一个表PM_USER,首先ORACLE会分配一区的空间给这个表,随着不断的INSERT数据到PM_USER,原来的这个区容不下插入的数据时,ORACLE是以区为单位进行扩展的,也就是说再分配多少个区给PM_USER,而不是多少个块

 

(3):是由一系列的区所组成,一般来说,当创建一个对象时(,索引),就会分配一个段给这个对象.所以从某种意义上来说,段就是某种特定的数据.CREATE TABLE PM_USER,这个段就是数据段,CREATE INDEX ON PM_USER(NAME),ORACLE同样会分配一个段给这个索引,但这是一个索引段了.查询段的信息可以通过数据字典: SELECT * FROM USER_SEGMENTS来获得,

 

(4)表空间:包含段,区及块.表空间的数据物理上储存在其所在的数据文件中.一个数据库至少要有一个表空间.

 

OK,我们现在回到HWM上来,那么,什么是高水位标记呢?这就跟ORACLE的段空间管理相关了.

 

 

()ORACLEHWM来界定一个段中使用的块和未使用的块.


举个例子来说,当我们创建一个表:PT_SCHE_DETAIL,ORACLE就会为这个对象分配一个段.在这个段中,即使我们未插入任何记录,也至少有一个区被分配,第一个区的第一个块就称为段头(SEGMENT HEADE),段头中就储存了一些信息,基中HWM的信息就存储在此.此时,因为第一个区的第一块用于存储段头的一些信息,虽然没有存储任何实际的记录,但也算是被使用,此时HWM是位于第2个块.当我们不断插入数据到PM_USER,1个块已经放不下后面新插入的数据,此时,ORACLE将高水位之上的块用于存储新增数据,同时,HWM本身也向上移.也就是说,当我们不断插入数据时,HWM会往不断上移,这样,HWM之下的,就表示使用过的块,HWM之上的就表示已分配但从未使用过的块.

 

()HWM在插入数据时,当现有空间不足而进行空间的扩展时会向上移,但删除数据时不会往下移.

 

这就好比是水库的水位,当涨水时,水位往上移,当水退出后,最高水位的痕迹还是清淅可见.
考虑让我们看一个段,如一张表,其中填满了块,如图 1 所示。在正常操作过程中,删除了一些行,如图 2 所示。现有就有了许多浪费的空间:(I) 在表的上一个末端和现有的块之间,以及 (II) 在块内部,其中还有一些没有删除的行。

 

1:分配给该表的块。用灰色正方形表示行

 

ORACLE 不会释放空间以供其他对象使用,有一条简单的理由:由于空间是为新插入的行保留的,并且要适应现有行的增长。被占用的最高空间称为最高使用标记 (HWM),如图 2 所示。

 


2:行后面的块已经删除了;HWM 仍保持不变

 

()HWM的信息存储在段头当中.


HWM
本身的信息是储存在段头.在段空间是手工管理方式时,ORACLE是通过FREELIST(一个单向链表)来管理段内的空间分配.在段空间是自动管理方式时(ASSM),ORACLE是通过BITMAP来管理段内的空间分配.

 

()ORACLE的全表扫描是读取高水位标记(HWM)以下的所有块.

 

所以问题就产生了.当用户发出一个全表扫描时,ORACLE 始终必须从段一直扫描到 HWM,即使它什么也没有发现。该任务延长了全表扫描的时间。

 

()当用直接路径插入行时例如,通过直接加载插入(用 APPEND 提示插入)或通过 SQL*LOADER 直接路径数据块直接置于 HWM 之上。它下面的空间就浪费掉了。

 

我们来分析这两个问题,后者只是带来空间的浪费,但前者不仅是空间的浪费,而且会带来严重的性能问题.我们来看看下面的例子:

 

(A)我们先来搭建测试的环境,第一步先创建一个段空间为手工管理的表空间:

 

CREATE TABLESPACE "RAINNY"
LOGGING
DATAFILE 'D:ORACLE_HOMEORADATARAINNYRAINNY.ORA' SIZE 5M
AUTOEXTEND
ON NEXT 10M MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT MANUAL;

 

(B)创建一个表,注意,此表的第二个字段我故意设成是CHAR(100),以让此表在插入1千万条记录后,空间有足够大:

 

CREATE TABLE TEST_TAB(C1 NUMBER(10),C2 CHAR(100)) TABLESPACE RAINNY;

 

插入记录

 

DECLARE
    I NUMBER(10);

BEGIN
    FOR I IN 1..10000000 LOOP
        INSERT INTO TEST_TAB VALUES(I,'TESTSTRING');
    END LOOP;
    COMMIT;

END;

/


(C)我们来查询一下,看在插入一千万条记录后所访问的块数和查询所用时间:


SQL> SET TIMING ON

SQL> SET AUTOTRACE TRACEONLY

SQL> SELECT COUNT(*) FROM TEST_TAB;

 

ELAPSED: 00:01:03.05

 

EXECUTION PLAN

------------------------------------------------------------

0 SELECT STATEMENT OPTIMIZER=CHOOSE (COST=15056 CARD=1)

1 0 SORT (AGGREGATE)

2 1 TABLE ACCESS (FULL) OF 'TEST_TAB' (COST=15056 CARD=10000

000)

 

STATISTICS

----------------------------------------------------------

0      RECURSIVE CALLS

0      DB BLOCK GETS

156310 CONSISTENT GETS

154239 PHYSICAL READS

0      REDO SIZE

379    BYTES SENT VIA SQL*NET TO CLIENT

503    BYTES RECEIVED VIA SQL*NET FROM CLIENT

2      SQL*NET ROUNDTRIPS TO/FROM CLIENT

0      SORTS (MEMORY)

0      SORTS (DISK)

1      ROWS PROCESSED


我们来看上面的执行计划,这句SQL总供耗时是:13.访问方式是采用全表扫描方式(FTS),逻辑读了156310BLOCK,物理读了154239BLOCK.
我们来分析一下这个表:

 

BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=> 'TEST',
TABNAME=> 'TEST_TAB',
PARTNAME=> NULL);END;

/


发现这个表目前使用的BLOCK: 156532,未使用的BLOCK(EMPTY_BLOCKS):0,总行数为(NUM_ROWS):1000 0000

 

(D)接下来我们把此表的记录用DELETE方式删掉,然后再来看看SELECT COUNT(*) FROM TEST_TAB所花的时间:

 

DELETE FROM TEST_TAB;
COMMIT;

 

SQL> SELECT COUNT(*) FROM TEST_TAB;

 

ELAPSED: 00:01:04.03

 

EXECUTION PLAN
----------------------------------------------------------
0 SELECT STATEMENT OPTIMIZER=CHOOSE (COST=15056 CARD=1)

1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'TEST_TAB' (COST=15056 CARD=1)

 

STATISTICS
----------------------------------------------------------
0      RECURSIVE CALLS
0      DB BLOCK GETS
156310 CONSISTENT GETS
155565 PHYSICAL READS
0      REDO SIZE
378    BYTES SENT VIA SQL*NET TO CLIENT
503    BYTES RECEIVED VIA SQL*NET FROM CLIENT
2      SQL*NET ROUNDTRIPS TO/FROM CLIENT
0      SORTS (MEMORY)
0      SORTS (DISK)
1      ROWS PROCESSED

 

大家来看,DELETE表后,此时表中已没有一条记录,为什么SELECT COUNT(*) FROM TEST_TAB花的时间为14, 反而比有记录稍微长点,这是为什么呢?而且大家看,其逻辑读了156310 BLOCK,跟之前有一千万行记录时差不多,ORACLE怎么会这么笨啊?


我们在DELETE表后再次分析表,看看有什么变化:
这时, TEST_TAB表目前使用的BLOCK: 156532,未使用的BLOCK(EMPTY_BLOCKS):0,总行数为(NUM_ROWS)已变成:0

为什么表目前使的BLOCK数还是156532?


问题的根源就在于ORACLEHWM.也就是说,在新增记录时,HWM会慢慢往上移,但是在删除记录后,HWM却不会往下移,也就是说,DELETE一千万条记录后,此表的HWM根本没移动,还在原来的那个位置,所以,HWM以下的块数同样也是一样的.ORACLE的全表扫描是读取ORACLE高水位标记下的所有BLOCK,也就是说,不管HWM下的BLOCK现在实际有没有存放数据,ORACLE都会一一读取,这样,大家可想而知,在我们DELETE表后,ORACLE读了大量的空块,耗去了大量的时间.

 


我们再来看DELETE表后段空间实际使用的状况:

 

SQL> EXEC SHOW_SPACE('TEST_TAB','TEST');

TOTAL BLOCKS............................164352 --总共164352
TOTAL BYTES.............................1346371584
UNUSED BLOCKS...........................7168
--7168块没有用过,也就是在HWM上面的块数
UNUSED BYTES............................58720256
LAST USED EXT FILEID....................9
LAST USED EXT BLOCKID...................158856
-- BLOCK ID 是针对数据文件来编号的,表示最后使用的一个EXTENT的第一个BLOCK的编号
LAST USED BLOCK.........................1024
--在最后使用的一个EXTENT 中一共用了1024

 

PL/SQL PROCEDURE SUCCESSFULLY COMPLETED

 

总共用了164352块,除了一个SEGMENT HEADER,实际总共用了164351个块,有7168块从来没有使用过。LAST USED BLOCK表示在最后一个使用的EXTENT 中使用的BLOCK, 结合 LAST USED EXT BLOCK ID可以计算 HWM 位置 :


LAST USED EXT BLOCK ID + LAST USED BLOCK -1 = HWM
所在的数据文件的BLOCK编号

 

代入得出: 158856+1024-1=159879,这个就是HWM所有的BLOCK编号

HWM所在的块:TOTAL BLOCKS- UNUSED BLOCKS=164352-7168=157184,也就是说,HWM在第157184个块,BLOCKID159879

 

(E)结下来,我们再做几个试验:

 

第一步:执行ALTER TABLE TEST_TAB DEALLOCATE UNUSED;

我们看看段空间的使用状况:

 

SQL> EXEC SHOW_SPACE('TEST_TAB','TEST');

 

TOTAL BLOCKS............................157184
TOTAL BYTES.............................1287651328
UNUSED BLOCKS...........................0
UNUSED BYTES............................0
LAST USED EXT FILEID....................9
LAST USED EXT BLOCKID...................158856
LAST USED BLOCK.........................1024

 

此时我们再代入上面的公式,算出HWM的位置: 157184-0=157184 HWM所在的BLOCK ID158856+1024-1=159879,跟刚刚的没有变化,也就是说执行ALTER TABLE TEST_TAB DEALLOCATE UNUSED,段的高水位标记的位置没有改变,但是大家看看UNUSED BLOCKS变为0,总的块数减少到157184,这证明,DEALLOCATE UNUSED为释放HWM上面的未使用空间,但是并不会释放HWM下面的自由空间,也不会移动HWM的位置.

 

第二步:我们再来看看执行ALTER TABLE TEST_TAB MOVE后段空间的使用状况:

 

SQL> EXEC SHOW_SPACE('TEST_TAB','TEST');

 

TOTAL BLOCKS............................8

TOTAL BYTES.............................65536

UNUSED BLOCKS...........................5

UNUSED BYTES............................40960

LAST USED EXT FILEID....................9

LAST USED EXT BLOCKID...................2632

LAST USED BLOCK.........................3


此时,总共用到的块数已变为8, 我们再代入上面的公式,算出HWM的位置: 8-5=3 HWM所在的BLOCK ID2632+3-1=2634,

 

OK,我们发现,此时HWM的位置已经发生变化,现在HWM的位置是在第3BLOCK,BLOCK ID2634,所有数据文件的ID9(这个没有发生变化,数据文件还是原来的那个数据文件,只是释放了原来的自由空间),最后使用的块数也变为3,也就是说已经使用了3,HWM就是在最后一个使用的块上,即第3个块上.大家可能会觉得奇怪,为什么释放空间后,未使用的块还有5个啊?也就是说HWM之上还是有5个已分配但从未使用的块.答案就跟HWM移动的规律有关.当我们在插入数据时,ORACLE首先在HWM之下的块当中定位自由空间(通过自由列表FREELIST),如果FREELIST当中没有自由块了,ORACLE就开始往上扩展,HWM也跟着往上移,5块移动一次.我们来看ORACLE的说明:

 

The high water mark is:
-Recorded in the segment header block
-Set to the beginning of the segment on the creation
-Incremented in five-block increments as rows are inserted
-Reset by the truncate command
-Never reset by the delete command
-Space above the high-water-mark can be reclaimed at the table level by using the following command:
ALTER TABLE DEALLOCATE UNUSED…

 

我们再来看看:SELECT COUNT(*) FROM TEST_TAB所花的时间:

 

SQL> SELECT COUNT(*) FROM TEST_TAB;

 

ELAPSED: 00:00:00.00

EXECUTION PLAN
----------------------------------------------------------

0 SELECT STATEMENT OPTIMIZER=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'TEST_TAB'

 

STATISTICS
----------------------------------------------------------
0     RECURSIVE CALLS
0     DB BLOCK GETS

3     CONSISTENT GETS
0     PHYSICAL READS
0     REDO SIZE
378   BYTES SENT VIA SQL*NET TO CLIENT
503   BYTES RECEIVED VIA SQL*NET FROM CLIENT
2     SQL*NET ROUNDTRIPS TO/FROM CLIENT
0     SORTS (MEMORY)
0     SORTS (DISK)
1     ROWS PROCESSED

 

很快,不到1.

 

我们最后再来对表作一次分析, 此时这个表目前使用的BLOCK: 0,未使用的BLOCK(EMPTY_BLOCKS):0,总行数为(NUM_ROWS):0
从中我们也可以发现,分析表和SHOW_SPACE显示的数据有点不一致.那么哪个是准的呢?其实这两个都是准的,只不过计算的方法有点不同.事实上,当你创建了一个对象如表以后,不管你有没有插入数据,它都会占用一些块,ORACLE也会给它分配必要的空间.同样,ALTER TABLE MOVE释放自由空间后,还是保留了一些空间给这个表.
最后,我们再来执行TRUNCATE命令,截断这个表,看看段空间的使用状况:

 

TRUNCATE TABLE TEST_TAB;

 

SQL> EXEC SHOW_SPACE('TEST_TAB','TEST');

 

TOTAL BLOCKS............................8
TOTAL BYTES.............................65536
UNUSED BLOCKS...........................5
UNUSED BYTES............................40960
LAST USED EXT FILEID....................9
LAST USED EXT BLOCKID...................2632
LAST USED BLOCK.........................3

 

PL/SQL PROCEDURE SUCCESSFULLY COMPLETED

 

SQL>

 

我们发现TRUNCATE后和MOVE没有什么变化.

 

为了,最终验证一下我上面的观点,我再DROP一下表,然后新建这个表,看看这时在没有插入任何数据之前,是否ORACLE确实有给这个对象分配必要的空间:

 

DROP TABLE TEST_TAB;

 

CREATE TABLE TEST_TAB(C1 NUMBER(10),C2 CHAR(100)) TABLESPACE RAINNY;

 

SQL> EXEC SHOW_SPACE('TEST_TAB','TEST');

TOTAL BLOCKS............................8
TOTAL BYTES.............................65536
UNUSED BLOCKS...........................5
UNUSED BYTES............................40960
LAST USED EXT FILEID....................9
LAST USED EXT BLOCKID...................2112
LAST USED BLOCK.........................3

 

大家看,即使我没有插入任何一行记录,ORACLE还是给它分配了8个块.当然这个跟建表语句的INITIAL 参数及MINEXTENTS参数有关:请看TEST_TAB的存储参数:

 

S TORAGE
(
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
);

 

也就是说,在这个对象创建以后,ORACLE至少给它分配一个区,初始大小是64K,一个标准块的大小是8K,刚好是8BLOCK.

 

 

总结:

 

9I:

 

(1)如果MINEXTENT 可以使ALTER TABLE TABLENAME DEALLOCATE UNUSEDHWM以上所有没使用的空间释放
(2)
如果MINEXTENT >HWM 则释放MINEXTENTS 以上的空间。如果要释放HWM以上的空间则使用KEEP 0
ALTER TABLE TABLESNAME DEALLOCATE UNUSED KEEP 0;
(3) TRUNCATE TABLE DROP STORAGE(
缺省值)命令可以将MINEXTENT 之上的空间完全释放(交还给操作系统),并且重置HWM
(4)
如果仅是要移动HWM,而不想让表长时间锁住,可以用TRUNCATE TABLE REUSE STORAGE,仅将HWM重置。
(5)ALTER TABLE MOVE
会将HWM移动,但在MOVE时需要双倍的表空间,而且如果表上有索引的话,需要重构索引
(6)DELETE
表不会重置HWM,也不会释放自由的空间(也就是说DELETE空出来的空间只能给对象本身将来的INSERT/UPDATE使用,不能给其它的对象使用)

 

ORACLE 10G:

 

可以使用ALTER TABLE TEST_TAB SHRINK SPACE命令来联机移动HWM,
如果要同时压缩表的索引,可以发布:ALTER TABLE TEST_TAB SHRINK SPACE CASCADE
注意:在使用此命令时需要先使行可迁移row movement(具体见例子)
        
与使用ALTER TABLE MOVE 不同的是执行此命令后并不需要重构索引。

 

 

Oracle 官方说明

 

Shrinking Database Segments Online
You use online segment shrink to reclaim fragmented free space below the high water mark in an Oracle Database segment. The benefits of segment shrink are these:
    * Compaction of data leads to better cache utilization, which in turn leads to better online transaction processing (OLTP) performance.
    * The compacted data requires fewer blocks to be scanned in full table scans, which in turns leads to better decision support system (DSS) performance.
Segment shrink is an online, in-place operation. DML operations and queries can be issued during the data movement phase of segment shrink. Concurrent DML operation are blocked for a short time at the end of the shrink operation, when the space is deallocated. Indexes are maintained during the shrink operation and remain usable after the operation is complete. Segment shrink does not require extra disk space to be allocated.
Segment shrink reclaims unused space both above and below the high water mark. In contrast, space deallocation reclaims unused space only above the high water mark. In shrink operations, by default, the database compacts the segment, adjusts the high water mark, and releases the reclaimed space.
Segment shrink requires that rows be moved to new locations. Therefore, you must first enable row movement in the object you want to shrink and disable any rowid-based triggers defined on the object.
Shrink operations can be performed only on segments in locally managed tablespaces with automatic segment space management (ASSM). Within an ASSM tablespace, all segment types are eligible for online segment shrink except these:
    * IOT mapping tables
    * Tables with rowid based materialized views
    * Tables with function-based indexes

 

 

操作的过程:

 

SQL> create table demo as select * from dba_source;

Table created.
Elapsed: 00:00:05.83

 

SQL> select count(*) from demo;

 

  COUNT(*)
----------
    210992
Elapsed: 00:00:01.06

 

SQL> insert into demo select * from demo;
210992 rows created.
Elapsed: 00:00:59.83

 

SQL> commit;
Commit complete.

 

//得到一个40万条记录的表,下面来查看这个表空间分布情况。

 

SQL> exec show_space('demo','auto');

 

PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07

 

SQL> set serveroutput on

 

SQL>  exec show_space('demo','auto');

 

Total Blocks............................9216
Total Bytes.............................75497472
Unused Blocks...........................768
Unused Bytes............................6291456
Last Used Ext FileId....................4
Last Used Ext BlockId...................8328
Last Used Block.........................256

 

一共有9216个数据块,HWM9216-768=8448这个块.
也可以通过查看extents得到HWM=8*16+128*63+256=8192+256=8448

 

PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01

 

SQL> delete from demo where rownum<220000;

 

219999 rows deleted.
Elapsed: 00:00:40.99

 

SQL> commit;

 

Commit complete.
Elapsed: 00:00:00.01

 

SQL>  exec show_space('demo','auto');

 

Total Blocks............................9216
Total Bytes.............................75497472
Unused Blocks...........................768
Unused Bytes............................6291456
Last Used Ext FileId....................4
Last Used Ext BlockId...................8328
Last Used Block.........................256

 

PL/SQL procedure successfully completed.

 

//删除操作后表的HWM没有变化,还是在第8448块这个位置。
Elapsed: 00:00:00.00

 

SQL> alter table demo shrink space;
alter table demo shrink space
*
ERROR at line 1:
ORA-10636: ROW MOVEMENT is not enabled

//先要enable row movement才能shrink
Elapsed: 00:00:00.09

 

SQL> alter table demo enable row movement;

 

Table altered.
Elapsed: 00:00:00.10

 

SQL>  alter table demo shrink space;

 

Table altered.
Elapsed: 00:01:35.51

 

SQL>  exec show_space('demo','auto');

 

Total Blocks............................3656
Total Bytes.............................29949952
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................4
Last Used Ext BlockId...................3720
Last Used Block.........................72

 

PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02

//可以看到HWM降到了3656这个块上面!

 

分享到:
评论

相关推荐

    034-基于AT89C52的矩阵键盘扫描proteus仿真设计.rar

    51单片机

    双级式储能模型,可做充放电转以及低电压故障穿越,含有负序抑制模块,可做对称故障与不对称故障

    双级式储能模型,可做充放电转以及低电压故障穿越,含有负序抑制模块,可做对称故障与不对称故障

    郑州升达大学2024-2025第一学期计算机视觉课程期末试卷,

    郑州升达大学2024-2025第一学期计算机视觉课程期末试卷,原版。配套教材为《OpenCV计算机视觉基础教程》夏帮贵主编。

    金工实习线上考试线切割课后试题.docx

    线切割课后试题

    网络原理课程设计【校园网规划】+思科模拟器,包含pkt文件及完整实验报告,附录含有源码

    目录 摘 要 1 一、设计任务概述 3 1.1 设计目的 3 1.2 项目任务和要求 3 1.3 参考资料 3 二、项目开发环境 4 三、项目需求分析 5 四、 项目设计和实现 5 4.1 总体设计 5 4.2 功能设计 6 4.3 系统实现 7 五、系统运行和测试 12 六、设计总结 15 七、附录 16 7.1 程序清单 16 7.2 其他需要说明的内容 23。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    智慧物联网系统发展战略研究

    智慧物联网系统发展战略研究

    基于springboot+vue的大创管理系统2(Java毕业设计,附源码,部署教程).zip

    该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven

    基于springboot+vue的网上点餐系统(Java毕业设计,附源码,部署教程).zip

    该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven

    直流电机的电枢回路串电阻启动的计算

    电机与拖动技术三级项目报告,直流电动机是电机的主要类型之一,具有调速范围广、调速特性平滑、过载能力强等优点,在生产生活中具有广泛的应用。此次课程项目阐述了直流电动机的结构、应用、并着重对电枢回路串电阻分级启动进行深入研究,MATLAB仿真软件对直流电动机分级启动进行仿真。

    Java Spring Boot实现基于URL + IP访问频率限制(源代码)

    详细说明:https://blog.csdn.net/a342874650/article/details/144989766 在 Web 应用中,恶意用户可能会通过频繁刷新接口或进行暴力请求来攻击系统,导致服务器负载过高或服务不可用。为了应对这一问题,本文将详细介绍如何使用 Spring Boot 结合拦截器(Interceptor)和 Redis 来实现基于 URL 和 IP 的访问频率限制。具体实现包括拦截器拦截请求、Redis 存储访问记录、检测访问频率并在达到限制时禁用 IP 的完整过程。通过本文的详细实现过程和完整源代码,读者可以快速掌握如何在自己的项目中应用这一机制来增强系统的安全性和稳定性。

    JavaEE核心技术:Web框架与持久层设计方案解析(主观题考试题库)

    内容概要:本文详细介绍了JavaEE核心技术,涵盖多个重要的Web框架和持久层技术,以及其应用场景和实施方案。具体内容包括:①Struts框架的特点和功能,特别是其对MVC架构的支持,以及如何应用于薪资管理系统;②MVC架构的基本概念和如何通过JSP、JavaBean及Servlet实现成绩管理系统;③Spring IoC容器的工作原理,强调其控制反转和依赖注入功能,展示了整合Struts和JPA的具体案例,如通讯管理系统Web层设计方案;④Spring MVC结构及其XML配置方法,并提出一种针对图书管理系统的Spring MVC实现思路;⑤深入探讨Spring AOP原理,介绍如何使用XML配置进行统一事务处理的应用方案;⑥分析Hibernate核心接口及设备管理系统持久层设计方案;⑦整合Hibernate和Spring IoC实现的成绩管理系统持久层设计方案。 适合人群:具备一定Java基础的初、中级JavaEE开发者,对JavaWeb开发有兴趣的学习者。 使用场景及目标:①帮助开发者理解JavaEE关键技术和框架的实际运用,提高项目开发技能;②指导实际项目的架构设计和技术选型;③促进团队协作,提高代码复用性和维护效率。 阅读建议:建议读者根据自身经验和兴趣选择重点章节仔细研读,并结合实际情况尝试实践,逐步掌握各知识点。此外,还应该结合最新的API文档和技术论坛资料不断跟进更新。

    easy-interceptor修改请求头和响应头.zip

    easy-interceptor修改请求头和响应头.zip

    Prime-Series-Level-1.z10

    Prime_Series_Level-1.z10 别下,这个是分卷压缩,笔者用来备份的

    基于springboot+vue的教师工作量管理系统(Java毕业设计,附源码,部署教程).zip

    该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven

    CST0402B+跟岗实习提交资料.zip

    CST0402B+跟岗实习提交资料.zip

    基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)

    基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目),个人大三大设计项目、经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为毕业设计、课程设计、期末大作业。 基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文档说明(高分项目)基于yolov5的医学影像肺结节检测项目源码+文

    循环法和对数法计算利息

    本金1W利息0.0325,几年能double?

    matlab机械臂关节空间轨迹规划,3-5-3分段多项式插值法,六自由度机械臂,该算法可运用到仿真建模机械臂上实时运动,可视化轨迹,有角度,速度,加速度仿真曲线 也可以有单独角度,速度,加速度仿真曲

    matlab机械臂关节空间轨迹规划,3-5-3分段多项式插值法,六自由度机械臂,该算法可运用到仿真建模机械臂上实时运动,可视化轨迹,有角度,速度,加速度仿真曲线。 也可以有单独角度,速度,加速度仿真曲线。 可自行更程序中机械臂与点的参数。 谢谢大家 (程序中均为弧度制参数)353混合多项式插值

    2011-2023年各省金融监管水平数据(含原始数据+计算过程+计算结果)

    2011-2023年各省金融监管水平数据(含原始数据+计算过程+计算结果) 1、时间:2011-2023年 2、来源:国家统计J、统计NJ 3、指标:金融业增加值、金融监管支出、金融监管水平 4、计算方法:金融监管水平=金融监管支出/金融业增加值

    简易手写汉字表.pdf

    本表名称为简易手写识字表,收录了21000多个汉字,每个汉字后面附上了简易手写笔画和输入编码。独体字是一个主笔画和一个字母编码,双码字是两个主笔画组合和两个字母编码,多码字是两个主笔画组合和三个字母编码。可用于识字、简易手写和大键盘汉字输入等参考。

Global site tag (gtag.js) - Google Analytics