TPCH是TPC(Transaction Processing Performance Council)组织提供的工具包。用于进行OLAP测试,以评估商业分析中决策支持系统(DSS)的性能。它包含了一整套面向商业的 ad-hoc 查询和并发数据修改,强调测试的是数据库、平台和I/O性能,关注查询能力。
简单来说,就是用来模拟一个现实中的商业应用,可以生成一堆虚构的数据,且自带一些查询,可以导入到各种数据库中来模拟现实需求,检查性能。
请点击 链接 进入百度网盘下载工具包,提取码: 95ud。感兴趣的小伙伴,可以点击进入 TPC 官网 查看,需要。
1、将下载的压缩包解压,进入 dbgen,往下翻,找到一个名为 tpch.sln 的文件,这是 Visual Studio 的工程文件,请读者先下载 Visual Studio 后打开工程。打开后如图所示:
2、选择 生成 -> 生成 dbgen 即可编译生成可执行文件,待完成之后,就可以关闭 Visual Studio 了
3、在 dbgen 中,找到 makefile.suite 文件,作为 文本文件打开它,往下划到 103 行,修改 CC=gcc ,DATABASE=SQLSERVER,MACHINE=WIN32,WORKLOAD=TPCH,保存退出,如图所示:
4、将 dbgen\Debug 目录下的 dbgen.exe 复制到 dbgen,打开 cmd 窗口,切换到 dbgen 目录,如图所示:
5、输入命令 dbgen -vf -s 1 ,-s 后面的数字参数即为生成的数据大小,1 为生成 1G 数据,0.1 生成 0.1 G 数据…回车,等待完成。
生成的数据文件在 dbgen 目录下,以 .tbl 结尾,可以作为文本文件打开查看里面的数据,至此,数据的生成已经完成,接下来我们要做的就是将它们导入到 Sql Server。
6、运行 Sql Server Management Studio,依次打开:安全性 -> 登录名 -> sa,修改并记住 sa 密码,待会儿要用,然后修改用户映射和状态。(My SQL 用户自行百度如何查看用户名和密码,端口默认为 3306)。如下图所示:
7.1、运行 Sql Server 配置管理器
7.2、依次打开 SQL Server 网络配置 -> MSSQLSERVER 的协议,鼠标右键启用 TCP/IP 协议
7.3、双击打开 TCP/IP,找到 IP 地址为 127.0.0.1 的项,将 ”活动“改为”是“,”已启用“改为”是“,其它不动,并记下端口号是多少,待会儿要用,保存退出,重启电脑。
7.4、运行 Sql Server Management Studio,选择SQL Server身份验证,输入账号密码,连接,若能连接成功就可以继续往下了,若连接失败,请仔细检查上述操作过程或百度,直到能够连接上去。
8.1、创建 TPCH 数据库。
drop database if exists TPCH;
create database TPCH;
8.2、创建 TPCH 相关表
use TPCH;
-- 零件表
create table PART(
P_PARTKEY integer not null primary key, -- 零件号,主键
P_NAME varchar(55) not null, -- 零件名称
P_MFGR char(25) not null, -- 制造商名称
P_BRAND char(10) not null, -- 品牌
P_TYPE varchar(25) not null, -- 类型
P_SIZE integer not null, -- 尺寸
P_CONTAINER char(10) not null, -- 包装
P_RETAILPRICE decimal(15,2) not null, -- 零售价格
P_COMMENT varchar(200) null -- 备注
);
-- 供应商表
create table SUPPLIER(
S_SUPPKEY integer not null primary key, -- 供应商号,主键
S_NAME char(25) not null, -- 名称
S_ADDRESS varchar(40) not null, -- 地址
S_NATIONKEY integer not null, -- 国家代码
S_PHONE char(15) not null, -- 国际电话,例:011-86-755-86285739
S_ACCTBAL decimal(15,2) not null, -- 账户余额
S_COMMENT varchar(200) null -- 备注
);
-- 供应商-零件表
create table PARTSUPP(
PS_PARTKEY integer not null references PART(P_PARTKEY), -- Foreign Key to P_PARTKEY
PS_SUPPKEY integer not null references SUPPLIER(S_SUPPKEY), -- Foreign Key to S_SUPPKEY
PS_AVAILQTY integer not null, -- 可用数量
PS_SUPPLYCOST decimal(15,2) not null, -- 供应价格
PS_COMMENT varchar(200) null, -- 备注
primary key(PS_PARTKEY, PS_SUPPKEY)
);
-- 地区表
create table REGION(
R_REGIONKEY integer not null primary key, -- 地区表主键,5 regions are populated
R_NAME char(25) not null, -- 地区名称
R_COMMENT varchar(200) null -- 备注
);
-- 国家表
create table NATION(
N_NATIONKEY integer not null primary key, -- 国家表主键,25 nations are populated
N_NAME char(25) not null, -- 国家名称
N_REGIONKEY integer not null references REGION(R_REGIONKEY), -- Foreign Key to R_REGIONKEY
N_COMMENT varchar(200) null -- 备注
);
-- 客户表
create table CUSTOMER(
C_CUSTKEY integer not null primary key, -- 客户表主键,SF*150,000 are populated
C_NAME varchar(25) not null, -- 顾客姓名
C_ADDRESS varchar(40) not null, -- 地址
C_NATIONKEY integer not null references NATION(N_NATIONKEY), -- Foreign Key to N_NATIONKEY
C_PHONE char(15) not null, -- 国际电话,例:011-86-755-86285739
C_ACCTBAL decimal(15,2) not null, -- 账户余额
C_MKTSEGMENT char(10) not null, -- 市场区块(如中国区、南美区、北美区等)
C_COMMENT varchar(200) null -- 备注
);
-- 订单表
create table ORDERS(
O_ORDERKEY integer not null primary key, -- 订单表主键
O_CUSTKEY integer not null references CUSTOMER(C_CUSTKEY), -- Foreign Key to C_CUSTKEY
O_ORDERSTATUS char(1) not null, -- 订单状态
O_TOTALPRICE decimal(15,2) not null, -- 总金额
O_ORDERDATE date not null, -- 订单日期
O_ORDERPRIORITY char(15) not null, -- 订单优先级
O_CLERK char(15) not null, -- 记账员
O_SHIPPRIORITY integer not null, -- 装运优先级
O_COMMENT varchar(100) null -- 备注
);
-- 订单明细
create table LINEITEM(
L_ORDERKEY integer not null references ORDERS(O_ORDERKEY), -- Foreign Key to O_ORDERKEY
L_PARTKEY integer not null references PART(P_PARTKEY), -- Foreign key to P_PARTKEY
L_SUPPKEY integer not null references SUPPLIER(S_SUPPKEY), -- Foreign key to S_SUPPKEY
L_LINENUMBER integer not null, -- 订单明细号
L_QUANTITY decimal(15,2) not null, -- 数量
L_EXTENDEDPRICE decimal(15,2) not null, -- 金额 (L_EXTENDEDPRICE = L_QUANTITY * P_RETAILPRICE)
L_DISCOUNT decimal(15,2) not null, -- 折扣
L_TAX decimal(15,2) not null, -- 税率
L_RETURNFLAG char(1) not null, -- 退货标志(If L_RECEIPTDATE <= CURRENTDATE then either "R" or "A" is selected at random else "N" is selected)
L_LINESTATUS char(1) not null, -- 明细状态("O" if L_SHIPDATE > CURRENTDATE "F" otherwise)
L_SHIPDATE date not null, -- 装运日期
L_COMMITDATE date not null, -- 委托日期
L_RECEIPTDATE date not null, -- 签收日期
L_SHIPINSTRUCT char(25) not null, -- 装运说明(如deliver in person)
L_SHIPMODE char(10) not null, -- 装运方式(如空运,陆运,海运)
L_COMMENT varchar(100) null, -- 备注
primary key(L_ORDERKEY, L_LINENUMBER)
);
9、这里我们使用 Python 将数据导入至 SQL Server,读者先用 pip 下载 pandas 和 pymssql (如果是 My SQL 用户则下载 pymysql)这两个包。然后将下面的代码稍作修改并运行,即可完成数据导入,如果代码导入失败,可以尝试降低数据量,或者复制 sql.txt 里的 sql 语句到 Sql Server (My SQL)内进行。
import pymssql # 如果是 My SQL 用户则应为 pymysql,其余代码不变
import pandas as pd
import sys
import os
def load_data(path):
"""
加载文件数据
:param path: 文件所在路径
:return: 返回数据
"""
data = {}
columns = {"PART": ["P_PARTKEY", "P_NAME", "P_MFGR", "P_BRAND", "P_TYPE", "P_SIZE", "P_CONTAINER", "P_RETAILPRICE",
"P_COMMENT"],
"SUPPLIER": ["S_SUPPKEY", "S_NAME", "S_ADDRESS", "S_NATIONKEY", "S_PHONE", "S_ACCTBAL", "S_COMMENT"],
"PARTSUPP": ["PS_PARTKEY", "PS_SUPPKEY", "PS_AVAILQTY", "PS_SUPPLYCOST", "PS_COMMENT"],
"REGION": ["R_REGIONKEY", "R_NAME", "R_COMMENT"],
"NATION": ["N_NATIONKEY", "N_NAME", "N_REGIONKEY", "N_COMMENT"],
"CUSTOMER": ["C_CUSTKEY", "C_NAME", "C_ADDRESS", "C_NATIONKEY", "C_PHONE", "C_ACCTBAL", "C_MKTSEGMENT",
"C_COMMENT"],
"ORDERS": ["O_ORDERKEY", "O_CUSTKEY", "O_ORDERSTATUS", "O_TOTALPRICE", "O_ORDERDATE", "O_ORDERPRIORITY",
"O_CLERK", "O_SHIPPRIORITY", "O_COMMENT"],
"LINEITEM": ["L_ORDERKEY", "L_PARTKEY", "L_SUPPKEY", "L_LINENUMBER", "L_QUANTITY", "L_EXTENDEDPRICE",
"L_DISCOUNT", "L_TAX"
, "L_RETURNFLAG", "L_LINESTATUS", "L_SHIPDATE", "L_COMMITDATE", "L_RECEIPTDATE", "L_SHIPINSTRUCT",
"L_SHIPMODE", "L_COMMENT"]}
for file in os.listdir(path):
if file.endswith(".tbl"):
name = file.split('.')[0].upper()
d = pd.read_csv(path + "\\" + file, sep='|', header=None)
d.drop(columns=d.shape[1] - 1, inplace=True)
d.columns = columns[name]
data.update({name: d})
return data
def connect_sql_server(host=None, username=None, password=None):
"""
连接 Sql Server 数据库
:param host: ip和端口
:param username: 登录账号
:param password: 登录密码
:return: 返回数据库连接
"""
connect = pymssql.connect(host=host, user=username, password=password, database='TPCH')
if connect:
print("connect success.")
return connect
else:
print("connect fail.")
return None
def insert(data, cursor):
"""
将数据导入 Sql Server
:param data: 待导入数据
:param cursor: Sql Server 游标
"""
sqls = {}
# 执行顺序,要先执行被引用的表
order = ["REGION", "NATION", "CUSTOMER", "ORDERS", "PART", "SUPPLIER", "PARTSUPP", "LINEITEM"]
for key in data:
sql = []
for t in [tuple(i) for i in data[key].values]:
s = "insert into " + key + str(tuple(data[key].columns)).replace('\'', '') + " values" + str(t) + ";"
sql.append(s)
sqls.update({key: sql})
with open("sql.txt", 'w') as f:
for key in order:
le = len(sqls[key])
sys.stdout.write('\'' + key + '\'' + " 进度: ")
for s in range(le):
try:
cursor.execute(sqls[key][s])
# 将执行成功的 Sql 语句保存至文件中
f.write(sqls[key][s] + "\n")
except:
pass
sys.stdout.write("\b\b\b\b\b% 3d %%" % int((s+1)*100/le))
f.write("\n\n")
print("\n" + key + " has done.")
if __name__ == "__main__":
# 填写自己的路径
data = load_data(r"D:\Download\TPC-H-Tool\2.18.0_rc2\dbgen")
# 填写自己的IP端口,账号,密码,如果是 MySQL 用户,IP和端口可以忽略不写
connect = connect_sql_server('127.0.0.1:1433', 'sa', 'root')
if connect:
# 获得数据库游标
cursor = connect.cursor()
# 执行插入
insert(data, cursor)
# 提交事务
connect.commit()
# 关闭游标
cursor.close()
# 关闭连接
connect.close()
原创不易,请点个赞再走呗~,如果能关注一下博主,那再好不过啦!博主目前在更新 0 基础机器学习系列教程,感兴趣的小伙伴一定要去主页看看呀~