Запросы Memsql TPCH

Я пытаюсь выполнить запросы TPCH DDL на memsql. Я новичок в memsql. Я не могу преобразовать 5 запросов TPCH ddl sql в запросы memsql. Невозможно установить отношение внешнего ключа с помощью концепции FOREIGH SHARD KEY в memsql. Пожалуйста, помогите мне преобразовать ниже 5 из 8 запросов на создание таблиц в запросы memsql. Очень старался, но столкнулся с множеством разных проблем.

CREATE TABLE REGION  ( R_REGIONKEY  INTEGER NOT NULL PRIMARY KEY,
                   R_NAME       CHAR(25) NOT NULL,
                   R_COMMENT    VARCHAR(152)
                   );

CREATE TABLE NATION  ( N_NATIONKEY  INTEGER NOT NULL PRIMARY KEY,
                   N_NAME       CHAR(25) NOT NULL,
                   N_REGIONKEY  INTEGER NOT NULL REFERENCES REGION(R_REGIONKEY),
                   N_COMMENT    VARCHAR(152)
                   );

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(23) NOT 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 REFERENCES NATION(N_NATIONKEY),
                    S_PHONE       CHAR(15) NOT NULL,
                    S_ACCTBAL     DECIMAL(15,2) NOT NULL,
                    S_COMMENT     VARCHAR(101) NOT NULL
                    );

CREATE TABLE PARTSUPP ( PS_PARTKEY     INTEGER NOT NULL REFERENCES PART(P_PARTKEY),
                    PS_SUPPKEY     INTEGER NOT NULL REFERENCES SUPPLIER(S_SUPPKEY),
                    PS_AVAILQTY    INTEGER NOT NULL,
                    PS_SUPPLYCOST  DECIMAL(15,2)  NOT NULL,
                    PS_COMMENT     VARCHAR(199) NOT NULL,
                    PRIMARY KEY (PS_PARTKEY, PS_SUPPKEY)
                    );

CREATE TABLE CUSTOMER ( C_CUSTKEY     INTEGER NOT NULL PRIMARY KEY,
                    C_NAME        VARCHAR(25) NOT NULL,
                    C_ADDRESS     VARCHAR(40) NOT NULL,
                    C_NATIONKEY   INTEGER NOT NULL REFERENCES NATION(N_NATIONKEY),
                    C_PHONE       CHAR(15) NOT NULL,
                    C_ACCTBAL     DECIMAL(15,2)   NOT NULL,
                    C_MKTSEGMENT  CHAR(10) NOT NULL,
                    C_COMMENT     VARCHAR(117) NOT NULL
                    );

