MySQL实战作业示例:从离线文件生成数据库

news2024/11/13 10:31:10

前言

MySQL实战的课后作业,作业内容具体见 https://bbs.csdn.net/topics/611904749
截至时间是 2023年2月2日,按时提交的同学有一位。确实这次的作业非常有挑战性,作业用到的内容没有百分之百的学过,需要大家进行深入而有效的搜索和尝试。
其实在解决困难问题的过程中,通过搜索解决方案和试错修正,我们可以快速学习。
下面我给出一个作业问题的解决方案,仅供大家参考。

问题分析

题目描述:创建数据库,将database_asset的表格(5073个证券2022年的交易日数据)全部导入数据库,并将他们合并,合并后,将表格的主键设置为证券代码、日期组成的联合主键。

先看一下给定的数据,5073个数据都是csv文件,数据是2022年全部交易日的交易数据。1月10日在群里另外给大家一个文件securities.csv,其中有证券的基本信息,包括显示名称,字母简称和上市和退市时间等。查看后,发现securities的内容并没有包含证券代码。

所以我们需要根据securities的数据内容,结合外部数据恢复证券代码。由于数据是从聚宽量化获取的,我们需要从数据源下载一份更全面的数据。下载过程(略)具体见聚宽的说明文档,聚宽量化 https://www.joinquant.com/data。下载目前上市的所有股票的资料,存入 all_securities.csv.

解决问题的步骤大致分为以下几步:
1、复原证券列表的代码部分,作为基础数据
2、处理数据,增加一些数据标签,方便以后进行分析
3、建库建表
4、导入个股数据
5、合并数据,增加主键
6、备份数据库

解决方案

1.复原基础数据

使用python进行数据预处理。导入需要的包,这里为了简洁省略了导入包的语句,大家可以自行脑补一下。

首先读入securities.csv

# 读入证券列表数据
securities = pd.read_csv('securities_0110.csv')

读入数据后,预览数据的情况。


securities.head() # 预览证券列表字段

securities.info() #查看空值情况

securities.duplicated().sum() # 查看有多少重复数据

securities表里有五个字段,熟悉证券交易的同学可以一眼看出每个字段的含义。
在这里插入图片描述

securities,一共5073行,五个字段都不含空值,所以不需要处理空值,行的维度没有重复值。
在这里插入图片描述

在已知的字段里找一下唯一标识

# 考察name和display_name是否唯一标识一只股票
l1 =  len(securities.display_name.unique()) # 5071 
print(l1)

l2 = len(securities.name.unique()) # 4115
print(l2)

l3 = len(securities[['display_name','name']])
print(l3)

securities[securities.display_name.duplicated()] #查看display_name为索引时的重复值

我们发现只有’display_name’,'name’联合在一起才能唯一标识一行数据,而display_name比较接近唯一标识,查看display_name为索引时的重复值项发现有两只固表存在display_name的重复。
在这里插入图片描述
查看这两只股票的数据:


securities[securities.display_name == '百联股份']

securities[securities.display_name == '东方明珠']

在这里插入图片描述
在这里插入图片描述
可以看到重复项的上市时间和退市时间存在分歧,所以必须借助证券代码来处理数据。

#获取额外数据来找到证券代码作为证券的唯一标识
alls = pd.read_csv('all_securities.csv')

因为聚宽的数据是dataframe格式的,会有一个格是Unnamed,通过下图所示的方式处理一下。
在这里插入图片描述

通过merge函数重新组装数据

#s = pd.merge(securities,alls,on=['display_name','name'],how='inner')
s = pd.merge(alls,securities,on=['display_name','name'],how = 'inner')
print(s)
s[s.code.duplicated()]

合并后的表有重复项4项。
在这里插入图片描述
去掉重复项后,去掉重复列(过程略),得到一个5070行的数据表。将s命名为final并修改字段名称为[‘code’, ‘display_name’, ‘name’, ‘start_date’, ‘end_date’]

2. 处理数据,添加标签

增加一列 ‘exit’,提示股票是否在2022年底已经退市。

final['exit'] = final.end_date<='2022-12-31'
final[final['exit']]  ## 168只股票已经退市

在这里插入图片描述
增加一个新股的提示字段 new,提示是否股票为新股

final['new'] = final.start_date>'2022-01-01'
final[final.new] 
# 2022年有346只新股, 发现有一只股票 6885062023年才上市的

在这里插入图片描述
因为该股不在我们的统计周期,故去掉这条数据。

# 删除688506的数据
final2 = final.drop([4944], axis=0)

新股的交易日不覆盖全年,我们的数据表中存在它们还未交易的数据行,所以需要计算条过的无效行的数量,增加一列row_skip, 统计新股发行前在2022年的交易日数量。

final2['row_skip']= np.nan

