mysql latid1_mysql觸發器的實戰經驗

1?? 引言

Mysql的觸發器和存儲過程一樣,都是嵌入到mysql的一段程序。觸發器是mysql5新增的功能,目前線上鳳巢系統、北斗系統以及哥倫布系統使用的數據庫均是mysql5.0.45版本,很多程序比如fc-star管理端,sfrd(das),dorado都會用到觸發器程序,實現對于數據庫增、刪、改引起事件的關聯操作。本文介紹了觸發器的類型和基本使用方法,講述了觸發器使用中容易產生的誤區,從mysql源碼中得到觸發器執行順序的結論,本文最后是實戰遭遇的觸發器經典案例。沒有特殊說明時,本文的實驗均基于mysql5.0.45版本。

2?? Mysql觸發器的類型

2.1?? Mysql觸發器的基本使用

創建觸發器。創建觸發器語法如下:

CREATE TRIGGER trigger_name trigger_time trigger_event

ON tbl_name FOR EACH ROW trigger_stmt

其中trigger_name標識觸發器名稱,用戶自行指定;

trigger_time標識觸發時機,用before和after替換;

trigger_event標識觸發事件,用insert,update和delete替換;

tbl_name標識建立觸發器的表名,即在哪張表上建立觸發器;

trigger_stmt是觸發器程序體;觸發器程序可以使用begin和end作為開始和結束,中間包含多條語句;

下面給出sfrd一個觸發器實例:

CREATE /*!50017 DEFINER = 'root'@'localhost' */ TRIGGER trig_useracct_update

AFTER UPDATE

ON SF_User.useracct FOR EACH ROW

BEGIN

IF OLD.ulevelid = 10101 OR OLD.ulevelid = 10104 THEN

IF NEW.ulevelid = 10101 OR NEW.ulevelid = 10104 THEN

if NEW.ustatid != OLD.ustatid OR NEW.exbudget != OLD.exbudget THEN

INSERT into FC_Output.fcevent set type = 2, tabid = 1, level = 1, userid = NEW.userid, ustatid = NEW.ustatid, exbudget = NEW.exbudget;

end if;

ELSE

INSERT into FC_Output.fcevent set type = 1, tabid = 1, level = 1, userid = NEW.userid, ustatid = NEW.ustatid, exbudget = NEW.exbudget;

END IF;

END IF;

END;

上述觸發器實例使用了OLD關鍵字和NEW關鍵字。OLD和NEW可以引用觸發器所在表的某一列,在上述實例中,OLD.ulevelid表示表 SF_User.useracct修改之前ulevelid列的值,NEW.ulevelid表示表SF_User.useracct修改之后 ulevelid列的值。另外,如果是insert型觸發器,NEW.ulevelid也表示表SF_User.useracct新增行的 ulevelid列值;如果是delete型觸發器OLD.ulevelid也表示表SF_User.useracct刪除行的ulevelid列原值。

另外,OLD列是只讀的,NEW列則可以在觸發器程序中再次賦值。

上述實例也使用了IF,THEN ,ELSE,END IF等關鍵字。在觸發器程序體中,在beigin和end之間,可以使用順序,判斷,循環等語句,實現一般程序需要的邏輯功能。

查看觸發器。查看觸發器語法如下,如果知道觸發器所在數據庫,以及觸發器名稱等具體信息:

SHOW TRIGGERS from SF_User like "usermaps%";

//查看SF_User庫上名稱和usermaps%匹配的觸發器

如果不了解觸發器的具體的信息,或者需要查看數據庫上所有觸發器,如下:

SHOW TRIGGERS;

//查看所有觸發器

用上述方式查看觸發器可以看到數據庫的所有觸發器,不過如果一個庫上的觸發器太多,由于會刷屏,可能沒有辦法查看所有觸發器程序。這時,可以采用如下方式:

Mysql中有一個information_schema.TRIGGERS表,存儲所有庫中的所有觸發器,desc information_schema. TRIGGERS,可以看到表結構:

+----------------------------+--------------+------+-----+---------+-------+

| Field????????????????????? | Type???????? | Null | Key | Default | Extra |

+----------------------------+--------------+------+-----+---------+-------+

