对于一个数据库里所有表里的所有字段数据都完完全全重复了一遍甚至好几遍,造成一个库的数据达到几十万条记录,那么可以使用下面的脚本进行一键去重!
select distinct 该命令是查询去重的数据,后面如果加 * 的话,那么就是查询所有字段里去重的数据;如果要查询哪几个字段的数据去重,那么就 select distinct 字段 from 数据库.数据表;
但是要注意的条件:
1、首先要对原原本本的数据库进行备份(这是必须的)
2、然后可以在数据库里挑几个(或者全部表)表分别查看表里的记录有多少条,用于后面的验证:
select count(1) from 数据库.数据表;
3、也可以单独对一个表或者几个表创建、更新一些数据,用于后面的验证
#!/bin/bash
#定义数据库相关变量
database_name="test"
database_user="root"
database_user_password='123456'
################################################对原表名进行输出重定向################################################
##选出所有需要去重数据的数据表名
old_table_name=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";show tables" | grep -v Tables_in_`
#将表名输出重定向到一个临时文件里
echo "$old_table_name" > /root/old_table_name.txt
#计算存放表名的临时文件的行数
num_old_tab_name=`cat /root/old_table_name.txt | wc -l`
####################################################################################################################
#对库里所有表的数据都去重复制到新表中
function create_new_table
{
echo -e "\033[032m 正在去重数据,创建副本数据表 \033[0m"
for ((notn=1;notn<="$num_old_tab_name";notn++))
do
old_tab_name=`sed -n "$notn"p /root/old_table_name.txt`
new_tab=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";create table New_"$old_tab_name" select distinct * from "$old_tab_name" "`
echo "$new_tab" #执行创表操作
done
}
#对旧表的数据全部删除。只是单纯删数据,不删除表,不该表表结构.这步操作要重复执行两到三次左右
function delete_data_tables
{
echo -e "\033[032m 正在删除原表中的数据 \033[0m"
echo -e "\033[031m 此次删除数据操作只删数据,不改变表的结构! \033[0m"
for ((notns=1;notns<="$num_old_tab_name";notns++)); do
old_table_names=`sed -n "$notns"p /root/old_table_name.txt`
del=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";delete from "$old_table_names" "`
echo "$del" #执行删数据操作
done
}
#删掉旧表数据后,查询一下所有的表是否已经将数据全部删除了
function select_old_tabs
{
echo -e "\033[032m 正在查询原表上是否有数据,如果有,请停止脚本单独执行删除旧表的函数 \033[0m"
for (( odt = 1; odt <= "$num_old_tab_name"; odt++ )); do
old_tab_names=`sed -n "$odt"p /root/old_table_name.txt`
select_old_tabs=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";select * from "$old_tab_names""`
echo "$select_old_tabs" #执行查询数据操作
done
}
#对去重的数据插入到对应的原表中
function insert_data_table
{
echo -e "\033[032m 正在向原表插入已去重的数据 \033[0m"
#根据临时文件的行数来输出各个原表的表名,然后进行插入去重的数据
for ((i=1;i<="$num_old_tab_name";i++))
do
#选出原表表名,每次遍历都是不同的表名
tab_name=`sed -n "$i"p /root/old_table_name.txt`
insert_data=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";insert into "$tab_name" select * from New_"$tab_name";"`
echo "$insert_data" #执行插入数据的操作
done
}
#删除副本数据表
function del_new_tables
{
echo -e "\033[032m 正在删除副本数据表 \033[0m"
#选出新表的名字
new_tables_name=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";show tables;" | grep -v Tables_in_"$database_name" | grep ^New_`
#将新表的名字全部重定向到一个文件里
echo "$new_tables_name" > /root/new_tab.txt
#将临时文件的行数赋值给变量new_num
new_num=`cat /root/new_tab.txt | wc -l`
#删除新表
for ((d=1;d<="$new_num";d++))
do
new_tab_name=`sed -n "$d"p /root/new_tab.txt`
dnt=`mysql -u"$database_user" -p"$database_user_password" -e "use "$database_name";drop table "$new_tab_name""`
echo "$dnt" #执行删新表操作
done
}
create_new_table
delete_data_tables
delete_data_tables
select_old_tabs
insert_data_table
del_new_tables
#删除临时文件
rm -rf /root/new_tab.txt
rm -rf /root/old_table_name.txt
echo -e "\033[035m /root 路径下的临时文件已删除,此次操作已结束! \033[0m"