KingbaseES函数三态
- 理解函数的三态1 - VOLATILE: - volatile函数没有限制,可以修改数据(如执行delete,insert,update), 使用同样的参数调用可能返回不同的值.
 - STABLE: - 不允许修改数据, PG8.0以及以上版本不允许在volatile函数中使用非SELECT|PERFORM语句.
 使用同样的参数调用返回同样的结果,在事务中有这个特性的也归属stable.
 - IMMUTABLE: - 不允许修改数据, 使用同样的参数调用返回同样的结果.
 - 备注:Pg 8.0以及以上版本不允许在stable或immutable函数中执行非select|perform语句. - 示例: - test=# create table tbl(id int primary key, info text, crt_time timestamp);
 CREATE TABLE
 test=# create or replace function f_tbl(i_id int) returns void as $$
 test$# declare
 test$# begin
 test$# update tbl set crt_time=now() where id=i_id;
 test$# end;
 test$# $$ language plpgsql stable;
 CREATE FUNCTION
 test=# \set VERBOSITY verbose
 test=# select f_tbl(1);
 ERROR: 0A000: UPDATE is not allowed in a non-volatile function
 背景: SQL statement "update tbl set crt_time=now() where id=i_id"
 PL/pgSQL function f_tbl(integer) line 4 at SQL statement
 位置: _SPI_execute_plan_internal, spi.c:2951
 - 漏洞:在stable或immutable函数中调用volatile函数是可以的. - 示例: - test=# alter function f_tbl(int) volatile;
 ALTER FUNCTION
 test=# create or replace function f_tbl1(i_id int) returns void as $$
 test$# declare
 test$# begin
 test$# perform f_tbl(i_id); -- 在stable或immutable函数中调用volatile函数是可以的.
 test$# end;
 test$# $$ language plpgsql stable;
 CREATE FUNCTION
 test=#
 test=# insert into tbl values(1,'test',now());
 INSERT 0 1
 test=# select * from tbl;
 id | info | crt_time
 ----+------+----------------------------
 1 | test | 2022-11-10 11:46:05.854350
 (1 行记录) test=# select f_tbl1(1);
 f_tbl1
 -------- (1 行记录) test=# select * from tbl;
 id | info | crt_time
 ----+------+----------------------------
 1 | test | 2022-11-10 11:46:33.153699
 (1 行记录)
 - 同样的参数多次调用. - volatile 函数相同的参数,多次调用返回结果可能不一样. - kbstattuple扩展插件可以参考KingbaseES在线手册
 https://help.kingbase.com.cn/v8/development/sql-plsql/ref-extended-plug-in/kbstattuple.html?highlight=kbstattuple test=# create extension kbstattuple ;
 CREATE EXTENSION
 test=# \dx+ kbstattuple ;
 对象用于扩展 "kbstattuple"
 对象描述
 ---------------------------------------
 function pg_relpages(regclass)
 function pg_relpages(text)
 function pgstatginindex(regclass)
 function pgstathashindex(regclass)
 function pgstatindex(regclass)
 function pgstatindex(text)
 function pgstattuple_approx(regclass)
 function pgstattuple(regclass)
 function pgstattuple(text)
 (9 行记录) test=# create table t2(id int);
 CREATE TABLE
 test=# select pg_relpages('t2');
 pg_relpages
 -------------
 0
 (1 行记录) test=# insert into t2 values (1);
 INSERT 0 1
 test=# select pg_relpages('t2'); -- 返回值变化
 pg_relpages
 -------------
 1
 (1 行记录) test=# select proname,provolatile from pg_proc where proname='pg_relpages';
 proname | provolatile
 -------------+-------------
 pg_relpages | v
 pg_relpages | v
 (2 行记录)
 - stable, immutable函数同样的参数多次调用返回结果不变. - 在事务中多次调用返回结果一致的也可归属于stable. - test=# select now();
 now
 -------------------------------
 2022-11-10 13:42:35.689740+08
 (1 行记录) test=# select now();
 now
 -------------------------------
 2022-11-10 13:42:36.756038+08
 (1 行记录) test=# begin;
 BEGIN
 test=# select now();
 now
 -------------------------------
 2022-11-10 13:42:39.037893+08
 (1 行记录) test=# select now();
 now
 -------------------------------
 2022-11-10 13:42:39.037893+08
 (1 行记录) test=# select provolatile,proname,proargtypes from pg_proc where proname='now';
 provolatile | proname | proargtypes
 -------------+---------+-------------
 s | now |
 (1 行记录) test=# select now();
 now
 -------------------------------
 2022-11-10 13:42:39.037893+08
 (1 行记录) test=# end;
 COMMIT
 test=# select now();
 now
 -------------------------------
 2022-11-10 13:43:31.772061+08
 (1 行记录)
 - immutable函数同stable, 同样的参数多次调用结果一致. - test=# select proname,provolatile from pg_proc where proname='abs';
 proname | provolatile
 ---------+-------------
 abs | i
 abs | i
 abs | i
 abs | i
 abs | i
 abs | i
 abs | i
 (7 行记录) test=# select abs(-10);
 abs
 -----
 10
 (1 行记录) test=# select abs(-10);
 abs
 -----
 10
 (1 行记录) test=# begin;
 BEGIN
 test=# select abs(-10);
 abs
 -----
 10
 (1 行记录) test=# select abs(-10);
 abs
 -----
 10
 (1 行记录) test=# end;
 COMMIT
 test=# select abs(-10);
 abs
 -----
 10
 (1 行记录)
 