| TRIGGER_CATALOG??????????? | varchar(512) | YES |???? | NULL??? |?????? |

| TRIGGER_SCHEMA???????????? | varchar(64) | NO?? |???? |???????? |?????? |

| TRIGGER_NAME?????????????? | varchar(64) | NO?? |???? |???????? |?????? |

| EVENT_MANIPULATION???????? | varchar(6)?? | NO?? |???? |???????? |?????? |

| EVENT_OBJECT_CATALOG?????? | varchar(512) | YES |???? | NULL??? |?????? |

| EVENT_OBJECT_SCHEMA??????? | varchar(64) | NO?? |???? |???????? |?????? |

| EVENT_OBJECT_TABLE???????? | varchar(64) | NO?? |???? |???????? |?????? |

| ACTION_ORDER?????????????? | bigint(4)??? | NO?? |???? | 0?????? |?????? |

| ACTION_CONDITION?????????? | longtext???? | YES |???? | NULL??? |?????? |

| ACTION_STATEMENT?????????? | longtext???? | NO?? |???? |???????? |?????? |

| ACTION_ORIENTATION???????? | varchar(9)?? | NO?? |???? |???????? |?????? |

| ACTION_TIMING????????????? | varchar(6)?? | NO?? |???? |???????? |?????? |

| ACTION_REFERENCE_OLD_TABLE | varchar(64) | YES |???? | NULL??? |?????? |

| ACTION_REFERENCE_NEW_TABLE | varchar(64) | YES |???? | NULL??? |?????? |

| ACTION_REFERENCE_OLD_ROW?? | varchar(3)?? | NO?? |???? |???????? |?????? |

| ACTION_REFERENCE_NEW_ROW?? | varchar(3)?? | NO?? |???? |???????? |?????? |

| CREATED??????????????????? | datetime???? | YES |???? | NULL??? |?????? |

| SQL_MODE?????????????????? | longtext???? | NO?? |???? |???????? |?????? |

| DEFINER??????????????????? | longtext???? | NO?? |???? |???????? |?????? |

+----------------------------+--------------+------+-----+---------+-------+

這樣,用戶就可以按照自己的需要,查看觸發器,比如使用如下語句查看上述觸發器:

select * from information_schema. TRIGGERS where TRIGGER_NAME= 'trig_useracct_update'\G;

刪除觸發器。刪除觸發器語法如下:

DROP TRIGGER [schema_name.]trigger_name

2.2?? Msyql觸發器的trigger_time和trigger_event

現在,重新注意到trigger_time和trigger_event,上文說過, trigger_time可以用before和after替換,表示觸發器程序的執行在sql執行的前還是后;trigger_event可以用 insert,update,delete替換,表示觸發器程序在什么類型的sql下會被觸發。

在一個表上最多建立6個觸發器,即1)before insert型,2)before update型,3)before delete型,4)after insert型,5)after update型,6)after delete型。

觸發器的一個限制是不能同時在一個表上建立2個相同類型的觸發器。這個限制的一個來源是觸發器程序體的“begin和end之間允許運行多個語句”(摘自mysql使用手冊)。

另外還有一點需要注意,msyql除了對insert,update,delete基本操作進行定義外,還定義了load data和replace語句,而load data和replace語句也能引起上述6中類型的觸發器的觸發。

Load data語句用于將一個文件裝入到一個數據表中,相當與一系列insert操作。replace語句一般來說和insert語句很像,只是在表中有 primary key和unique索引時,如果插入的數據和原來primary key和unique索引一致時,會先刪除原來的數據,然后增加一條新數據;也就是說,一條replace sql有時候等價于一條insert sql,有時候等價于一條delete sql加上一條insert sql。即是:

??? Insert型觸發器:可能通過insert語句,load data語句,replace語句觸發;

??? Update型觸發器:可能通過update語句觸發;

??? Delete型觸發器:可能通過delete語句,replace語句觸發;

3?? Mysql觸發器的執行順序

先拋出觸發器相關的幾個問題

3.1?? 如果before類型的觸發器程序執行失敗,sql會執行成功嗎?

實驗如下:

1)在FC_Word.planinfo中建立before觸發器:

DELIMITER |

create trigger trigger_before_planinfo_update

before update

ON FC_Word.planinfo FOR EACH ROW