# 使用trade_days为skip_row赋值
for i in final2.index:
    final2.row_skip[i] = trade_days('2022-01-01',final2.start_date[i])

#查看赋值情况
final2[final2['new']]

trade_days(start_date,end_date)是我们自己定义的函数,主要使用calender包统计交易日,这里略过。赋值后,新股都有了相应的值。

在这里插入图片描述
至此,数据处理完成,将处理结果导出

final2.to_csv('stockList.txt',index = None,encoding='utf8')

之所以存成.txt文件,是因为.csv文件莫名会把数字字符串转成数字存储,也可能是显示方式的问题,总之会导致数据出问题,所以我们选择txt文件。

3. 建库建表

使用csdn的云容器,4核4G的MySQL技能树。

先创建数据库stocks;代码略。

在库里建表stockList存放我们刚才处理好的基础数据。

CREATE TABLE stockList(
code char(8),
display_name varchar(20),
name char(5),
start_date date,
end_date date,
exlisting ENUM('True','False'),
newlisting ENUM('True','False'),
row_skip INT
);

使用load data命令导入数据

load data infile '/media/stockList.txt' into table stockList 
fields terminated by ','
lines terminated by '\n'
ignore 1 rows;

按照作业要求需要将个股的数据先导入,所以需要为每只个股建立表。考虑到个股的数量在5000以上,手动建表已经没有可行性,所以我们写一个存储过程来实现建表的过程。

创建存储过程create_tables():

delimiter $
CREATE PROCEDURE create_tables()
BEGIN
  SET @list := (SELECT GROUP_CONCAT(code) FROM stockList);
  SET @counter := 1;
  WHILE @counter <= (SELECT COUNT(code) FROM stockList) DO
        SET @str := (SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(@list,',',@counter),',',-1));
        SET @tablename := CONCAT('price_',@str);
        SET @sql_text = CONCAT('CREATE TABLE ' '', @tablename, '(trade_day DATE, op DECIMAL(6,2),              cl DECIMAL(6,2), high DECIMAL(6,2), low DECIMAL(6,2), volume BIGINT,  money BIGINT  );'); 
        PREPARE stmt FROM @sql_text; 
        EXECUTE stmt; 
        DEALLOCATE PREPARE stmt;
        SET @counter = @counter + 1;	
  END WHILE;
END $
delimiter ;

我们这里使用自定义变量 @list, @counter, @str帮助我们提取证券代码并轮询建表语句。在存储过程中无法直接create table,需要prepare。

GROUP_CONCAT() 和 SUBSTRING_INDEX( )这两个函数帮了我们大忙。调用时call create_tables(),之后我们就得到5069个表;

4. 导入数据

个股数据的导入直觉上是再写一个存储过程就完事儿啦,但是,很可惜,mysql的存储过程并不能包含LOAD DATA。但是,很幸运,mysql还有mysqlimport这个功能,可以帮助我们很快解决问题。

mysqlimport的语法: mysqlimport --ignore-lines=1 --fields-terminated-by=, --local -u root -p Database TableName.csv

我们可以看出,.csv文件的名称必须是表名,但是我们的.csv文件的名称是证券代码,与表名相比,缺少一个前缀 ‘price_’。不过没有关系,添加前缀也是很方便的。

我们在.csv文件所在的文件夹,使用下面这一行命令就可以完成任务

for f in * ; do mv -- "$f" "price_$f" ; done

万事俱备,只欠东风啦!
我们再用一行语句完成个股数据的导入。

for f in * ; do mysqlimport --ignore-lines=1 --fields-terminated-by=, --verbose --local -u root stocks /media/database_asset/"$f"; done

照一张表格去一部分数据看一下,
在这里插入图片描述
看起来没有问题。

5. 合并数据,增加主键

合并数据的话,依然需要使用存储过程。
当然,首先创建一个合并表:

CREATE TABLE merged_table (
 code CHAR(8), 
 date DATE, 
 open DECIMAL(6,2), 
 close DECIMAL(6,2),
 high DECIMAL(6,2),
 low DECIMAL(6,2), 
 volume BIGINT, 
 money BIGINT 
 );

我们合并表时使用 INSERT INTO … SELECT … FROM … 这样的方式,这样比一行一行的insert要快很多。

创建一个存储过程merge_tables() :

