快速导入mysql百万用户数据

news2024/9/28 9:24:37

1. 前言

随着互联网的发展,大数据已经是很普遍的一个现象,已不再是零几年时的神话。数据资源意为着就是信息资源,很好的使用起来说是财富资源一点也不夸张.所以无论当下是小的还是大的互联网公司都会遇到大数的情况。只不过不同的业务逻辑需求与使用情况不一样罢了。

大数据我这大致归类为两种,一种是静态的数据,比如说在一定时间段内的账号信息;另一种是动态数据,比如流量访问信息等。

2. 目标

以上简单的概述了大数量的背景,而本文不会展开叙述太多,而接下来要叙述的是就是如何快速导入百万账号。账号也就是我在上一章节说到的静态资源,这些静态资源有个特性就是在一段时间内是没有多大的变化的,并且与相关联性要求也很高,所以注定存储此类数据会使用选择使用关系型数据库(ACID特性:原子性,一致性,隔离性,持久性),即我们常见的如"MySQL、PostgreSQL、Oracle Database、Microsoft SQL Server等"。这几个典型的数据各有利弊,综合场景与成本等来考虑,大部分会选择使用开源的mysql数据库.所以下文实例都是以mysql数据为例。

3. 方法

常用的有两种方式:一种方法是,直接写sql语句插入数据;另一种方法是,数据文件导入。通常情况下,直接通过SQL语句将数据写入数据库比导入CSV文件数据更快。这里有几点考虑因素:

  • 直接SQL语句写入数据库的优势:

    • 直接数据传输:通过SQL语句直接写入数据库时,数据可以直接传输到数据库的存储引擎中,跳过了文件读取、解析和加载的过程。
    • 少量数据时更快:特别是对于少量数据,直接使用SQL语句可以快速执行,避免了文件操作的额外开销和时间。
    • 即时处理:SQL语句的执行几乎是实时的,一旦语句提交,数据就可以立即在数据库中可用。
  • 导入CSV文件数据的考虑:

    • 大数据量处理:对于大数据量,虽然导入CSV文件可能需要一些预处理步骤(如文件读取、解析和加载),但在某些情况下,使用数据库的批量导入工具或者专门的ETL(Extract, Transform, Load)工具可能会更高效。
    • 数据准备和格式化:如果数据已经以CSV文件的形式存在,并且需要进行大量的数据转换或者数据清洗,导入CSV文件可能更具实际可行性和操作便利性。
    • 导入工具的优化:一些数据库管理系统提供了优化的导入工具,可以有效地处理大量数据的导入,比如MySQL的LOAD DATA INFILE命令或PostgreSQL的COPY命令。

综合考虑:

  • 数据量和频率:如果你经常需要导入大量数据,并且已经准备好了CSV文件,那么使用导入工具可能更为方便和高效。

  • 实时性需求:如果你需要实时数据更新,并且数据量不是特别大,那么直接使用SQL语句写入数据库可能更合适。

综上所述,对于大多数情况,直接使用SQL语句写入数据库通常更快速和直接,特别是对于少量数据或需要即时处理的情况。然而,对于大量数据的导入,特别是需要预处理或者已经存在CSV文件的情况下,使用导入工具可能更有效率。

4.如何快速导入百万级账号

了解了背景与目的,又分析了方法,这里就是具体的操作实现了。研究了几种方式发现导入300百万以上的数据还是使用命令"load data infile"命令最快,一个表全量写入32个字段数据.使用python构造数据csv文件耗时18秒左右,csv文件写入库耗时不到6分钟;另一个全量表8个字段,构造数据文件耗时8秒,csv文件写入库耗时不到2分钟.经查看结果与写入的csv数据保持一致。

注:

  1. 这里有个前提条件,那就是具有可修改my.cnf权限.或是"--secure-file-priv"已经做了配置.因为这涉及到安全性考虑没有配置打开"--secure-file-priv"那就没有办法快捷导入csv数据文件到库里。

  2. 构造数据还需要有python环境

  3. 因不涉及到创建与获取组织架构信息,所以得提前知道组织的名称与组织id.这里简化了一下在构造时输入一个组织名称与id(org_auto,zdy_530853592895066112).实际情况可以写入到一个文件里,然后可以从文件中获取再写入到对应的csv数据表中。