BEGIN

insert into FC_Output.abc (planid) values (New.planid);

END

|

2)查看:mysql> select showprob from planinfo where planid=1;

+----------+

| showprob |

+----------+

|??????? 2 |

+----------+

3)執行sql:

update planinfo set showprob=200 where planid=1;

觸發觸發器程序;

4)由于不存在FC_Output.abc,before觸發器執行失敗,提示:

ERROR 1146 (42S02): Table 'FC_Output.abc' doesn't exist

5)再次查看:

mysql> select showprob from planinfo where planid=1;

+----------+

| showprob |

+----------+

|??????? 2 |

+----------+

即修改sql未執行成功。即如果before觸發器執行失敗,sql也會執行失敗。

3.2?? 如果sql執行失敗,會執行after類型的觸發器程序嗎?

實驗如下:

1)在FC_Word.planinfo中建立after觸發器:

DELIMITER |

create trigger trigger_after_planinfo_update

after update

ON FC_Word.planinfo FOR EACH ROW

BEGIN

INSERT INTO FC_Output.fcevent set level = 2, type = 2, tabid = 5, userid = NEW.userid, planid = NEW.planid, planstat2 = NEW.planstat2, showprob = NEW.showprob, showrate = NEW.showrate, showfactor = NEW.showfactor, planmode = NEW.planmode;

END

|

2)查看觸發表:

mysql> select * from FC_Output.fcevent where planid=1;

Empty set (0.00 sec)

沒有planid=1的記錄

3)執行sql:

mysql> update planinfo set showprob1=200 where planid=1;

4)由于不存在showprob1列,提示錯誤:

ERROR 1054 (42S22): Unknown column 'showprob1' in 'field list'

5)再次查看觸發表:

mysql> select * from FC_Output.fcevent where planid=1;

Empty set (0.00 sec)

觸發表中沒有planid=1的記錄,sql在執行失敗時,after型觸發器不會執行。

3.3?? 如果after類型的觸發器程序執行失敗,sql會回滾嗎?

實驗如下:

1)在FC_Word.planinfo中建立after觸發器:

DELIMITER |

create trigger trigger_after_planinfo_update

after update

ON FC_Word.planinfo FOR EACH ROW

BEGIN

insert into FC_Output.abc (planid) values (New.planid);

END

|

2)查看:mysql> select showprob from planinfo where planid=1;

+----------+

| showprob |

+----------+

|??????? 2 |

+----------+

3)執行sql:

update planinfo set showprob=200 where planid=1;觸發觸發器程序;

4)由于不存在FC_Output.abc,after觸發器執行失敗,提示:

ERROR 1146 (42S02): Table 'FC_Output.abc' doesn't exist

5)再次查看:

mysql> select showprob from planinfo where planid=1;

+----------+

| showprob |

+----------+

|??????? 2 |

+----------+

即修改sql未執行成功。即如果after觸發器執行失敗,sql會回滾。

這里需要說明一下,上述實驗所使用的mysql引擎是innodb,innodb引擎也是目前線上鳳巢系統、北斗系統以及哥倫布系統所使用的引擎,在 innodb上所建立的表是事務性表,也就是事務安全的。“對于事務性表,如果觸發程序失敗(以及由此導致的整個語句的失敗),該語句所執行的所有更改將回滾。對于非事務性表,不能執行這類回滾”(摘自mysql使用手冊)。因而,即使語句失敗,失敗之前所作的任何更改依然有效,也就是說,對于 innodb引擎上的數據表,如果觸發器中的sql或引發觸發器的sql執行失效,則事務回滾,所有操作會失效。

3.4?? mysql觸發器程序執行的順序

當一個表既有before類型的觸發器,又有after類型的觸發器時;當一條sql語句涉及多個表的update時,sql、觸發器的執行順序經過mysql源碼包裝過,有時比較復雜。

可以先看一段mysql的源代碼,當SQL中update多表的時候,Mysql的執行過程如下(省去了無關代碼):

/* 遍歷要更新的所有表 */

for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)

{

org_updated = updated

/* 如果有 BEFORE 觸發器,則執行;如果執行失敗,跳到err2位置 */

if (table->triggers &&

table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,TRG_ACTION_BEFORE, TRUE))

goto err2;

/*執行更新,如果更新失敗,跳到err位置*/

if(local_error=table->file->update_row(table->record[1], table->record[0])))

goto err;

updated++; // 更新計數器

/* 如果有 AFTER 觸發器,則執行;如果執行失敗,跳到err2位置*/

if (table->triggers &&

table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))

goto err2;

err:

{

/*標志錯誤信息,寫日志等*/

}

err2:

{

/*恢復執行過的操作*/

check_opt_it.rewind();

/*如果執行了更新,且表是有事務的,做標志*/

if (updated != org_updated)

{

if (table->file->has_transactions())

transactional_tables= 1;

}

}

}

從上面代碼可以找到本章開始時拋出問題的答案。

1)?? 如果before型觸發器執行失敗,直接goto跳到err2位置,不會執行后續sql語句;

2)?? 如果sql執行失敗,直接goto跳到err位置,不會執行或許的after型觸發器;

3)?? 如過after觸發器執行失敗,goto到err2位置,恢復執行過的操作,且在事務型的表上做標記。

另外,在使用復雜的sql時,由于有些復雜的sql是mysql自己定義的,所以存在不確定性,使用簡單的sql比較可控。

4?? Mysql觸發器在數據庫同步中的表現

4.1?? 觸發器運行失敗時,數據庫同步會失敗嗎?

有同步關系如下dbA?dbB。初始時同步正常。

1)在dbB上建立觸發器:

DELIMITER |

create trigger trigger_after_planinfo_update

after update

ON FC_Word.planinfo FOR EACH ROW

BEGIN

insert into FC_Output.abc (planid) values (New.planid);

END

|

2)在dbA上執行sql,執行成功;

mysql>

update planinfo set showprob=200 where planid= 1;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

3)由于dbB上沒有FC_Output.abc表,觸發器會執行失敗,這時,檢查一下同步狀態:

Slave_IO_Running: Yes

Slave_SQL_Running: NO

Last_Errno: 1146

Last_Error: Error 'Table 'FC_Output.abc' doesn't exist' on query. Default database: 'FC_Word'. Query: 'update planinfo set showprob=200 where planid= 1'

可以看到IO線程運行正常,sql線程運行失敗,并提示觸發器運行失敗的錯誤信息。

回憶一下3.1和3.3所述部分,無論是before部分的觸發器還是after類型的觸發器,對于innodb引擎,當觸發器執行失敗時,相應sql也會執行失敗,所以數據庫同步也會失敗。

4.2?? 創建、刪除觸發器寫bin-log

創建和刪除觸發器的語句也會寫入bin-log里,所以也會如一般的insert,update,delete語句一樣同步到下游數據庫中,即上游創建觸發器,下游也會創建。

這里再引出兩個小問題:有同步關系dbA?dbB,

1)?? 在dbA上創建一個觸發器,如果dbB上已經有同表同類型的觸發器,同步狀態如何?

2)?? 在dbB上刪除一個觸發器,如果dbB上沒有對應觸發器,同步狀態如何?

這兩個問題可以類比同步中的insert語句和delete語句,答案就是

1)?? 同步失敗,因為不允許重復創建同表同類型的觸發器;

2)?? 同步正常,因為drop一個不存在的觸發器,不影響運行結果;

5?? Mysql觸發器經典案例

5.1?? 案例1 一條sql涉及多個表的update時,觸發得到update之前的舊值

【現象】表test_info上建有觸發器如下:

CREATE /*!50017 DEFINER = 'root'@'localhost' */ TRIGGER trig_test_info_update

AFTER UPDATE

ON FC_Word.test_info FOR EACH ROW

BEGIN

DECLARE tlevel INTEGER DEFAULT 0;

DECLARE ttype INTEGER DEFAULT 0;

SET tlevel = 4;

SET ttype = 33;

INSERT INTO TEST_Output.fcevent (te, le, uid, pid, uid, wid, bi, mbid, wl) SELECT ttype, tlevel, NEW.uid, NEW.pid, NEW.uid, NEW.wid, NEW.bi, NEW.mbid, wl FROM TEST_Word.wext2 where wid = NEW.wid;

/*。。。其余部分邏輯省略*/

END IF;

END;

