TPC-H数据导入Mysql数据方案
本文主要参考了以下几篇博文,以下内容主要来源于这些博文,并在此基础上做了相应的归纳整理。感谢他们!
鉴于原博客github打不开,所以相关源码看不到,我当时也费了很多劲,本文将需要修改的代码以文本的形式展示出来,供大家参考。
我的操作系统为 -------centos7
参考文章:http://www.cnblogs.com/joyeecheung/p/3599698.html https://testerhome.com/topics/14409
https://blog.csdn.net/qq_33560172/article/details/78453812?utm_source=copy
好啦请看正文:
0:TPC-H简介:
TPC-H是TPC提供的一个benchmark,用来模拟一个现实中的商业应用,可以生成一堆虚构的数据,且自带一些查询,可以导入到各种数据库中来模拟现实需求,检查性能。
1:获取TPC-H文件
首先进入官网 http://www.tpc.org/tpch/ ,在最左下边栏目里找到Downloads,点击进入,然后找到TPC-H那一栏对应的source code(是一个zip格式的文件),点击下载到本地,随便放个好找的地方就OK啦啦啦啦啦。
2:准备MySql数据库
由于是使用mysql数据库,所以需要安装mysql数据库。怎么安装就下去自己准备吧。
3:修改makefile文件
首先将咱们在第1步中下载的zip文件解压出来。在解压的文件夹下面cd到dbgen目录下,找到makefile.suite文件。
~/tpch_2_16_1$ cd dbgen
~/tpch_2_16_1/dbgen$ vi makefile.suite
然后修改把103~112行左右这个样子
CC = gcc
# Current values for DATABASE are: INFORMIX, DB2, TDAT (Teradata)
# SQLSERVER, SYBASE, ORACLE, VECTORWISE
# Current values for MACHINE are: ATT, DOS, HP, IBM, ICL, MVS,
# SGI, SUN, U2200, VMS, LINUX, WIN32
# Current values for WORKLOAD are: TPCH
DATABASE = MYSQL
MACHINE = LINUX
WORKLOAD = TPCH
#
注意:请确保你的系统上已有gcc编译器!!!若不确定是否有,请输入以下代码测试或安装
yum install gcc
改动的地方分别是:
- 设定C语言编译器为gcc(如果你用的是其他的编译器就改成其他对应名字)
- DATABASE设为MYSQL(注意注释里写的提供的数据库格式没有mysql,所以等一下要自己写一个格式,见步骤3)
- MACHINE = LINUX 和 WORKLOAD = TPCH 就不用说啥意思了……
改好之后保存,将makefile.suite的文件后缀去掉,保存为makefile,这样后面使用make命令时,才能正确应用。代码如下:
mv makefile.suite makefile
4:修改tpcd.h
// 其实这一步好像没什么用 = =
// 不过你上面把DATABASE设成了MYSQL的话就不要跳过这一步,不然编译不了。
// 或者上面那步也可以设成SQLSERVER这步就不用管了
//之前说了官方的生成程序没有mysql的格式,所以我们要自己写一个
打开tpcd.h,在开头找一个空白的地方写上下面的宏定义
#ifdef MYSQL
#define GEN_QUERY_PLAN ""
#define START_TRAN "START TRANSACTION"
#define END_TRAN "COMMIT"
#define SET_OUTPUT ""
#define SET_ROWCOUNT "limit %d;\n"
#define SET_DBASE "use %s;\n"
#endif
这样就定义了一个MYSQL的脚本格式可以用了。
5:生成dbgen
直接输入make命令,之后会在dbgen文件夹里面看到有许多.o格式的文件和一个dbgen文件被输出。
~/tpch_2_16_1/dbgen$ make
6:生成.tbl数据文件
接下来要用dbgen生成数据,一共会生成8个表(.tbl)。
查看README里面有命令行参数解说,这里我们在dbgen目录下用
./dbgen -s 1
其中1表示生成1G数据。如果你想生成10G。直接将1改为10就OK啦啦啦啦啦啦啦。
ps:(如果你之前曾经尝试过生成数据,最好先make clean,再重新make,接着到这步加上-f覆盖掉)。
如:
./dbgen -s -f 1
7:修改初始化脚本使mySQL可用
压缩包里自带两个脚本:
- dss.ddl:用来建表
- dss.ri :关联表中primary key和foreign key。
不过这些脚本不能直接在mySQL里用(看README就知道人家根本没考虑过mySQL……),要修改。
7.1--->修改dss.ddl
dss.ddl的开头需要加上一些给MySQL建立数据库连接用的指令。在最前面加上如下代码:
DROP DATABASE tpch;
CREATE DATABASE tpch;
USE tpch;
鉴于tpch自带的测试用的表名是小写的,而dss.ddl里面的表名是大写的,我们最好也改成小写,方法如下:
用vim打开dss.ddl
vi dss.ddl
在普通模式下输入如下命令并执行:
:%s/TABLE\(.*\)/TABLE\L\1
7.2--->修改dss.ri(用vim打开dss.ri,然后全部复制、替换掉初始版本就能用)
注意:若上述八个表的名字为小写字母,则下面的表名全部改为小写。如:tpch.REGION ---->tpch.region
-- Sccsid: @(#)dss.ri 2.1.8.1 -- tpch Benchmark Version 8.0 USE tpch; -- ALTER TABLE tpch.REGION DROP PRIMARY KEY; -- ALTER TABLE tpch.NATION DROP PRIMARY KEY; -- ALTER TABLE tpch.PART DROP PRIMARY KEY; -- ALTER TABLE tpch.SUPPLIER DROP PRIMARY KEY; -- ALTER TABLE tpch.PARTSUPP DROP PRIMARY KEY; -- ALTER TABLE tpch.ORDERS DROP PRIMARY KEY; -- ALTER TABLE tpch.LINEITEM DROP PRIMARY KEY; -- ALTER TABLE tpch.CUSTOMER DROP PRIMARY KEY; -- For table REGION ALTER TABLE tpch.REGION ADD PRIMARY KEY (R_REGIONKEY); -- For table NATION ALTER TABLE tpch.NATION ADD PRIMARY KEY (N_NATIONKEY); ALTER TABLE tpch.NATION ADD FOREIGN KEY NATION_FK1 (N_REGIONKEY) references tpch.REGION(R_REGIONKEY); COMMIT WORK; -- For table PART ALTER TABLE tpch.PART ADD PRIMARY KEY (P_PARTKEY); COMMIT WORK; -- For table SUPPLIER ALTER TABLE tpch.SUPPLIER ADD PRIMARY KEY (S_SUPPKEY); ALTER TABLE tpch.SUPPLIER ADD FOREIGN KEY SUPPLIER_FK1 (S_NATIONKEY) references tpch.NATION(N_NATIONKEY); COMMIT WORK; -- For table PARTSUPP ALTER TABLE tpch.PARTSUPP ADD PRIMARY KEY (PS_PARTKEY,PS_SUPPKEY); COMMIT WORK; -- For table CUSTOMER ALTER TABLE tpch.CUSTOMER ADD PRIMARY KEY (C_CUSTKEY); ALTER TABLE tpch.CUSTOMER ADD FOREIGN KEY CUSTOMER_FK1 (C_NATIONKEY) references tpch.NATION(N_NATIONKEY); COMMIT WORK; -- For table LINEITEM ALTER TABLE tpch.LINEITEM ADD PRIMARY KEY (L_ORDERKEY,L_LINENUMBER); COMMIT WORK; -- For table ORDERS ALTER TABLE tpch.ORDERS ADD PRIMARY KEY (O_ORDERKEY); COMMIT WORK; -- For table PARTSUPP ALTER TABLE tpch.PARTSUPP ADD FOREIGN KEY PARTSUPP_FK1 (PS_SUPPKEY) references tpch.SUPPLIER(S_SUPPKEY); COMMIT WORK; ALTER TABLE tpch.PARTSUPP ADD FOREIGN KEY PARTSUPP_FK2 (PS_PARTKEY) references tpch.PART(P_PARTKEY); COMMIT WORK; -- For table ORDERS ALTER TABLE tpch.ORDERS ADD FOREIGN KEY ORDERS_FK1 (O_CUSTKEY) references tpch.CUSTOMER(C_CUSTKEY); COMMIT WORK; -- For table LINEITEM ALTER TABLE tpch.LINEITEM ADD FOREIGN KEY LINEITEM_FK1 (L_ORDERKEY) references tpch.ORDERS(O_ORDERKEY); COMMIT WORK; ALTER TABLE tpch.LINEITEM ADD FOREIGN KEY LINEITEM_FK2 (L_PARTKEY,L_SUPPKEY) references tpch.PARTSUPP(PS_PARTKEY,PS_SUPPKEY); COMMIT WORK; ALTER TABLE CUSTOMER rename to customer; ALTER TABLE LINEITEM rename to lineitem; ALTER TABLE NATION rename to nation; ALTER TABLE ORDERS rename to orders; ALTER TABLE PART rename to part; ALTER TABLE PARTSUPP rename to partsupp; ALTER TABLE REGION rename to region; ALTER TABLE SUPPLIER rename to supplier;
下一步执行如下 命令,添加外键等约束条件
mysql> \. 路径/dss.ri
8:建tpch数据库及表
启动mysql,键入如下命令:
mysql> \. ~/tpch_2_16_1/dbgen/dss.ddl
代码中的 “/tpch_2_16_1” 应被替换为你电脑上,dss.ddl文件的实际位置。
接下来我们使用如下语句查询是否创建成功,一般都没啥问题的。
SHOW DATABASES;
可以看到多了一个tpch名字的数据库,这就是第七步里,我们在dss.ddl开头添加的代码起作用了。
到此我们得到了数据库以及8个空表。接下来开始导入数据。
9:导入数据
低配版:
通过mysql语句,导入数据。比较麻烦,适合我这种渣渣使用:
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/customer.tbl' INTO TABLE customer FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/orders.tbl' INTO TABLE orders FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/lineitem.tbl' INTO TABLE lineitem FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/nation.tbl' INTO TABLE nation FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/partsupp.tbl' INTO TABLE partsupp FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/part.tbl' INTO TABLE part FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/region.tbl' INTO TABLE region FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
LOAD DATA LOCAL INFILE '/root/tpc-h/dbgen/supplier.tbl' INTO TABLE supplier FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';
高配版:
8个表就需要输入执行8条命令,这里joyee写了一个脚本,可以方便的生成sql命令,脚本如下。
在dbgen目录下创建一个load.sh脚本文件:
vi load.sh
将以下代码输入并保存
#!/bin/bash
write_to_file()
{
file="loaddata.sql"
if [ ! -f "$file" ] ; then
touch "$file"
fi
echo 'USE tpch;' >> $file
echo 'SET FOREIGN_KEY_CHECKS=0;' >> $file
DIR=`pwd`
for tbl in `ls *.tbl`; do
table=$(echo "${tbl%.*}")
echo "LOAD DATA LOCAL INFILE '$DIR/$tbl' INTO TABLE $table" >> $file
echo "FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';" >> $file
done
echo 'SET FOREIGN_KEY_CHECKS=1;' >> $file
}
write_to_file
开始执行:
sh load.sh
同目录下就会生成一个loaddata.sql,里面是从8个tbl里导入数据的sql指令。
在dbgen目录下运行
mysql -u root -p < loaddata.sql
即可。
(这里如果运行有问题看看试试joyee说的加上 –local-infile。mysql --local-infile -u root -p < loaddata.sql
)
然后就等等等等等等等.........................................
完毕~以上。
感谢各位大佬的文章。