#数据库--第1章 Windows 下的数据库导入 TPCH 数据(以 SQL Server 作为示例,MySQL同样适用)

#数据库--第1章 Windows 下的数据库导入 TPCH 数据(以 SQL Server 作为示例,MySQL同样适用

一、TPCH 简介

  TPCH是TPC(Transaction Processing Performance Council)组织提供的工具包。用于进行OLAP测试,以评估商业分析中决策支持系统(DSS)的性能。它包含了一整套面向商业的 ad-hoc 查询和并发数据修改,强调测试的是数据库、平台和I/O性能,关注查询能力。
  简单来说,就是用来模拟一个现实中的商业应用,可以生成一堆虚构的数据,且自带一些查询,可以导入到各种数据库中来模拟现实需求,检查性能。

二、TPCH 文件

  请点击 链接 进入百度网盘下载工具包,提取码: 95ud。感兴趣的小伙伴,可以点击进入 TPC 官网 查看,需要翻墙。

三、生成 TPCH 数据


  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。

四、导入 TPCH 数据


  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 基础机器学习系列教程,感兴趣的小伙伴一定要去主页看看呀~

  • 32
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值