- VOLATILE/STABLE/IMMUTABLE区别: 
VOLATILE
	volatile函数不能被优化器作为优化条件.
		1)例如单SQL处理多行时不能减少volatile函数的调用次数,
		2)不能使用volatile函数创建函数索引,
		3)在过滤条件中使用volatile函数时, 不能走索引扫描.
	在同一个查询中, 同样参数的情况下可能被多次执行(QUERY有多行返回/扫描的情况下).
STABLE
	1)优化器可根据实际场景优化stable函数的调用次数, 同样的参数多次调用可能减少成单次调用.
	2)stable函数可以用于优化器选择合适的索引扫描, 因为索引扫描仅评估被比较的值一次, 后多次比较.
	3)stable和volatile函数都不能用于创建函数索引, 只有immutable函数可以用于创建函数索引.
IMMUTABLE
	优化器在处理immutable函数时, 先评估函数结果, 将结果替换为常量.
- 理解函数的三态2 - test=# create table t3(id int);
 CREATE TABLE
 test=# insert into t3 values(1),(1),(1),(2),(2),(2);
 INSERT 0 6
 test=#
 test=# create or replace function f_t3(id int) returns int as $$
 test$# declare
 test$# begin
 test$# raise notice 'Called.';
 test$# return id;
 test$# end;
 test$# $$ language plpgsql stable; -- stable 状态
 CREATE FUNCTION
 test=# select * from t3 where f_t3(id) =1;
 -- f_t3(id) --这里id是变量,不能被优化器优化,因此函数调用了6次.
 test=# select * from t3 where f_t3(id) =1;
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 id
 ----
 1
 1
 1
 (3 行记录) select * from t3 where f_t3(1) =1;
 -- 这里使用常量调用f_t3()所以可以被优化器优化.
 test=# select * from t3 where f_t3(1) =1;
 NOTICE: 00000: Called. -- 函数只被调用一次
 位置: exec_stmt_raise, pl_exec.c:3908
 id
 ----
 1
 1
 1
 2
 2
 2
 (6 行记录) 把函数改成volatile后, 函数不能被优化. test=# alter function f_t3(int) volatile;
 ALTER FUNCTION
 test=# select proname,provolatile from pg_proc where proname='f_t3';
 proname | provolatile
 ---------+-------------
 f_t3 | v
 (1 行记录) test=# select * from t3 where f_t3(1) =1;
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 NOTICE: 00000: Called.
 位置: exec_stmt_raise, pl_exec.c:3908
 id
 ----
 1
 1
 1
 2
 2
 2
 (6 行记录)
 
根据函数的实际情况设置稳定态, 可以达到优化效果.
例如f_t3函数调用一次耗时1秒, 并且是stable的状态,以上例子可以减少5秒的查询时间.使用volatile态则需要6秒.
优化器在处理immutable函数时,先评估函数结果,将结果替换为常量.
	test=# explain select * from t2 where id>abs(-1);
                     QUERY PLAN
	-----------------------------------------------------
	 Seq Scan on t2  (cost=0.00..41.75 rows=847 width=4)
	   Filter: (id > 1)
	(2 行记录)
	因为abs(int)是immutable函数,这里abs(-1)替换成常量1.
