我把每日股票成交明细的 csv 文件,导入到 mysql 里,结果数据库占硬盘过大怎么处理..

2020-07-11 11:16:46 +08:00
 blueaurora

我从淘宝上买了每天的股票成交明细文件, 每支股票一天的成交明细就是一个 csv,一天就是 3800 多个 csv (沪深股票总数。 打成 7z 压缩包,就是 400M 左右。一个月 30 天的话,也就是 12G 左右。 我觉得 csv 麻烦,就想把这些数据写到 mysql 里

我用 python 的 sqlalchemy 从 csv 里 先读出 DataFrame,再把成交股数改为成交手数,再 dataFrame.toSql 写到 mysql 里。 但没想到 mysql 里一天的数据,也就是对应压缩包 400M 的数据,竟然占了 27G.. 我看一个 csv 的内容,到 mysql 里是 10M 左右..我也不知道还有什么乱七八糟的,怎么这么大

我这个 csv 的行首, 就是下边这些了,一般股票,也就是一个 csv 也就 3 万列: TranID Time Price Volume SaleOrderVolume BuyOrderVolume Type SaleOrderID SaleOrderPrice BuyOrderID BuyOrderPrice

我从 sqlalchemy 打印出来的 sql 语句看 TranID 、SaleOrderID 、BuyOrderID ,都是 BigInteger

而 SaleOrderVolume BuyOrderVolume Price SaleOrderPrice BuyOrderPrice 因为有小数,从 sqlalchemy 打印出来的 sql 语句看 都是 Float(53),应该转成 double 了

我觉得这个类型不是影响数据库占硬盘大小的关键问题吧? 我是个 mysql 新手, 想问问这事怎么优化, 我希望的是同样数据量 mysql 占硬盘比 csv 还小,哪知道大了这么多倍

5880 次点击
所在节点    MySQL
38 条回复
xyjincan
2020-07-11 11:20:02 +08:00
设计该表为压缩表
Mysql 开发手册中指出,“In particular, compressed tables use less disk space and so require less disk I/O to read and write the data. Compression is available for all kinds of workloads with InnoDB tables, and for read-only MyISAM tables.”
————————————————

关闭日志
encro
2020-07-11 11:34:09 +08:00
--- 查看那张表占用空间大

USE information_schema;

SELECT
TABLE_SCHEMA,
TABLE_NAME,
DATA_LENGTH,
INDEX_LENGTH
FROM
TABLES
GROUP BY
TABLE_SCHEMA
ORDER BY
DATA_LENGTH DESC;


-- 修改表采用压缩

USE mydb;

ALTER TABLE mytable ROW_FORMAT = DYNAMIC;

OPTIMIZE TABLE mytable;

如果没有 DYNAMIC,那么采用 COMPRESSED 也可以

-- 修改表采用 tokudb (需要安装 tokudb 引擎)

ALTER TABLE `mytable`
ENGINE=tokudb;


数据可以共享下不?
encro
2020-07-11 11:37:40 +08:00
还有就是修改字段长度
felixcode
2020-07-11 11:38:11 +08:00
可能不是数据文件占用的,是日志文件占用的,先找下是什么文件占用的空间吧
encro
2020-07-11 11:39:21 +08:00
希望占用比 csv 小是不可能的。采用 gbk 存?

ALTER TABLE `mytable`
DEFAULT CHARACTER SET=gbk,
encro
2020-07-11 11:47:11 +08:00
mysql 日志爆满,删除日志文件,定时清理日志
https://my.oschina.net/magicalSam/blog/1143079


以上写进了我新鲜出炉的 Blog:

Mysql 查看以及优化表空间
https://c4ys.com/archives/2255
blueaurora
2020-07-11 11:56:23 +08:00
@encro
数据 我在 http://www.sdata.vip 买的,200 块一年吧
网盘是 https://pan.baidu.com/s/1nAqB-fA4S9dz98znapSfNQ#list/path=%2F
pwd 是 ascii 十进制 105 112 112 100 ,也就是四个小写字母 。
隔一段网盘密码就换
imn1
2020-07-11 12:17:15 +08:00
分笔数据只能用服务器级机器
实际上个人拿分笔没太大用,因为个人通过券商联网购买,比起席位号机器购买是有延时的
除非预埋地雷单,否则抢不过人家

如果要做深度分析,还是备台强力机器吧
blueaurora
2020-07-11 12:36:52 +08:00
@encro 每个表就是 10M,3800 个表, 那其实就是好几十 G 了。 这表不能再小了?
blueaurora
2020-07-11 12:39:10 +08:00
@felixcode 同问
“每个表就是 10M,3800 个表, 那其实就是好几十 G 了。 这表不能再小了?”
blueaurora
2020-07-11 12:40:47 +08:00
现在就是 一个表的 .ibd 文件,就是 10M 的样子。 比如 600196.ibd ,有 14M
blueaurora
2020-07-11 12:45:12 +08:00
我没有开日志呢..
fengyqf
2020-07-11 12:45:20 +08:00
数据库通常不会比 csv 小,除了数据还要存索引,都要空间;字符串型字段,如果固定长度的表,还会大量浪费空间。
laminux29
2020-07-11 12:47:08 +08:00
你可以写个程序,每次查询时,先自动从 7z 解压,自动导入 mysql,然后再进行查询。查询完毕后,自动把 mysql 数据清空。这样就能解决数据库占硬盘过大的问题。
yzwduck
2020-07-11 13:01:30 +08:00
如果是 mysql 新手的话,我觉得可以跳过 mysql,试试 xsv 这个工具,它能直接处理 csv 数据。
csv 体积大的话,可以用 xz/zstd 压缩一下。
laqow
2020-07-11 13:20:19 +08:00
我能想到的直接存 csv 的 gz,写个 python 的接口,需要哪天再读哪天进数据库,数据库只维护关系表,不维护具体数据
outoftimeerror
2020-07-11 13:55:08 +08:00
写 hive,日期做分区字段,格式选 parquet
rockyou12
2020-07-11 14:10:01 +08:00
换 pg 试下,我现在就用 pg 分析日线周线,数据量应该比你的小但完全没碰到压力。或者考虑下 timescale ?这个是时序数据库,但基本还是 pg 用法,性能要强得多
angryfish
2020-07-11 14:14:56 +08:00
要注意字段类型的设置
ichao1214
2020-07-11 14:33:57 +08:00
场景不太适合,不如使用时直接读 csv 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/689122

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX