No.2.測(cè)試MySQL表中安全刪除重復(fù)數(shù)據(jù)只保留一條的相關(guān)方法

第二篇文章測(cè)試說(shuō)明
開(kāi)發(fā)測(cè)試中,難免會(huì)存在一些重復(fù)行數(shù)據(jù),因此常常會(huì)造成一些測(cè)試異常.
下面簡(jiǎn)單測(cè)試mysql表刪除重復(fù)數(shù)據(jù)行的相關(guān)操作.
主要通過(guò)一下三個(gè)大標(biāo)題來(lái)測(cè)試說(shuō)明:
02.嘗試刪除dept_name重復(fù)的列
03 嘗試刪除多個(gè)字段(dept_name和db_source)都重復(fù)的字段!
04 是否可以使用兩重for循環(huán)來(lái)判斷是否存在重復(fù)行并進(jìn)行刪除!

數(shù)據(jù)庫(kù)的表不要隨便刪除,需要?jiǎng)h除部分?jǐn)?shù)據(jù)的話請(qǐng)事先備份成SQL,或者創(chuàng)建備份表.不然--
后端一時(shí)爽,運(yùn)維火葬場(chǎng).

01.建表

(隨手找來(lái)一個(gè)現(xiàn)成的表,直接拷貝出sql語(yǔ)句)
CREATE DATABASE IF NOT EXISTS cloudDB01;

USE clouddb01;

CREATE TABLE IF NOT EXISTS `dept` (
  `dept_no` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `dept_name` VARCHAR(60) DEFAULT NULL,
  `db_source` VARCHAR(60) DEFAULT NULL,
  PRIMARY KEY (`dept_no`)
) ENGINE=INNODB AUTO_INCREMENT=278 DEFAULT CHARSET=utf8;
 /*插入dept表一系列數(shù)據(jù)*/
insert  into `dept`(`dept_no`,`dept_name`,`db_source`) values 
(1,'開(kāi)發(fā)部','clouddb01'),
(2,'人事部','clouddb01'),
(3,'財(cái)務(wù)部','clouddb01'),
(4,'市場(chǎng)部','clouddb01'),
(5,'運(yùn)維部','clouddb01'),
(6,'\'喝茶醬油部\'','clouddb01'),
(21,'開(kāi)發(fā)部','clouddb01'),
(22,'人事部','clouddb01'),
(23,'財(cái)務(wù)部','clouddb01'),
(24,'市場(chǎng)部','clouddb01'),
(25,'運(yùn)維部','clouddb01'),
(26,'\'喝茶醬油部\'','clouddb01');

02.嘗試刪除dept_name重復(fù)的列

也就是說(shuō),一個(gè)部門(mén)名只用占一行就可以了,多行的話豈不是浪費(fèi)了!
  • 02.1.1.查詢(xún)存在dept_name存在重復(fù)的行
SELECT  d.dept_name
    FROM `dept` d
    GROUP BY d.`dept_name` 
    HAVING  COUNT(dept_name) > 1
  • 02.1.2.結(jié)果


    image.png
  • 02.2.1 把上面的表當(dāng)做子表查出重復(fù)的整個(gè)行
SELECT *
FROM `dept` 
WHERE `dept_name` IN
(
      SELECT  d.dept_name
    FROM `dept` d
    GROUP BY d.`dept_name` 
    HAVING  COUNT(dept_name) > 1    
);  
  • 02.2.2 結(jié)果 (其實(shí)這里恰好就是整個(gè)表了)


    image.png
  • 02.3.1 上面的結(jié)果是不行的,刪除時(shí)不能都刪了,我們?yōu)榱吮A粢粋€(gè)行,where條件需要再修改一下保留部門(mén)號(hào)(dept_no)最小的那行數(shù)據(jù)好了!
DELETE
FROM
  `dept`
WHERE `dept_name` IN

  (SELECT
    dept_name
  FROM
    `dept` 
  GROUP BY `dept_name`
  HAVING COUNT(dept_name) > 1)
  
  AND `dept_no` NOT IN 
  
  (SELECT
    MIN(dept_no)
  FROM
    `dept` 
  GROUP BY `dept_name`
  HAVING COUNT(dept_name) > 1);
  • 02.3.2 結(jié)果 : 執(zhí)行出現(xiàn)問(wèn)題;


    image.png
  • 02.3.3 那是什么原因呢?原因:筆者的數(shù)據(jù)庫(kù)安全模式較高,為REPEATABLE-READ(可重復(fù)讀)級(jí)別,此模式下可以解決臟讀 和 不可重復(fù)讀 (mysql默認(rèn)的);
    錯(cuò)誤代碼:1093,意思就是mysql不允許在查詢(xún)表的同時(shí)對(duì)這個(gè)表進(jìn)行刪除更新操作是不安全的.

    image.png
    • 02.3.4 那可怎么辦?除了降級(jí)以外還能怎么辦?
      Duang!!Duang!!Duang!!Duang!!
      再來(lái)一個(gè)副本表"dept2",同時(shí)還可以起到備份的作用! 創(chuàng)建的sql在最上面,都在dept后面加個(gè)2即可!


      dept2.png

-02.3.5 Show Time!是不是恍然大悟了!

DELETE
FROM
  `dept`
WHERE `dept_name` IN

  (SELECT
    dept_name
  FROM
    `dept2` 
  GROUP BY `dept_name`
  HAVING COUNT(dept_name) > 1)
  
  AND `dept_no` NOT IN 
  
  (SELECT
    MIN(dept_no)
  FROM
    `dept2` 
  GROUP BY `dept_name`
  HAVING COUNT(dept_name) > 1);

-02.3.6 回頭看,不曾走遠(yuǎn),dept表中dept_name重復(fù)的行已經(jīng)沒(méi)了!!