下面以结合业务逻辑写入到三个库表数据为例的具体操作:

4.1 根据实际情况构造数据文件

首先要了解数据结构,那些字段是改写字段不能为空,那些是可以为空,那些是可以为空但实际情况下基本不为空.在此是在线上根据业务根据了真实值情况进行了信息虚拟化改造了一下。

-- base1.table1_user definition

CREATE TABLE `table1_user` (
  `userid` varchar(64) NOT NULL,
  `emid` varchar(32) DEFAULT '',
  `cname` varchar(64) DEFAULT '',
  `utype` int DEFAULT '0',
  `pswd` varchar(64) DEFAULT '',
  `onjob` tinyint(1) DEFAULT '1',
  `userstatus` varchar(16) DEFAULT '',
  `mobile` varchar(64) DEFAULT '',
  `idnumbermd5` varchar(32) DEFAULT '',
  `mail` varchar(256) DEFAULT '',
  `pin_errorcount` int DEFAULT '0',
  `pin_locktime` int DEFAULT '0',
  `deptname` text,
  `dept_path_id` text,
  `dept_path_name` text,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `expire_time` datetime DEFAULT NULL,
  `surname` varchar(64) DEFAULT '',
  `givenname` varchar(64) DEFAULT '',
  `resetpwd` tinyint(1) DEFAULT '0',
  `emp_type` varchar(256) DEFAULT '',
  `dept_id` text,
  `companynumber` varchar(256) DEFAULT '',
  `leader` varchar(64) DEFAULT '',
  `ptjs` varchar(256) DEFAULT '',
  `errorcount` int DEFAULT '0',
  `locktime` int DEFAULT '0',
  `lockstatus` int DEFAULT '0',
  `note` varchar(256) DEFAULT '',
  `mailmember` text,
  `modify_pwd` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

-- base2.table2_organization definition

CREATE TABLE `table2_organization` (
  `org_id` varchar(64) NOT NULL,
  `org_name` varchar(255) NOT NULL,
  `status` tinyint(1) DEFAULT '1',
  `type` varchar(8) DEFAULT NULL,
  `note` varchar(255) DEFAULT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `source_opcode` int DEFAULT '0',
  `inherit` int DEFAULT '0',
  PRIMARY KEY (`org_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

-- base2.table2_user definition

CREATE TABLE `table2_user` (
  `userid` varchar(64) NOT NULL,
  `utype` int DEFAULT '0',
  `cname` varchar(64) DEFAULT '',
  `surname` varchar(64) DEFAULT '',
  `givenname` varchar(64) DEFAULT '',
  `emid` varchar(32) DEFAULT '',
  `mobile` varchar(64) DEFAULT '',
  `onjob` tinyint(1) DEFAULT '1',
  `userstatus` varchar(16) DEFAULT '',
  `idnumbermd5` varchar(32) DEFAULT '',
  `pwd` varchar(64) DEFAULT '',
  `resetpwd` tinyint(1) DEFAULT '0',
  `emp_type` varchar(256) DEFAULT '',
  `mail` varchar(256) DEFAULT '',
  `deptname` text,
  `dept_id` text,
  `companynumber` varchar(256) DEFAULT '',
  `leader` varchar(64) DEFAULT '',
  `ptjs` varchar(256) DEFAULT '',
  `dept_path_id` text,
  `dept_path_name` text,
  `errorcount` int DEFAULT '0',
  `locktime` int DEFAULT '0',
  `lockstatus` int DEFAULT '0',
  `note` varchar(256) DEFAULT '',
  `mailmember` text,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  `updated` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `modify_pwd` datetime DEFAULT CURRENT_TIMESTAMP,
  `expire_time` datetime DEFAULT NULL,
  `source_opcode` int DEFAULT '0',
  `login_time` datetime DEFAULT NULL,
  PRIMARY KEY (`userid`),
  KEY `utype` (`utype`) USING BTREE,
  KEY `lockstatus` (`lockstatus`) USING BTREE,
  KEY `userstatus` (`userstatus`) USING BTREE,
  KEY `index_onjob_userstatus` (`onjob`,`userstatus`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

结合上表结构,实现的python代码如下,保存为createDate.py文件:

# -*- coding: utf-8 -*-
# @Time    : 2024-3-30
# @Author  : zhh
# @Version :
# @File    : createDate.py
# @Software: PyCharm
import time,sys,os,random
from datetime import datetime

def time_str():

    start_date = datetime(2022, 1, 1)
    end_date = datetime(2024, 7, 10)

    random_date = start_date + random.random() * (end_date - start_date)

    time_str = random_date.strftime("%Y-%m-%d %H:%M:%S")
    return time_str
# 删除目录下的所有文件
def delete_files_in_directory(directory):
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        try:
            if os.path.isfile(file_path):
                os.remove(file_path)
                print(f"已删除文件: {file_path}")
            elif os.path.isdir(file_path):
                print(f"跳过目录: {file_path}")
        except Exception as e:
            print(f"删除 {file_path} 时出错: {e}")
def ensure_directory_exists(directory):
    if not os.path.exists(directory):
        print(f"目录 '{directory}' 不存在,将会创建。")
        os.makedirs(directory)
        print(f"目录 '{directory}' 创建成功。")
        return 0
    else:
        print(f"目录 '{directory}' 已经存在,无需创建。")
        return 1
        # delete_files_in_directory(directory)

def write_file(data, flag):
    # with lock:
    # 将数据写入到文件中
    file=flag
    with open(f"{directory_path}/{file}.csv", "a") as f:
        # f.writel(data + "\n")
        f.writelines(data)

# 创建线程A,B,同时向文件中写入数据
def thread_write(org_name,org_id,numbers):
    num = 0
    SSHA="{SSHA2}"
    created_tiem = time_str()
    FILL_TIME = "2099-01-01 01:00:00"

    for i in range(int(numbers)):
        chian_user_lst = []
        chian_org_user_lst = []
        chianotp_user_lst = []

        for i1 in range(10000):
            # 补充0,保持7位数
            userid = "addUser" +str(i).zfill(3) + str(i1).zfill(4)

            chian_user_row = f"{userid},0,'测试账号','测试','账号','2','+86',1,'Active','','{SSHA}RNFjJb5v4QenLqdfWi8nR9E3anlQcHd2U2RaYw==',0,'正式','',{org_name},{org_id},'','','',{org_id},{org_name},0,0,0,'','',{created_tiem},{created_tiem},{created_tiem},{FILL_TIME},0,{FILL_TIME}\n"
            chian_user_lst.append(chian_user_row.replace("'", ""))

            chian_org_user_row = f"{org_id},{userid},'',0, \n"
            chian_org_user_lst.append(chian_org_user_row.replace("'", ""))

            chianotp_user_row = f"{userid},'2','测试账号',0, '', 1,'Active','+86','','',0,0,{org_name},{org_id},{org_name},{created_tiem},{created_tiem},{FILL_TIME},'测试','账号',0,'正式',{org_id},'','','',0,0,0,'','',{FILL_TIME}\n"
            chianotp_user_lst.append(chianotp_user_row.replace("'", ""))

        write_file(chian_user_lst, "chian_user")
        write_file(chian_org_user_lst, "chian_organization_user")
        write_file(chianotp_user_lst, "chianotp_user")

        # time.sleep(1)  # 线程等待1秒钟
        num = num + 1
        print("写入行数:", num*10000)

if __name__ == '__main__':
    # 存储数据目录
    directory_path = 'sql/csvfile'
    path_exist = ensure_directory_exists(directory_path)

    if path_exist:
        delete_files_in_directory(directory_path)
    # 获取命令行参数
    args = sys.argv
    org_name = sys.argv[1]
    org_id = sys.argv[2]
    numbers = sys.argv[3]
    # 创建线程
    thread_a = threading.Thread(target=thread_write, args=[org_name, org_id, numbers])
    startTime = datetime.now()
    print("开始时间", startTime)
    # 启动线程
    thread_a.start()    
    # 等待线程结束
    thread_a.join()
    endTime = datetime.now()
    duration = (endTime-startTime).total_seconds() # 计算总秒数
    print("结束时间", endTime, "共持续", duration, "秒")

把createDate.py文件上传到mysql服务器上,如"/opt/createDate"目录下.执行以下命令:

/data/pubchian/python3/bin/python3 createDate.py org_auto zdy_530853592895066112 1

实际执行结果如下图显示:
在这里插入图片描述

确认mysql的secure-file-priv配置信息,打开/etc/my.cnf配置文件,添加要写入csv文件的路径即在[mysqld]项中添加如下:

[mysqld]
secure_file_priv = '/opt/createDate/csvfile/'

添加完成后需要重启一下mysql数据库.
重启 MySQL 服务:

sudo systemctl restart mysql

如果 MySQL 服务名不是 mysql,而是 mysqld,则使用:

sudo systemctl restart mysqld #这会通过 systemd 来重新启动 MySQL 服务。

csv文件数据导入mysql数据库中,执行如下命令:

# 进入数据库
/data/chiansec/mysql/bin/mysql -uroot -pMSFpMmlZ1ZkY6ZLSZrPU
# 确定可以导入数据库的文件目录,如果没有可以在/etc/my.cnf的配置文件[mysqld]中添加,如:secure_file_priv = "/opt/createDate/csvfile/"
SHOW VARIABLES LIKE 'secure_file_priv';
# 导入数据库文件
USE chianotpms;
load data infile '/opt/createDate/csvfile/chianotp_user.csv' replace into table `chianotp_user` 
fields terminated by ',' 
lines terminated by '\n';

# 
use chianseciam;
load data infile '/opt/createDate/csvfile/chian_user.csv' replace into table chian_user
fields terminated by ',' 
lines terminated by '\n';
# 
load data infile '/opt/createDate/csvfile/chian_organization_user.csv' replace into table chian_organization_user
fields terminated by ',' 
lines terminated by '\n';

5.其他

如果是集群部署的话,可以重复以上操作导入相同的数据(csv文件也可以重复使用不用再构造),也可以使用数据迁移的方式mysql数据库直接同步到集群中的另一台mysql服务器上,即保持数据的一致性,完整性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1919783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git为文件添加可执行权限

查看文件权限 git ls-files --stage .\SecretFinder.py100644 表示文件的所有者有读取和写入权限 添加可执行权限 git update-index --chmod x .\SecretFinder.py再次查看文件权限 git ls-files --stage .\SecretFinder.py100755 表示文件的所有者有读取、写入和执行权限

安卓逆向经典案例——XX优品(uniapp)

uni-app逆向 uniapp的目录结构 有一个io文件夹,下面有dcloud uniapp UniApp 可以用于开发 H5 应用,但它不仅仅局限于 H5 应用。UniApp 的特点包括: 1. 跨平台:可以一套代码同时生成适用于多个平台(如 iOS、Android、…

STM32杂交版(HAL库、音乐盒、闹钟、点阵屏、温湿度)

一、设计描述 本设计精心构建了一个以STM32MP157A高性能单片机为核心控制单元的综合性嵌入式系统。该系统巧妙融合了蜂鸣器、数码管显示器、点阵屏、温湿度传感器、LED指示灯以及按键等多种外设模块,形成了一个功能丰富、操作便捷的杂交版智能设备。通过串口…

Linux C语言基础 day9

目录 思维导图 学习目标: 学习内容: 1. 值传递与地址传递(非常重要) 1.1 值传递 1.2 地址传递 2. 递归函数 2.1 递归的概念 2.2 递归条件 2.3 递归思想 3. 指针 3.1 指针相关概念 3.2 指针变量的定义 3.2.1. 定义格…

初识MVVM分层思想——05

1.MVVM是什么? M :model(模型/数据) V : view(试图) VM :ViewModel (试图模型) : VM 是MVVM 中的核心部分。(它起到一个核心的非常重要的作用&…

mac下mysql无法登陆的问题

用如下命令登录出现错误。 sudo mysql.server start解决方案 使用如下命令登录 sudo /usr/local/MySQL/support-files/mysql.server start

【C++基础】初识C++(1)

目录 一、认识C 1.1 C 相关概念 1.2 C的发展 1.3 C的关键字 1.4 第一个程序 二、命名空间 2.1 namespace的定义 2.2 命名空间的使用 三、C输入和输出 四、缺省函数 五、函数重载 一、认识C 1.1 C 相关概念 1983年,Bjarne Stroustrup在C语⾔的基础上…

Python 视频的色彩转换

这篇教学会介绍使用OpenCV 的cvtcolor() 方法,将视频的色彩模型从RGB 转换为灰阶、HLS、HSV...等。 因为程式中的OpenCV 会需要使用镜头或GPU,所以请使用本机环境( 参考:使用Python 虚拟环境) 或使用Anaconda Jupyter 进行实作( 参考&#x…

BMS电池管理系统 — 1 什么是BMS

目录 1 储能系统组成 1.1 储能电池结构 1.2 储能集装箱组成 2 BMS系统组成 3 BMS功能 3.1 SOC荷电状态估计 3.2 SOH估计 3.3 主动均衡与被动均衡 3.4 电池热管理 4 BMS架构 4.1 集中式BMS 4.2 分布式BMS 参考论文 1 储能系统组成 1.1 储能电池结构 电芯&#xf…

docker(六)--创建镜像

六、创建镜像 1.创建镜像两种方式 方式1: 更新镜像 docker commit 方式2:构建镜像 docker build 2.更新镜像 1)用法 docker commit -m“描述信息” -a作者 容器id或者容器名 镜像名:tag 2)步骤 ①根据镜像运行容器 ②进入容…

PHP将两张图片合成一张图片代码实例(源代码)

使用PHP将两张图片合成一张图片可以通过GD库来实现。下面是一个示例代码,展示如何将两张图片合成一张图片: 加载两张图片。获取每张图片的宽度和高度。创建一个新的空白图片,其宽度是两张图片宽度的和,高度是两张图片中较大的高度…

酒店民宿小程序:酒店民宿便利预订,提高收益!

在旅游业发展旺盛时期,酒店民宿也得到了快速发展。随着移动互联网的发展,人们逐渐在手机上预订酒店民宿,这给酒店民宿小程序的发展提供了用户基础,为大众出行带来了更多的便利。 酒店民宿小程序是一个基于微信平台的应用程序&…

PHP计件工资系统小程序源码

解锁高效管理新姿势!全面了解计件工资系统 🔥 开篇:为什么计件工资系统成为企业新宠? 在这个效率至上的时代,企业如何精准激励员工,提升生产力成为了一大挑战。计件工资系统应运而生,它以其公…

Python大数据分析——K近邻模型(KNN)

Python大数据分析——K近邻模型 数学部分模型思想模型步骤距离度量指标欧氏距离曼哈顿距离余弦相似度 K值选择 代码部分函数示例1——知识掌握程度示例2——预测发电量 数学部分 模型思想 如图所示,模型的本质就是寻找k个最近样本,然后基于最近样本做“…

qml 实现一个带动画的switch 按钮

一.效果图 》 二.qml 代码 import QtQuick 2.12 import QtQuick.Controls 2.12Switch {id: controlimplicitWidth: 42implicitHeight: 20indicator: Rectangle {id: bkRectangleanchors.fill: parentx: control.leftPaddingy: parent.height / 2 - height / 2radius: height …

C语言有哪些特点?

C语言是一种结构化语言,它有着清晰的层次,可按照模块的方式对程序进行编写,十分有利于程序的调试,且c语言的处理和表现能力都非常的强大,依靠非常全面的运算符和多样的数据类型,可以轻易完成各种数据结构的…

Linux系统日志管理服务和配置

文章目录 Linux系统日志服务rsyslog日志分类rsyslog相关文件/var/log/message重启失败分析 /var/log/secure自定义日志输出路径1.修改sshd_config配置文件2.修改rsyslog.conf3.重启服务 常见日志文件日志管理工具journalctl选项说明journalctl用法示例 日志分析实战host无法解析…

qt creator中右边的的类和对象如何显示出来

qt creator中右边的的类和对象如何显示出来? 解决方法: 鼠标右键,重置为默认布局。

未来互联网的新篇章:深度解析Web3技术

随着技术的不断演进,Web3正逐渐成为引领未来互联网发展的关键驱动力。本文将深入探讨Web3技术的核心概念、关键特征以及其对未来互联网生态的深远影响,旨在帮助读者全面理解和把握这一新兴技术的发展方向和潜力。 1. Web3的基本概念和演进 Web3并非简单…

【AI大模型】通义灵码的部署与使用

【AI大模型】通义灵码的部署与使用 目前已支持: JetBrains IDEsIDE 版本:IntelliJ IDEA、PyCharm、GoLand、WebStorm、Android Studio 等 2020.3 及以上操作系统:Windows 7 及以上、macOS、LinuxVisual Studio CodeIDE 版本:1.68.…