這個觸發器程序有點長,可以單看飄黃的兩句,即更新操作滿足第一個條件執行飄黃語句時,觸發器的行為。觸發器是建立在test_info表上的,飄黃語句中可以看到,也需要查詢wext2表。

執行如下sql1:

Update test_info a, wext2 b set a.th=(a.th+1), a.w4=(a.w4&8), b.wl=NULL where a.wid=b.wid and a.wid=142394379;

可以看到sql中既修改了test_info2表,同時修改了wext2表,程序原意是觸發得到wext2表wl字段修改后的新值(即NULL);不過實驗得到,執行上述sql后,觸發器程序查詢到的wurl是sql修改之前的舊值。

再執行下面類似sql2:

Update wext2 a, test_info2 b set b.th=(b.th+1), b.w4=(b.w4&8), a.wl=NULL where a.wid=b.wid and a.wid=142394379;

實驗的到,執行上述sql后,觸發器程序查詢到的wurl是sql修改之后的新值。

【原因】原因當然與sql中的別名a,b無關,而是和wext2表和test_info表的書寫順序有關。如本文3.4部分所述,一條sql涉及多個表的 update操作時,數據表字段、觸發器執行順序是mysql源碼包裝過的。在執行上述sql1時,先執行test_info的更新,然后是after觸發器,最后是wext2的更新,也就是說,在執行after觸發器時,wext2還沒有進行更新,所以觸發得到的是舊值。而執行sql2時,先執行 wext2更新,然后是test_info更新,最后是after觸發器,也就是說,在執行after觸發器時,wext2已經更新完畢,所以出去得到的是新值。

引起上述現象是順序關系的,無論該表是否支持事務。在使用復雜的sql時,由于有些復雜的sql是mysql自己定義的,所以存在不確定性,存在風險,使用簡單的sql比較可控。

5.2?? 案例2 mysql5.0.19版本修改表結構后觸發器失效

【現象】userpref表上建有after類型觸發器,修改userpref表的外鍵關聯后,在userpref表中的新增記錄沒有觸發下來,即觸發器失效。

【原因】mysql5.0.19修改表結構是,觸發器消失。這是mysql5.0.19的一個bug,在創建觸發器時,會把觸發器的內容保存在 information_schema.TRIGGERS表中,同時在var目錄下創建觸發器的數據庫目錄下創建一個觸發器名稱為前綴,以TRN為后綴的文件,當修改觸發器的表時,information_schema.TRIGGERS表的內容會刪除,導致觸發器消失。

在mysql5.0.45版本中,這個bug已經被修復。Mysql5.0.45版本的觸發器,無論是修改表的索引、外鍵,還是改變表字段,觸發器都不會失效。

5.3?? 案例3 刪除數據表后觸發器失效

【現象】聯調環境中存在dbA?dbB,主庫dbA上沒有觸發器,在從庫dbB上的FC_Word.wnegative表,FC_Word.wbuget 表上建有觸發器;觸發器開始運行正常,期間沒有對從庫的任何直接操作,有一日發現對wnegative表上的修改無法觸發。查看從庫狀態,同步正常;用 select TRIGGER_NAME from information_schema.TRIGGERS發現wnegative表上的觸發器消失了;在var/FC_Word目錄下也沒有 wnegative的.TRN文件,wnegative表上的觸發器不見了。

【分析】查找dbB的查詢日志,發現有一條:

100223 18:27:45 135939 Query?????? DROP TABLE IF EXISTS `wnegative`

135939 Query?????? CREATE TABLE `wnegative` (

KEY `Index_wnegative_planid` (`planid`),

KEY `Index_wnegative_unitid` (`unitid`)

135939 Query?????? /*!40000 ALTER TABLE `wnegative` DISABLE KEYS */

100223 18:27:46 135939 Query?????? INSERT INTO `wnegative` VALUES (614,1,289026,2911155,1848481);

可以看到,在100223 18:27:45時,刪除了表wnegative,緊接著有創建表wnegative;查找觸發表發現,在100223 18:27:45時間后對wnegative的修改就沒有觸發了,而在這個之前對wnegative的修改是觸發正常的。故,懷疑對wnegative表的刪除使wnegative表上的觸發器也被刪除。對wnegative表的刪除是在主庫dbA上操作后,被同步到dbB上。

【原因】在刪除wnegative表時,mysql同時刪除了wegative表上的觸發器。

可以通過下面實驗證明上述猜測:

1)?? 首先在wnegative建立after insert型觸發器;