如果把函数改成stable, 那么将不会替换成常量.
	test=# alter function abs(int) stable;
	ALTER FUNCTION
	test=# select proname,provolatile from pg_proc where proname='abs';
	 proname | provolatile
	---------+-------------
	 abs     | i
	 abs     | i
	 abs     | i
	 abs     | i
	 abs     | i
	 abs     | s
	 abs     | i
	(7 行记录)
	test=# explain select * from t2 where id>abs(-1);
	                     QUERY PLAN
	-----------------------------------------------------
	 Seq Scan on t2  (cost=0.00..48.10 rows=847 width=4)
	   Filter: (id > abs('-1'::integer))
	(2 行记录)
	由于abs(int)被改成stable了, 将不会替换成常量
在prepared statement中使用需要注意区别. 后面会有例子.
只有immutable函数可以创建函数索引.
	test=# create table t4(id int,info timestamp(0));
	CREATE TABLE
	test=# \set VERBOSITY verbose
	test=# create index idx_t4_1 on t4(to_char(info,'yyyymmdd'));
	ERROR:  42P17: functions in index expression must be marked IMMUTABLE
	位置:  ComputeIndexAttrs, indexcmds.c:1940
	test=# create table t5(id int primary key, info text);
	CREATE TABLE
	test=# insert into t5 select generate_series(1,100000),md5(random()::text);
	INSERT 0 100000
	test=# alter function abs(int) volatile;
	ALTER FUNCTION
	test=# 
	test=# \d+ t4
	                                     数据表 "public.t4"
	 栏位 |              类型              | 校对规则 | 可空的 | 预设 | 存储  | 统计目标 | 描述
	------+--------------------------------+----------+--------+------+-------+----------+------
	 id   | integer                        |          |        |      | plain |          |
	 info | timestamp(0) without time zone |          |        |      | plain |          |
	访问方法 heap
	test=# \d+ t5
	                            数据表 "public.t5"
	 栏位 |  类型   | 校对规则 |  可空的  | 预设 |   存储   | 统计目标 | 描述
	------+---------+----------+----------+------+----------+----------+------
	 id   | integer |          | not null |      | plain    |          |
	 info | text    |          |          |      | extended |          |
	索引:
	    "t5_pkey" PRIMARY KEY, btree (id)
	访问方法 heap
索引扫描时, 用于过滤条件的表达式只被评估一次后, 再与索引值进行比较判断是否满足条件.
	test=# explain select * from t5 where id<abs(10);
	                        QUERY PLAN
	----------------------------------------------------------
	 Seq Scan on t5  (cost=0.00..2341.00 rows=33333 width=37)
	   Filter: (id < abs(10))
	(2 行记录)
只有stable函数和immutable函数符合索引扫描的刚性需求.
	test=# alter function abs(int) stable;
	ALTER FUNCTION
	test=# explain select * from t5 where id<abs(-100);
	                             QUERY PLAN
	--------------------------------------------------------------------
	 Index Scan using t5_pkey on t5  (cost=0.29..9.99 rows=97 width=37)
	   Index Cond: (id < abs('-100'::integer))
	(2 行记录)
	test=# alter function abs(int) immutable;
	ALTER FUNCTION
	test=# explain select * from t5 where id<abs(-100);
	                             QUERY PLAN
	--------------------------------------------------------------------
	 Index Scan using t5_pkey on t5  (cost=0.29..9.99 rows=97 width=37)
	   Index Cond: (id < 100)
	(2 行记录)
 volatile函数同样的输入参数可能返回不同值,在一个查询中将被多次调用,不符合索引扫描规则.
 stable和immutable同样的参数返回值不变,因此可以作为索引扫描的比较值,优化器允许走索引扫描.
- 理解函数的三态3 - 函数内的每条查询语句的数据可见性: - VOLATILE - snapshot为函数内的每个query开始时的snapshot. 因此对外部已提交的数据时可见的.
 - STABLE - snapshot为外部调用函数的QUERY的snapshot, 函数内部始终保持这个snapshot.
 - IMMUTABLE - 同stable
 
