#数据库原理--Windows 下 Sql Server 导入 TPCH 数据

#数据库原理--Windows下 Sql Server 导入 TPCH 数据

一、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 密码,待会儿要用,如果已经知道 sa 密码的读者可以跳过这一步。


  7.1、运行 Sql Server 配置管理器

  7.2、依次打开 SQL Server 网络配置 -> MSSQLSERVER 的协议,鼠标右键启用 TCP/IP 协议

  7.3、双击打开 TCP/IP,找到 IP 地址为 127.0.0.1 的项,将 ”活动“改为”是“,”已启用“改为”是“,其它不动,并记下端口号是多少,待会儿要用,保存退出,重启电脑


  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 这两个包。然后将下面的代码稍作修改并运行,即可完成数据导入,如果代码导入失败,可以尝试降低数据量,或者复制 sql.txt 里的 sql 语句到 Sql Server 内进行。

import pymssql
import pandas as pd
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, username, password):
    """
    连接 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"]
    with open("sql.txt", 'w') as f:
        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)
                # 将 Sql 语句保存至文件中
                f.write(s + "\n")
            f.write("\n\n")
            sqls.update({key: sql})
    for key in order:
        le = len(sqls[key])
        for s in range(le):
            try:
                cursor.execute(sqls[key][s])
            except:
                pass
            if s % 100 is 0:
                print('\'' + key + '\'' + " 进度:" + str(s / le * 100))
        print(key + " has done.")


if __name__ == "__main__":
    # 填写自己的路径
    data = load_data(r"D:\Download\TPC-H-Tool\2.18.0_rc2\dbgen")
    # 填写自己的IP端口,账号,密码
    connect = connect_sql_server('127.0.0.1:1433', 'sa', 'root')
    if connect:
        # 获得 Sql Server 游标
        cursor = connect.cursor()
        # 执行插入
        insert(data, cursor)
        # 提交事务
        connect.commit()
        # 关闭游标
        cursor.close()
        # 关闭连接
        connect.close()

原创不易,请点个赞再走呗~,如果能关注一下博主,那再好不过啦!博主目前在更新 0 基础机器学习系列教程,感兴趣的小伙伴一定要去主页看看呀~

发布了14 篇原创文章 · 获赞 50 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_43519779/article/details/105601470