CREATE TABLE ORDERS  ( O_ORDERKEY       INTEGER NOT NULL PRIMARY KEY,
                   O_CUSTKEY        INTEGER NOT NULL REFERENCES CUSTOMER(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(79) NOT NULL
                   );

CREATE TABLE LINEITEM ( L_ORDERKEY    INTEGER NOT NULL REFERENCES ORDERS(O_ORDERKEY),
                    L_PARTKEY     INTEGER NOT NULL REFERENCES PART(P_PARTKEY),
                    L_SUPPKEY     INTEGER NOT NULL REFERENCES SUPPLIER(S_SUPPKEY),
                    L_LINENUMBER  INTEGER NOT NULL,
                    L_QUANTITY    DECIMAL(15,2) NOT NULL,
                    L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
                    L_DISCOUNT    DECIMAL(15,2) NOT NULL,
                    L_TAX         DECIMAL(15,2) NOT NULL,
                    L_RETURNFLAG  CHAR(1) NOT NULL,
                    L_LINESTATUS  CHAR(1) NOT NULL,
                    L_SHIPDATE    DATE NOT NULL,
                    L_COMMITDATE  DATE NOT NULL,
                    L_RECEIPTDATE DATE NOT NULL,
                    L_SHIPINSTRUCT CHAR(25) NOT NULL,
                    L_SHIPMODE     CHAR(10) NOT NULL,
                    L_COMMENT      VARCHAR(44) NOT NULL,
                    PRIMARY KEY (L_ORDERKEY,L_LINENUMBER),
                    FOREIGN KEY (L_PARTKEY,L_SUPPKEY) REFERENCES PARTSUPP(PS_PARTKEY, PS_SUPPKEY)
                    );                                                     

Я могу создать первые 3 таблицы в memsql, но не могу остальные таблицы. 1-й и 3-й запросы очень просты и работают как есть. Я могу создать вторую таблицу, но опять же не уверен, что это правильный путь.

CREATE TABLE NATION  ( N_NATIONKEY  INTEGER NOT NULL,
                   N_NAME       CHAR(25) NOT NULL,
                   N_REGIONKEY  INTEGER NOT NULL,
                   N_COMMENT    VARCHAR(152),
                   FOREIGN SHARD KEY (N_REGIONKEY) REFERENCES REGION (R_REGIONKEY), 
           PRIMARY KEY (N_NATIONKEY, N_REGIONKEY)
                   );

Возможно ли создать в memsql только таблицу репликации, а не раздел? и как?


person Kishor Bachhav    schedule 24.09.2015    source источник


Ответы (1)


Поскольку MemSQL не поддерживает ссылочную целостность, внешние осколочные ключи являются вспомогательным средством оптимизации и не являются обязательными. Однако внешние ключи сегментов позволяют вам узнать во время создания таблицы, что две таблицы могут быть объединены локально (без сетевого трафика) по этому ключу. Однако оптимизатору не требуются внешние ключи осколков, чтобы воспользоваться преимуществом этой локализации данных.

Начиная с таблиц ORDERS и LINEITEM:

CREATE TABLE ORDERS  ( O_ORDERKEY       INTEGER NOT NULL PRIMARY KEY,
               O_CUSTKEY        INTEGER NOT NULL,
               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(79) NOT NULL,
               KEY (O_CUSTKEY)
               );

CREATE TABLE LINEITEM ( L_ORDERKEY    INTEGER NOT NULL,
                L_PARTKEY     INTEGER NOT NULL,
                L_SUPPKEY     INTEGER NOT NULL,
                L_LINENUMBER  INTEGER NOT NULL,
                L_QUANTITY    DECIMAL(15,2) NOT NULL,
                L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
                L_DISCOUNT    DECIMAL(15,2) NOT NULL,
                L_TAX         DECIMAL(15,2) NOT NULL,
                L_RETURNFLAG  CHAR(1) NOT NULL,
                L_LINESTATUS  CHAR(1) NOT NULL,
                L_SHIPDATE    DATE NOT NULL,
                L_COMMITDATE  DATE NOT NULL,
                L_RECEIPTDATE DATE NOT NULL,
                L_SHIPINSTRUCT CHAR(25) NOT NULL,
                L_SHIPMODE     CHAR(10) NOT NULL,
                L_COMMENT      VARCHAR(44) NOT NULL,
                PRIMARY KEY (L_ORDERKEY,L_LINENUMBER),
                FOREIGN SHARD KEY (L_ORDERKEY) REFERENCES ORDERS (O_ORDERKEY),
                KEY (L_PARTKEY),
                KEY (L_SUPPKEY)
                );  

В этом случае мы знаем, что можем воспользоваться локальным соединением между ORDERS и LINEITEM, потому что они оба разделены на ORDERKEY. ORDERS и LINEITEM — две самые большие таблицы в TPCH, поэтому мы хотим убедиться, что их можно объединить локально. Поскольку первичным ключом ORDERS является O_ORDERKEY, мне не нужно указывать ключ сегмента для ORDERS. MemSQL будет сегментирован на O_ORDERKEY автоматически.

Я также поместил вторичные индексы в оставшиеся столбцы внешнего ключа. Это полезно, так как будут соединения по внешним ключам.

Применяя эти концепции к PART, PARTSUPP, SUPPLIER и CUSTOMER:

CREATE TABLE CUSTOMER ( C_CUSTKEY     INTEGER NOT NULL PRIMARY KEY,
                C_NAME        VARCHAR(25) NOT NULL,
                C_ADDRESS     VARCHAR(40) NOT NULL,
                C_NATIONKEY   INTEGER NOT NULL,
                C_PHONE       CHAR(15) NOT NULL,
                C_ACCTBAL     DECIMAL(15,2)   NOT NULL,
                C_MKTSEGMENT  CHAR(10) NOT NULL,
                C_COMMENT     VARCHAR(117) NOT NULL,
                KEY(C_NATIONKEY)
                );


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,
                S_ACCTBAL     DECIMAL(15,2) NOT NULL,
                S_COMMENT     VARCHAR(101) NOT NULL,
                KEY(S_NATIONKEY)
                );

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(23) NOT NULL
             );

CREATE TABLE PARTSUPP ( PS_PARTKEY     INTEGER NOT NULL,
                PS_SUPPKEY     INTEGER NOT NULL,
                PS_AVAILQTY    INTEGER NOT NULL,
                PS_SUPPLYCOST  DECIMAL(15,2)  NOT NULL,
                PS_COMMENT     VARCHAR(199) NOT NULL,
                PRIMARY KEY (PS_PARTKEY, PS_SUPPKEY),
                SHARD KEY(PS_PARTKEY),
                KEY(PS_SUPPKEY)
                );

Хотя PARTSUPP и PART разделены на один и тот же ключ (PARTKEY), мне не нужно указывать внешний ключ сегмента, чтобы воспользоваться локальным соединением между ними по этому ключу; оптимизатор подберет это автоматически.

Отвечая на ваш последний вопрос, MemSQL позволяет создавать реплицированные таблицы вместо секционированных. Это называется справочной таблицей и будет полезно для NATION и REGION таблиц, так как они очень маленькие. Справочные таблицы не нужны для выполнения распределенных запросов, но являются полезной оптимизацией.

CREATE REFERENCE TABLE REGION  ( R_REGIONKEY  INTEGER NOT NULL PRIMARY KEY,
               R_NAME       CHAR(25) NOT NULL,
               R_COMMENT    VARCHAR(152)
               );

CREATE REFERENCE TABLE NATION  ( N_NATIONKEY  INTEGER NOT NULL PRIMARY KEY,
               N_NAME       CHAR(25) NOT NULL,
               N_REGIONKEY  INTEGER NOT NULL,
               N_COMMENT    VARCHAR(152)
               );

Для получения дополнительной документации по всему описанному посетите: http://docs.memsql.com/latest/concepts/distributed_sql/

person Rob Walzer    schedule 24.09.2015
comment
Спасибо, Роб, за запросы memsql с подробным объяснением. Я попробую их на своем кластере memsql. - person Kishor Bachhav; 25.09.2015
comment
Как можно добиться ссылочной целостности между таблицей региона и страны. NATION'S N_REGIONKEY определяется как внешний ключ для ключа REGION R_REGION'. - person Kishor Bachhav; 15.10.2015