测试:
	test=# create or replace function f_t6() returns void as $$
	test$# declare
	test$# r record;
	test$# begin
	test$# for i in 1..10 loop
	test$# for r in select * from t6  loop
	test$# raise notice 'loop:%,t6:%.',i,r;
	test$# end loop;
	test$# perform pg_sleep(5);
	test$# end loop;
	test$# end;
	test$# $$ language plpgsql volatile;
	CREATE FUNCTION
	test=# create table t6(id int,info text);
	CREATE TABLE
	--执行过程中,新建连接往t6表插入新数据,volatile函数察觉新增行
	test=# select f_t6();
	NOTICE:  loop:2,t6:(1,test).
	NOTICE:  loop:3,t6:(1,test).
	NOTICE:  loop:4,t6:(1,test).
	NOTICE:  loop:5,t6:(1,test).
	NOTICE:  loop:5,t6:(1,test1).
	NOTICE:  loop:6,t6:(1,test).
	NOTICE:  loop:6,t6:(1,test1).
	NOTICE:  loop:6,t6:(1,test3).
	NOTICE:  loop:7,t6:(1,test).
	NOTICE:  loop:7,t6:(1,test1).
	NOTICE:  loop:7,t6:(1,test3).
	NOTICE:  loop:7,t6:(1,test5).
	NOTICE:  loop:8,t6:(1,test).
	NOTICE:  loop:8,t6:(1,test1).
	NOTICE:  loop:8,t6:(1,test3).
	NOTICE:  loop:8,t6:(1,test5).
	NOTICE:  loop:9,t6:(1,test).
	NOTICE:  loop:9,t6:(1,test1).
	NOTICE:  loop:9,t6:(1,test3).
	NOTICE:  loop:9,t6:(1,test5).
	NOTICE:  loop:10,t6:(1,test).
	NOTICE:  loop:10,t6:(1,test1).
	NOTICE:  loop:10,t6:(1,test3).
	NOTICE:  loop:10,t6:(1,test5).
	NOTICE:  loop:10,t6:(1,hello).
	 f_t6
	------
	(1 行记录)
	test=# insert into t6 values(1,'test');
	INSERT 0 1
	test=# insert into t6 values(1,'test1');
	INSERT 0 1
	test=# insert into t6 values(1,'test3');
	INSERT 0 1
	test=# insert into t6 values(1,'test5');
	INSERT 0 1
	test=# insert into t6 values(1,'hello');
	INSERT 0 1
	test=# 
	--更改稳定态为 stable immutable
	test=# alter function f_t6() stable;
	ALTER FUNCTION
	test=# truncate table t6;
	TRUNCATE TABLE
	test=# select f_t6();
	 f_t6
	------
	(1 行记录)
	--f_t6()执行过程中对t6变更, 函数不感知.
	test=# insert into t6 values(1,'hello');
	INSERT 0 1
	test=# insert into t6 values(1,'test5');
	INSERT 0 1
	test=# insert into t6 values(1,'test3');
	INSERT 0 1
	test=# insert into t6 values(1,'test3');
	INSERT 0 1
	test=#
- 理解函数的三态4 - STABLE和IMMUTABLE的区别: - 在SELECT子句中,优化器对stable和immutable区别对待.
 - 测试: - test=# create table t7(id int);
 CREATE TABLE
 test=# insert into t7 values (1),(2),(3);
 INSERT 0 3
 test=# create or replace function f_t7(i int) returns int as $$
 test$# declare
 test$# begin
 test$# raise notice 'called';
 test$# return i;
 test$# end;
 test$# $$ language plpgsql stable;
 CREATE FUNCTION -- SELECT子句中, stable函数不被优化器优化
 test=# select f_t7(1),* from t7;
 NOTICE: called --多次调用
 NOTICE: called
 NOTICE: called
 f_t7 | id
 ------+----
 1 | 1
 1 | 2
 1 | 3
 (3 行记录) test=# alter function f_t7(int) immutable;
 ALTER FUNCTION -- immutable函数被替换成常量, 只执行一次.
 test=# select f_t7(1),* from t7;
 NOTICE: called --一次调用
 f_t7 | id
 ------+----
 1 | 1
 1 | 2
 1 | 3
 (3 行记录) --当函数为stable时, 优化器没有处理这种过滤条件, 理论上是可以优化为一次调用f_t7(1)的. 目前仅仅immutable被优化.
 test=# alter function f_t7(int) stable;
 ALTER FUNCTION 当使用索引扫描时, stable在这里只会执行一次. test=# select * from t7 where id=f_t7(1);
 NOTICE: called --有一次为explain的评估输出.
 NOTICE: called
 NOTICE: called
 NOTICE: called
 id
 ----
 1
 (1 行记录) -- 将id=f_t7(1)替换成f_t7(1)=1
 test=# select * from t7 where f_t7(1)=1;
 NOTICE: called
 id
 ----
 1
 2
 3
 (3 行记录) test=# explain select * from t7 where f_t7(1)=1;
 QUERY PLAN
 ------------------------------------------------------------
 Result (cost=0.25..35.65 rows=2540 width=4)
 One-Time Filter: (f_t7(1) = 1)
 -> Seq Scan on t7 (cost=0.25..35.65 rows=2540 width=4)
 (3 行记录) test=# alter function f_t7(int) immutable;
 ALTER FUNCTION
 test=# explain select * from t7 where f_t7(1)=1;
 NOTICE: called
 QUERY PLAN
 ------------------------------------------------------
 Seq Scan on t7 (cost=0.00..35.40 rows=2540 width=4)
 (1 行记录)
 