2)?? 增加一條wnegative中記錄;

3)?? 查看結果發現觸發器正確觸發;

4)?? 刪除wnegative表;

5)?? 使用select TRIGGER_NAME from information_schema.TRIGGERS查看所有觸發器,wnegative表上觸發器已經不存在了;同時到var/FC_Word目錄下,對應觸發器的.TRN文件也不存在了;

6)?? 重新創建wnegative表,并增加一條wnegative中記錄;沒有了wnegative表上觸發器,自然也不能觸發任何結果。

6?? 結束語

Mysql中的觸發器功能已經在鳳巢系統的各個模塊中有廣泛應用,究其細節,還有很多值得注意的地方;本文建立在實驗和案例的基礎上,數據庫基于線上系統使用的mysql5.0.45版本,分析了觸發器相關的一些特殊情況下msyql的處理方式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534489.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534489.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534489.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql數據庫sql注入原理_SQL注入原理解析以及舉例1

sql注入是指web應用程序對用戶輸入數據的合法性沒有判斷,導致攻擊者可以構造不同的sql語句來實現對數據庫的操作。sql注入漏洞產生滿足條件:1;用戶能夠控制數據的輸入。2;原本需要執行的代碼,拼接了用戶的輸入。舉例&a…

mysql存儲map數據結構_map數據結構

Go map實現原理 - 戀戀美食的個人空間 - OSCHINA - 中文開源技術交流社區 https://my.oschina.net/renhc/blog/2208417// A header for a Go map.type hmap struct {// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.// Make sure this…

四因素三水平正交表_做論文要用正交表?我打包送給你

正交試驗目前在國內的應用量仍然是比較高的,許多高校畢業生喜歡利用正交試驗來獲取研究數據,最終完成畢業論文的撰寫或者期刊投稿。正交試驗方案的設計,必然要用到(標準)正交表。那么大家都是從哪里獲取正交表的呢?小兵給這方面的…

plsql視圖添加表字段_Oracle-單表多字段查詢(不使用*)

環境:Oracle 11g,plsql 14目的:不使用*,查詢擁有上百個字段的表的所有字段。懶人大法:在文章末尾。sql實現邏輯:1、首先建一張100個字段以上的表,通過excel的方式將表建好后直接復制粘貼到plsql的建表界面。…

mysql 編譯安裝與rpm安裝的區別_編譯安裝與RPM安裝的區別

建議在安裝線上的生產服務器軟件包時都用源碼安裝,這是因為源碼安裝可以自行調整編譯參數,最大化地定制安裝結果。這里以MySQL 5線上環境的編譯安裝來說明之,其編譯參數如下所示:./configure-prefix/usr/local/mysql -without-deb…

python字符串變量s的值是python網絡爬蟲_【Python爬蟲作業】-字符串