delimiter $
CREATE PROCEDURE merge_tables()
BEGIN
  set @list := (SELECT GROUP_CONCAT(code) FROM stockList);
  set @counter := 1;
  WHILE @counter <= (select count(code) from stockList) DO
        SET @str := (select substring_index(substring_index(@list,',',@counter),',',-1));
        SET @tablename := CONCAT('price_',@str);
        SET @sql_text = CONCAT('INSERT  INTO  merged_table( code, date , open , close ,high ,low , volume , money ) SELECT ''',@str,''' as code, trade_day , op , cl ,high ,low , volume , money  FROM  ',@tablename,';'); 
        PREPARE stmt FROM @sql_text; 
        EXECUTE stmt; 
        DEALLOCATE PREPARE stmt;
        SET @counter = @counter + 1;	
  END WHILE;
END $
delimiter ;

调用call merge_tables(), 我们就得到合并的所有数据。数据量122万左右。
在这里插入图片描述
在这里插入图片描述
所有的证券代码都导入了。

然后我们使用alter name给merged_table表添加联合主键。

 ALTER table merged_table add primary key(code,date);

6.备份数据库

使用mysqldump将数据库备份到/media文件夹下:

mysqldump stocks > /media/stocks_backup.sql

将.sql文件下载到本地,保存,以备后用。

至此,作业已经完成。但是我们还要做一些扫尾工作,记得把刚才建立的存储过程删除哦。

DROP PROCEDURE create_tables;
DROP PROCEDURE merge_tables;

后记

本次作业的过程难点主要在于如何在mysql里使用循环语句,构建存储过程,以及如何快速导入文本数据。

作业的过程中,搜索是一项重要的技能,百度和csdn可能并不能提供完全的解决方案,需要我们试错,并有耐心排除故障,找到问题的所在。

存储过程和用户自定义函数其实在mysql的系统眼里并没有本质区别,自定义函数应该是被当作了带有返回值的存储过程,这一点是在尝试批量导入个股数据表时发现的。因为两种方式的报错信息是完全一样的。

这个作业很难,但是探索完成的过程中,我们很自然的学到了mysql的很多相关知识。希望大家enjoy!

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

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

相关文章

【MyBatis】高级映射多对一,一对多和延迟加载

数据库准备:1. 多对一:多个学生对应一个班级(学生表是主表, 班级表是副表)多种实现方式, 常见的包括三种第一种方式&#xff1a; 一条sql语句, 级联属性映射// StudentMapper.xml // 一条sql语句, 级联属性映射 <resultMap id"studentResultMap" type"Studen…

Java当中的AQS

一、什么是AQS AQS的全称是:AbstractQueuedSynchronizer AQS是java当中的一个抽象类&#xff0c;用来构建锁和同步器。 例如我们常见的ReentrantLock&#xff0c;Semaphore等等都是通过AQS来构建的。 AQS的原理 如果被请求的共享资源没有被占用&#xff0c;那么就把请求资源…

spring boot集成xxl job

目录 1.xxl job介绍 2.搭建说明 (1)配置调度中心 (2)配置执行器 (3).执行 1.xxl job介绍 官网地址:分布式任务调度平台XXL-JOB XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。 2.搭建说明 环境搭建主要分为两个部分…

《深入浅出计算机组成原理》学习笔记 Day19

冒险和预测&#xff08;三&#xff09;乱序执行参考乱序执行 尽管代码生成的指令是顺序的&#xff0c;但是如果后面的指令和前面的指令独立&#xff0c;完全不需要等待前面的指令运算完成&#xff0c;可以先执行。 这种解决方案称为乱序执行&#xff08;Out-of-Order Executi…

程序加载与运行过程中的资源分配与管理

目录 程序的加载 程序的内存空间 程序入口地址 BSS段初始化 程序运行过程中的堆栈管理 栈内存管理 变量的作用域&#xff1a; 栈溢出攻击原理 Linux堆内存管理 查看进程内存布局 内存分配器 内存块合并 top chunk 程序的运行分两种情况&#xff1a;一种是在有操作…

矩阵理论复习(九)

A为正规矩阵时&#xff0c;A的奇异值是A的特征值的模。A为半正定Hermite矩阵时&#xff0c;A的奇异值是A的特征值。 最佳逼近解 最小二乘解 矩阵的单边逆 A是左可逆的充要条件是A为列满秩矩阵 A是左可逆的充要条件是NA{0} 投影矩阵N(A)R(I-A),N(I-A)R(A) A是右可逆的充要…

腾讯电子签小程序跳转(app 跳小程序,小程序跳小程序) Api

腾讯电子签 官网地址&#xff1a;腾讯电子签跳转 api 文档 let id‘yDw9jUUgyg34gq97U7WZ9b1rWEBV******’ let name ‘张**’ let phone ‘MTQ3NDU3Oidioidkl’ let path pages/guide?fromSFY&toMVP_CONTRACT_COVER&id${id}&name${name}&phone${phone} wx…

Echarts解决左右上下边距问题( 两种方法)

第007个点击查看专栏目录文章目录示例效果示例源代码&#xff08;共88行&#xff09;相关资料参考相应的设置参数&#xff08;方法1&#xff09;相应的设置参数&#xff08;方法2&#xff09;专栏介绍示例效果 没有添加grid之前&#xff08;有grid的默认值来控制&#xff09; …

Web 3 财富分配方式

文章作者&#xff1a;Andrew Beal每个星期四&#xff0c;Forta 基金会团队都会在 Zoom 上聚会&#xff0c;享受虚拟欢乐时光。我还没有亲自见过我的一些同事&#xff0c;所以这是我唯一一次了解他们在办公室之外的身份。每个人都有故事要讲&#xff0c;你只需要问。规则是 “我…

Canal安装和配置

Canal安装和配置1.开启MySQL主从1.1.开启binlog1.2.设置用户权限2.安装Canal2.1.创建网络2.2.安装Canal2.3.查看canal是否与mysql建立连接下面我们就开启mysql的主从同步机制&#xff0c;让Canal来模拟salve 1.开启MySQL主从 Canal是基于MySQL的主从同步功能&#xff0c;因此…

wamp内置mysql和学习后端下载mysql相冲突问题

文章目录前言1.将后端的mysql放入wamp路径下2.打包代码文件3&#xff0c;查询wamp集合环境换mysql的办法成功way前言 尝试了各种能够兼容两者的办法都失败了 所以一气之下把wamp内的mysql删了&#xff0c;使前后端都使用一个mysql 1.将后端的mysql放入wamp路径下 将后端的mysq…

【6s965-fall2022】量化 Quantization Ⅱ

什么是线性量化 rS(q−Z)r S(q - Z)rS(q−Z) 式中&#xff0c;SSS是比例因子&#xff0c;通常是一个浮点数&#xff1b;qqq是rrr的量化后的表示&#xff0c;是一个整数&#xff1b;ZZZ也是一个整数&#xff0c;把qqq中和ZZZ相同的整数映射到rrr中零&#xff0c;因此ZZZ是零点偏…

24_mimikatz

mimikatz 一、介绍 二、修改注册表抓取明文密码 当目标为win10或2012R2以上时&#xff0c;默认在内存缓存中禁止保存明文密码&#xff0c;但可以通过修改注册表的方式抓取明文。 重启或用户重新登录后可以成功抓取 reg add HKLM\SYSTEM\CurrentControlSet\Control\Security…

Java设计模式总结

java常用七种设计模式总结单例模式单例模式的实现第 1 种&#xff1a;懒汉式单例第 2 种&#xff1a;饿汉式单例工厂方法模式一&#xff0c;简单工厂模式二、工厂方法模式三、抽象工厂模式建造者模式策略模式模板方法责任链模式代理模式适配器模式观察者模式单例模式 单例模式…

第三届腾讯Light技术公益创造营启动

简介 腾讯Light技术公益创造营通过持续探索技术与公益的结合&#xff0c;已经打造出了包括推进公众参与中华白海豚保育的公益计划、使用AI技术助力新生儿黄疸诊断的“高危儿拯救计划”等一批优秀项目 全面升级的第三届腾讯Light技术公益创造营在海南海口正式启动&#xff0c;…

Redis 分布式锁实现详解

一、概述分布式锁&#xff0c;即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题&#xff0c;而分布式锁&#xff0c;就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是&#xff0c;分布式系统中竞争共享资源的最小粒度从线程升级成…

Go练手==若依go语言版本开发day01

代码地址&#xff1a;ry-vue-go: 使用GO开发若依后台 启动方式&#xff1a; pycharm打开项目后点击main.go启动后端 打开文件夹浏览器后&#xff0c;点击ruoyi-ui下的z_start_ui.bat启动前端 数据库 mysql 缓存redis ORM框架 GORM WEB框架 GIN 今日实现功能 mysql连接池U…

python采集《狂飙》评论,看看是什么让它如此火爆

前言 大家早好、午好、晚好吖 ❤ ~ “是非面前稍不留神&#xff0c;就会步入万丈深渊&#xff0c;唯有坚守信仰&#xff0c;才能守得初心” 2023年首部爆款剧集《狂飙》迎来大结局&#xff0c;今天我们就来采集一下评论,看看为什么它这么火爆 开发环境: python 3.8 pycharm …

计算机网络-TCP如何保证传输可靠性

TCP协议传输的特点主要就是面向字节流、传输可靠、面向连接。 TCP协议如何确保传输的可靠性的? 确保传输可靠性的方式 TCP协议保证数据传输可靠性的方式主要有&#xff1a; 1.校验和 2.序列号 3.确认应答 4.超时重传 5.连接管理 6.流量控制 7.拥塞控制 1.校验和 发送方&a…

MVC,MVP和MVVM框架之间的理解

一、MVC的理解 1、MVC是什么 MVC, 即Model-View-Controller, 基于页面逻辑的修改要多于业务逻辑, 分离两种逻辑减少类代码的修改 Model: 即数据层, 负责处理业务逻辑, 监听网络与数据库接口View: 即界面(UI)层, 显示来源于Model的数据Contoller: 即逻辑层, 传递用户的交互和更…