- 理解函数的三态 - VOLATILE - 1)volatile函数没有限制, 可以修改数据(如执行delete, insert , update).
 2)使用同样的参数调用可能返回不同的值.
 3)volatile函数不能被优化器选择作为优化条件.(例如减少调用, 函数索引, 索引扫描不允许使用volatile函数)
 4)在同一个查询中, 同样参数的情况下可能被多次执行(QUERY有多行返回/扫描的情况下).
 5)snapshot为函数内的每个query开始时的snapshot. 因此对在函数执行过程中, 外部已提交的数据可见.(仅限于调用函数的事务隔离级别为read committed)
 
STABLE
	1)stable和immutable函数, 函数内不允许修改数据.(如PGver>=8.0 函数内不可执行非SELECT|PERFORM语句.)
	2)使用同样的参数调用返回同样的结果, 在事务中有这个特性的也归属stable.
	3)优化器可根据实际场景优化stable函数的调用次数, 同样的参数多次调用可减少成单次调用.
	4)stable和immutable函数可用于优化器选择合适的索引扫描, 因为索引扫描仅评估被比较的表达式一次, 后多次与索引值进行比较.
	5)stable和volatile函数都不能用于创建函数索引, 只有immutable函数可以用于创建函数索引.
	6)stable和immutable函数, snapshot为外部调用函数的QUERY的snapshot, 函数内部始终保持这个snapshot, 外部会话带来的的数据变更不被反映到函数执行过程中.
IMMUTABLE
	1)不允许修改数据, 使用同样的参数调用返回同样的结果.
	2)优化器在处理immutable函数时, 先评估函数结果, 将结果替换为常量.
	3)因此使用约束优化查询的场景中也只识别immutable函数.
STABLE和IMMUTABLE的区别
	1)STABLE函数在SELECT和WHERE子句中不被优化, 仅仅当使用索引扫描时WHERE子句对应的STABLE函数才会被优化为1次调用.
	2)在PREPARED STATEMENT中的使用区别:
	3)IMMUTABLE函数在PLAN时以常量替代,STABLE函数在EXECUTE阶段被执行.
	4)因此IMMUTABLE函数参数为常量时,在PREPARED STATEMENT场景只执行一次,而STABLE函数被多次执行.