一、定義字符串變量1.請定義三個字符串a,b,c值分別為 I,like, python2.請將上面三個變量合并輸出I like pythonaIblikecpythonprint(a)print(b)print(c)print(a,b,c)二、定義一個變量 s sdghHhf 1.請先將變量s的空白符去掉 賦值給新變量s1 打印輸出2.請分別將s1變為全部大寫(命…

lableimg閃退_CV學習筆記(二十五):數據集標注與制作

最近在做一些數據標注的工作,雖然標注數據比較枯燥,但這也是每個做算法的工程師升級打怪的必由之路。使用一些合適的工具往往可以事半功倍,效率UP。一:數據標注流程二:數據處理的一些小代碼1:重命名當得到這…

mysql show profile詳解_SQL 性能分析利器 show profile

本文首發個人公眾號《andyqian》, 期待你的關注~前言在之前的文章中,我們提到過一些慢SQL優化的步驟。其中就包括:使用 explain 關鍵字來查看執行計劃,是否命中索引。通過計算某列的區分度,來判斷該列是否適合新建索引…

php判斷給定的整數是否是2的冪_C++_C語言判斷一個數是否是2的冪次方或4的冪次方,快速判斷一個數是否是2的冪次 - phpStudy...

C語言判斷一個數是否是2的冪次方或4的冪次方快速判斷一個數是否是2的冪次方,若是,并判斷出來是多少次方!將2的冪次方寫成二進制形式后,很容易就會發現有一個特點:二進制中只有一個1,并且1后面跟了n個0&…

python 包編譯安裝mysql_CentOS7編譯安裝MySQL8.0.23和Python3.1.9

卸載mariadbrpm -qa | grep mariadbmariadb-libs-5.5.64-1.el7.x86_64yum remove mariadb-libs.x86_64 -y安裝高版本GCC,解決編譯中會遇到的GCC 5.3 or newer is required (-dumpversion says 4.8.5)cd /optyum install centos-release-scl -yyum install devtoolse…

python3.0下載用什么瀏覽器_無法讓Python下載網頁源代碼:“不支持瀏覽器版本”...

查看您列出的url,我執行了以下操作:使用wget下載了頁面將urllib與ipython一起使用并下載了頁面使用chrome,只保存了url所有3個都給了我相同的結果文件(相同的大小,相同的內容)。在這可能是因為我沒有登錄,但我確實看到…

java線程堆棧_深入JVM剖析Java的線程堆棧

在這篇文章里我將教會你如何分析JVM的線程堆棧以及如何從堆棧信息中找出問題的根因。在我看來線程堆棧分析技術是Java EE產品支持工程師所必須掌握的一門技術。在線程堆棧中存儲的信息,通常遠超出你的想象,我們可以在工作中善加利用這些信息。我的目標是…

java 文件下載方法_【工具類】Java后臺上傳下載文件的幾種方式

/*** 將本地照片上傳至騰訊云服務上*/public void uploadImage(String localImagePath) throws Exception {// 1.將訂單照片上傳至騰訊地圖眾包側提供的云服務上try {File imageFile new File(localImagePath);if (imageFile.exists()) {String url "http://" map…

java io流讀取txt文件_Java使用IO流讀取TXT文件

通過BufferedReader讀取TXT文件window系統默認的編碼是GBK,而IDE的編碼多數為UTF-8,如果沒有規定new InputStreamReader(new FileInputStream(file),“GBK”)為GBK會出現讀取內容亂碼。//文件路徑String filePath"C:/Users/Admin/Desktop/products.…

c 調用java程序_C ++可以調用Java代碼嗎?

小編典典是的,您當然可以。這是一個例子:這是java文件:public class InvocationHelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");System.out.println("Arguments sent to this pro…

java 大數類_Java大數類介紹

java能處理大數的類有兩個高精度大整數BigInteger和高精度浮點數BigDecimal,這兩個類位于java.math包內,要使用它們必須在類前面引用該包:importjava.math.BigInteger;和importjava.math.BigDecimal;或者importjava.math.*;以下從幾個方面對B…

java 畫樹_java – 如何繪制代表連接節點圖的樹?

我想在Java GUI中顯示樹,但我不知道如何.樹代表連接節點的圖形,如下所示:我應該說我有自己的樹類:public class BinaryTree{private BinaryNode root;public BinaryTree( ){root null;}public BinaryTree( Object rootItem ){root new BinaryNode( roo…

mysql 優化代碼_MySQL Order by 語句優化代碼詳解

Order by語句是用來排序的,經常我們會使用到Order by來進行排序,下面我給大家來講講Order by用法與優化排序,有需要的同學可參考MySQL Order By keyword是用來給記錄中的數據進行分類的。MySQL Order By Keyword根據關鍵詞分類ORDER BY keywo…

java.lang.class_關于Java.lang.Class的一些疑問

User.class可以在編譯時就確定下來Class的泛型,而new User().getClass()實際上是運行時才能確定下來實際是什么泛型。舉個例子:public class User{}public class Student extends User{public static void main(String[] args) {User user1 new User();…

java文件 linux_Linux執行Java文件

最近學習shell腳本,寫個簡單java類讓linux去執行java類沒別的東西,就引了一個fastjson的jar,寫了個main方法 序列化一個User對象 打印package com.lws.demo;import java.util.Date;import com.alibaba.fastjson.JSONObject;import com.lws.mo…