image.png

03 嘗試刪除多個(gè)字段(dept_name和db_source)都重復(fù)的字段!

目的也就是一個(gè)部門(mén)實(shí)體用這兩個(gè)字段就可以清楚地區(qū)分出來(lái),如何任意兩行數(shù)據(jù)中存在dept_name和db_source都重復(fù)的話,那么必定有一項(xiàng)為重復(fù)的沒(méi)有意義的! 既然沒(méi)有意義,那就刪除了!
  • 03.1.1 清空dept表和備份表dept2,dept表的sql如下,dept2的sql簡(jiǎn)單把下面的表名改一下即可
    注意,人事部和喝茶醬油部這兩個(gè)的db_source列是油變動(dòng)的,不然跟上面的表就一模一樣了!
/*清空dept表,以及重置自增的主鍵*/
TRUNCATE dept;
/*插入dept表一系列數(shù)據(jù)*/
INSERT  INTO `dept`(`dept_no`,`dept_name`,`db_source`) VALUES 
(1,'開(kāi)發(fā)部','clouddb01'),
(2,'人事部','clouddb02'),
(3,'財(cái)務(wù)部','clouddb01'),
(4,'市場(chǎng)部','clouddb01'),
(5,'運(yùn)維部','clouddb01'),
(6,'\'喝茶醬油部\'','clouddb02'),
(21,'開(kāi)發(fā)部','clouddb01'),
(22,'人事部','clouddb01'),
(23,'財(cái)務(wù)部','clouddb01'),
(24,'市場(chǎng)部','clouddb01'),
(25,'運(yùn)維部','clouddb01'),
(26,'\'喝茶醬油部\'','clouddb01');
  • 03.1.2 現(xiàn)有dept/dept2表數(shù)據(jù)


    image.png
  • 03.2.1 比葫蘆畫(huà)瓢,使用上面的方法試試!同樣,如果存在兩個(gè)列數(shù)據(jù)重復(fù)的行的話,只保留dept_no最小的哪行數(shù)據(jù)!
DELETE
FROM
  `dept`
WHERE `dept_name` IN
        /*篩選出存在多列重復(fù)的*/
  (SELECT
    dept_name
  FROM
    `dept2` 
  GROUP BY `dept_name`,db_source
  HAVING COUNT(dept_name) > 1)
      /**保留dept_no最小的那行數(shù)據(jù)*/
  AND `dept_no` NOT IN 
  
  (SELECT
    MIN(dept_no)
  FROM
    `dept2` 
  GROUP BY `dept_name`
  HAVING COUNT(dept_name) > 1);
  • 03.2.2 結(jié)果怎么樣 : 符合預(yù)期結(jié)果


    image.png
    • 03.3.1 單獨(dú)執(zhí)行第一個(gè)子表中的內(nèi)容,發(fā)現(xiàn)正好篩選出了四個(gè)部門(mén),沒(méi)有人事部和喝茶醬油部這兩個(gè).
      想想,GROUP BY X, Y意思是將所有具有相同X字段值和Y字段值的記錄放到一個(gè)分組里。
      這里的是 GROUP BY dept_name,db_source ,故只選出XY兩個(gè)字段都相同的才可以放到一塊來(lái).
      image.png

04 是否可以使用兩重for循環(huán)來(lái)判斷是否存在重復(fù)行并進(jìn)行刪除!

  • 就像一維數(shù)組一樣,進(jìn)行刪除操作!
  • mysql貌似也支持寫(xiě)for循環(huán)!不過(guò).....用Java不更方便吧!
  • 貌似還真可以, 先把所有mysql表中的數(shù)據(jù)取出來(lái)轉(zhuǎn)換成List<Entity>,然后跑兩重for循環(huán)遍歷List ,如果判斷出兩個(gè)實(shí)體符合重復(fù)的條件,則一定有一個(gè)實(shí)體是多余的,則從數(shù)據(jù)庫(kù)中移除對(duì)應(yīng)的記錄(行)即可!
  • 暴力大法好! 時(shí)間上應(yīng)該不分上下!
  • 我都想好了實(shí)現(xiàn)步驟,
    1>取數(shù)據(jù): MybatisPlus的baseMapper.selectList() ;
    2>for兩重判斷實(shí)體是否相等,
    2> 如果存在則刪除一個(gè)即可: baseMapper.deleteById(xxxx) / 同時(shí)移除一個(gè)實(shí)體 兩個(gè)操作即可.
  • 其他方法也可以喲!
  • 未完待續(xù)!!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn) # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    呂品?閱讀 10,123評(píng)論 0 44
  • 1. 了解SQL 1.1 數(shù)據(jù)庫(kù)基礎(chǔ) ? 學(xué)習(xí)到目前這個(gè)階段,我們就需要以某種方式與數(shù)據(jù)庫(kù)打交道。在深入學(xué)習(xí)MyS...
    鋒享前端閱讀 1,320評(píng)論 0 1
  • MYSQL 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫(kù)概要 2 簡(jiǎn)單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 MySQL基本操...
    Kingtester閱讀 8,060評(píng)論 5 115
  • tip: windows 系統(tǒng)下的MySQL學(xué)習(xí)參考資料: 菜鳥(niǎo)教程 1.安裝 按照網(wǎng)上的許多教程安裝好了MySQ...
    恰皮閱讀 1,875評(píng)論 0 3
  • 我們住在萬(wàn)達(dá)廣場(chǎng)邊上的維也納國(guó)際酒店,吃喝很方便,但是據(jù)說(shuō)是三四環(huán)了,到寬窄巷子要坐地鐵,步行10分鐘到成都西站口...
    微笑_b9fd閱讀 421評(píng)論 0 0

友情鏈接更多精彩內(nèi)容