函数稳定性通过查看PG_PROC/SYS_PROC.PROVOLATILE得到
	PROVOLATILE 说明函数是仅仅只依赖 于它的输入参数 ,还是会被外部 因素影响。
	值 I 表示“不变的”函数,它对于相同的输入总是输出相同的结果。
	值 S 表示“稳定的”函数,它的结果(对于固定输入在一次扫描内不会变化。
	值 V 表示“不稳定的”函数,它的结果在任何时候都可能变化。
	使用V页表示函数具有副作用,所以对它们的调用无法得到优化。
KingbaseES函数三态的更多相关文章
- KingbaseES 函数稳定性与SQL性能
		背景:客户现场的一次艰苦的调优过程(https://www.cnblogs.com/kingbase/p/16015834.html),让我觉得非常有必要让数据库用户了解函数的不同稳定性属性,及其对于 ... 
- KingbaseES函数如何返回结果集
		函数返回值一般是某一类型值,如int,varchar,date等,返回结果集时就需要用到setof语法. 创建数据 create table class(id number primary key, ... 
- KingbaseES 与Oracle 函数稳定性对于性能影响差异比较
		一.函数的属性 KingbaseES 函数在定义时有三种稳定性级别:volatile.stable 和 immutable.默认情况下,创建函数的稳定性为volatile.以下是这三种函数的区别: V ... 
- KingbaseES时间函数的比较
		KingbaseES提供了多种的时间函数,这些函数在使用过程中存在哪些不同? **同一事务** test=# begin test-# for i in 1.. 10 loop test-# rais ... 
- KingbaseES 格式化函数
		KingbaseES格式化函数提供一套有效的工具用于把各种数据类型(日期/时间.integer.floating point和numeric)转换成格式化的字符串以及反过来从格式化的字符串转换成指定的 ... 
- KingbaseES 实现MYSQL hex/unhex 函数
		MySQL 的hex 和 unhex 函数类似于KingbaseES 的encode 和 decoding,实现字符与16进制之间的转换. 一.先看MySQL例子 mysql> select h ... 
- KingbaseES 行列转换函数
		关键字: 行专列,列转行, pivot, unpivot 行列转换是在数据分析中经常用到的一项功能,KingbaseES从V8R6C3B0071版本开始通过扩展插件(kdb_utils_func ... 
- KingbaseES sys_blocking_pids 函数
		会话出现了锁等待,想要快速查询到堵塞的会话,可以使用 sys_blocking_pids 函数来实现这一目的. sys_blocking_pids:获取哪些会话阻塞了某个会话(输入参数). sys_b ... 
- KingbaseES DENSE_RANK 函数用法
		DENSE_RANK()函数用于为结果集分区内的每一行分配一个排名,排名值之间没有差距,函数为结果集的每个分区中的每一行分配一个等级. 与 RANK() 函数不同的是,DENSE_RANK() 函数总 ... 
- KingbaseES 中可以通过构造一个聚集函数来实现mysql的any_value功能。
		示例 创建函数 create function coalesce_("anyelement","anyelement") returns "anyel ... 
随机推荐
- Pycharm系列---QT配置
			PYSIDE2 添加外部工具 file---settings External Tools,点击左上角的 加号+ designer 位置: envs\QT6\Lib\site-packages\PyS ... 
- 【Virt.Contest】CF1155(div.2)
			CF 传送门 T1:Reverse a Substring 只有本身单调不减的字符串不能转换为字典序更小的字符串.否则肯定会出现 \(s_i>s_{i+1}\) 的情况. 所以只要从头到尾扫一遍 ... 
- Python 学习思路 思维导图 Xmind
			如果需要,请在评论区留下邮箱,我看到后会一次发送. 
- vue3的学习笔记:MVC、Vue3概要、模板、数据绑定、用Vue3 + element ui、react框架实现购物车案例
			一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.Vue是框架而jQuery则是库. 1.2.MVC(Mo ... 
- K8S节点选择器案例
			#给节点打上标签 [root@lecode-k8s-master deployment]# kubectl label no lecode-dev-001 hostname=lecode-dev-00 ... 
- 3. qtdesinger的使用方法
			专栏地址 ʅ(‾◡◝)ʃ windows 上使用 qtdesigner 找到那个路径直接打开就行了 linux 上使用 qtdesigner 打开 qtcreator 软件 1. 启动软件,新建项目 ... 
- day25 前端
			https://www.dcloud.io/hbuilderx.html 下载HbuilderX,直接解压缩双击打开 html5 <!DOCTYPE html><!-- 文档类型,声 ... 
- Windows 10 读取bitlocker加密的硬盘出现参数错误怎么解决?
			我为了数据安全,用windows专业版的bitlocker加密了一个固态硬盘SSD做的移动硬盘(u盘同理),在家里电脑(windows10 家庭版)打开的时候出现了参数错误 即使密码输入正确还是这个错 ... 
- day28-jQuery01
			jQuery01 参考文档1:jQuery API 中文文档 | jQuery API 中文在线手册 | jquery api 下载 | jquery api chm (cuishifeng.cn) ... 
- 大前端html基础学习03-定位锚点透明
			一.position 定位属性和属性值position 定位属性,检索对象的定位方式:语法:position:static /absolute/relative/fixed/sticky/unset/ ... 
