Análise de status de operações de uma loja de departamento de varejo
Conhecimento de fundo
Nesta prática, os dados de negócios diários de cada loja de varejo são carregados do OBS para a tabela correspondente no cluster de armazém de dados para resumir e consultar KPIs. Esses dados incluem a rotatividade da loja, o fluxo de clientes, a classificação mensal de vendas, a taxa de conversão mensal do fluxo de clientes, índice mensal de preço-aluguel e as vendas por unidade de área. Este exemplo demonstra a consulta e análise multidimensional do GaussDB(DWS) no cenário de varejo.
Os dados de amostra foram carregados na pasta retail-data em um bucket do OBS, e todas as contas da Huawei Cloud receberam a permissão somente leitura para acessar o bucket do OBS.
Procedimento geral
Essa prática leva cerca de 60 minutos. O procedimento é os seguintes:
Regiões suportadas
Tabela 1 descreve as regiões onde os dados do OBS foram carregados.
Região |
Bucket de OBS |
---|---|
CN North-Beijing1 |
dws-demo-cn-north-1 |
CN North-Beijing2 |
dws-demo-cn-north-2 |
CN North-Beijing4 |
dws-demo-cn-north-4 |
CN North-Ulanqab1 |
dws-demo-cn-north-9 |
CN East-Shanghai1 |
dws-demo-cn-east-3 |
CN East-Shanghai2 |
dws-demo-cn-east-2 |
CN South-Guangzhou |
dws-demo-cn-south-1 |
CN South-Guangzhou-InvitationOnly |
dws-demo-cn-south-4 |
CN-Hong Kong |
dws-demo-ap-southeast-1 |
AP-Singapore |
dws-demo-ap-southeast-3 |
AP-Bangkok |
dws-demo-ap-southeast-2 |
LA-Santiago |
dws-demo-la-south-2 |
AF-Johannesburg |
dws-demo-af-south-1 |
LA-Mexico City1 |
dws-demo-na-mexico-1 |
LA-Mexico City2 |
dws-demo-la-north-2 |
RU-Moscow2 |
dws-demo-ru-northwest-2 |
LA-Sao Paulo1 |
dws-demo-sa-brazil-1 |
Preparativos
- Você registrou uma conta do GaussDB(DWS), e a conta não está em atraso ou congelada.
- Você obteve o AK e SK da conta.
- Um cluster foi criado e conectado usando o Data Studio. Para mais detalhes, veja Passo 1: criar um cluster e Passo 2: usar o Data Studio para conectar-se a um cluster.
Passo 1: importar dados de amostra da loja de departamento de varejo
Depois de se conectar ao cluster usando a ferramenta de cliente SQL, execute as seguintes operações na ferramenta de cliente SQL para importar os dados de amostra de lojas de departamento de varejo e executar consultas.
- Execute a instrução a seguir para criar o banco de dados retail:
1
CREATE DATABASE retail encoding 'utf8' template template0;
- Execute as seguintes etapas para alternar para o novo banco de dados:
- Na janela Object Browser do cliente do Data Studio, clique com o botão direito do mouse na conexão de banco de dados e selecione Refresh no menu de atalho. Em seguida, o novo banco de dados é exibido.
- Clique com o botão direito do mouse no nome do novo banco de dados retail e escolha Connect to DB no menu de atalho.
- Clique com o botão direito do mouse no nome do novo banco de dados retail e escolha Open Terminal no menu de atalho. A janela de comando SQL para conexão com o banco de dados especificado é exibida. Execute os seguintes passos na janela.
- Crie uma tabela de banco de dados.
Os dados de amostra consistem em 10 tabelas de banco de dados cujas associações são mostradas em Figura 1.
Copie e execute as seguintes instruções para alternar para criar uma tabela de banco de dados de informações de lojas de departamento de varejo.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
CREATE SCHEMA retail_data; SET current_schema='retail_data'; DROP TABLE IF EXISTS STORE; CREATE TABLE STORE ( ID INT, STORECODE VARCHAR(10), STORENAME VARCHAR(100), FIRMID INT, FLOOR INT, BRANDID INT, RENTAMOUNT NUMERIC(18,2), RENTAREA NUMERIC(18,2) ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS POS; CREATE TABLE POS( ID INT, POSCODE VARCHAR(20), STATUS INT, MODIFICATIONDATE DATE ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS BRAND; CREATE TABLE BRAND ( ID INT, BRANDCODE VARCHAR(10), BRANDNAME VARCHAR(100), SECTORID INT ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS SECTOR; CREATE TABLE SECTOR( ID INT, SECTORCODE VARCHAR(10), SECTORNAME VARCHAR(20), CATEGORYID INT ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS CATEGORY; CREATE TABLE CATEGORY( ID INT, CODE VARCHAR(10), NAME VARCHAR(20) ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS FIRM; CREATE TABLE FIRM( ID INT, CODE VARCHAR(4), NAME VARCHAR(40), CITYID INT, CITYNAME VARCHAR(10), CITYCODE VARCHAR(20) ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS DATE; CREATE TABLE DATE( ID INT, DATEKEY DATE, YEAR INT, MONTH INT, DAY INT, WEEK INT, WEEKDAY INT ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS PAYTYPE; CREATE TABLE PAYTYPE( ID INT, CODE VARCHAR(10), TYPE VARCHAR(10), SIGNDATE DATE ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY REPLICATION; DROP TABLE IF EXISTS SALES; CREATE TABLE SALES( ID INT, POSID INT, STOREID INT, DATEKEY INT, PAYTYPE INT, TOTALAMOUNT NUMERIC(18,2), DISCOUNTAMOUNT NUMERIC(18,2), ITEMCOUNT INT, PAIDAMOUNT NUMERIC(18,2) ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY HASH(ID); DROP TABLE IF EXISTS FLOW; CREATE TABLE FLOW ( ID INT, STOREID INT, DATEKEY INT, INFLOWVALUE INT ) WITH (ORIENTATION = COLUMN, COMPRESSION=MIDDLE) DISTRIBUTE BY HASH(ID);
- Crie uma tabela estrangeira, que é usada para identificar e associar os dados de origem no OBS.
- <obs_bucket_name> indica o nome do bucket do OBS. Apenas algumas regiões são suportadas. Para obter detalhes sobre as regiões suportadas e os nomes dos bucket do OBS, consulte Regiões suportadas. Os clusters do GaussDB(DWS) não oferecem suporte ao acesso entre regiões aos dados do bucket do OBS.
- Nesta prática, a região CN-Hong Kong é usada como exemplo. Digite dws-demo-ap-southeast-1 e substitua <Access_Key_Id> e <Secret_Access_Key> pelo valor obtido em Preparativos.
- // AK e SK codificados rigidamente ou em texto não criptografado são arriscados. Para fins de segurança, criptografe seu AK e SK e armazene-os no arquivo de configuração ou nas variáveis de ambiente.
- Se a mensagem"ERROR: schema "xxx" does not exist Position" for exibida quando você criar uma tabela estrangeira, o esquema não existe. Execute a etapa anterior para criar um esquema.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
CREATE SCHEMA retail_obs_data; SET current_schema='retail_obs_data'; DROP FOREIGN table if exists SALES_OBS; CREATE FOREIGN TABLE SALES_OBS ( like retail_data.SALES ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/sales', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists FLOW_OBS; CREATE FOREIGN TABLE FLOW_OBS ( like retail_data.flow ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/flow', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists BRAND_OBS; CREATE FOREIGN TABLE BRAND_OBS ( like retail_data.brand ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/brand', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists CATEGORY_OBS; CREATE FOREIGN TABLE CATEGORY_OBS ( like retail_data.category ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/category', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists DATE_OBS; CREATE FOREIGN TABLE DATE_OBS ( like retail_data.date ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/date', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists FIRM_OBS; CREATE FOREIGN TABLE FIRM_OBS ( like retail_data.firm ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/firm', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists PAYTYPE_OBS; CREATE FOREIGN TABLE PAYTYPE_OBS ( like retail_data.paytype ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/paytype', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists POS_OBS; CREATE FOREIGN TABLE POS_OBS ( like retail_data.pos ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/pos', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists SECTOR_OBS; CREATE FOREIGN TABLE SECTOR_OBS ( like retail_data.sector ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/sector', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' ); DROP FOREIGN table if exists STORE_OBS; CREATE FOREIGN TABLE STORE_OBS ( like retail_data.store ) SERVER gsmpp_server OPTIONS ( encoding 'utf8', location 'obs://<obs_bucket_name>/retail-data/store', format 'csv', delimiter ',', access_key '<Access_Key_Id>', secret_access_key '<Secret_Access_Key>', chunksize '64', IGNORE_EXTRA_DATA 'on', header 'on' );
- Copie e execute as seguintes instruções para importar os dados da tabela externa para o cluster:
1 2 3 4 5 6 7 8 9 10
INSERT INTO retail_data.store SELECT * FROM retail_obs_data.STORE_OBS; INSERT INTO retail_data.sector SELECT * FROM retail_obs_data.SECTOR_OBS; INSERT INTO retail_data.paytype SELECT * FROM retail_obs_data.PAYTYPE_OBS; INSERT INTO retail_data.firm SELECT * FROM retail_obs_data.FIRM_OBS; INSERT INTO retail_data.flow SELECT * FROM retail_obs_data.FLOW_OBS; INSERT INTO retail_data.category SELECT * FROM retail_obs_data.CATEGORY_OBS; INSERT INTO retail_data.date SELECT * FROM retail_obs_data.DATE_OBS; INSERT INTO retail_data.pos SELECT * FROM retail_obs_data.POS_OBS; INSERT INTO retail_data.brand SELECT * FROM retail_obs_data.BRAND_OBS; INSERT INTO retail_data.sales SELECT * FROM retail_obs_data.SALES_OBS;
Leva algum tempo para importar dados.
- Copie e execute a instrução a seguir para criar a exibição v_sales_flow_details:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
SET current_schema='retail_data'; CREATE VIEW v_sales_flow_details AS SELECT FIRM.ID FIRMID, FIRM.NAME FIRNAME, FIRM. CITYCODE, CATEGORY.ID CATEGORYID, CATEGORY.NAME CATEGORYNAME, SECTOR.ID SECTORID, SECTOR.SECTORNAME, BRAND.ID BRANDID, BRAND.BRANDNAME, STORE.ID STOREID, STORE.STORENAME, STORE.RENTAMOUNT, STORE.RENTAREA, DATE.DATEKEY, SALES.TOTALAMOUNT, DISCOUNTAMOUNT, ITEMCOUNT, PAIDAMOUNT, INFLOWVALUE FROM SALES INNER JOIN STORE ON SALES.STOREID = STORE.ID INNER JOIN FIRM ON STORE.FIRMID = FIRM.ID INNER JOIN BRAND ON STORE.BRANDID = BRAND.ID INNER JOIN SECTOR ON BRAND.SECTORID = SECTOR.ID INNER JOIN CATEGORY ON SECTOR.CATEGORYID = CATEGORY.ID INNER JOIN DATE ON SALES.DATEKEY = DATE.ID INNER JOIN FLOW ON FLOW.DATEKEY = DATE.ID AND FLOW.STOREID = STORE.ID;
Passo 2: executar análise de status de operações
O seguinte usa a consulta padrão de informações de varejo de lojas de departamento como um exemplo para demonstrar como executar a consulta básica de dados no GaussDB(DWS).
Antes de consultar dados, execute o comando Analyze para gerar estatísticas relacionadas à tabela do banco de dados. Os dados de estatísticas são armazenados na tabela do sistema PG_STATISTIC e são úteis quando você executa o planejador, o que fornece um plano de execução de consulta eficiente.
A seguir estão exemplos de consulta:
- Consultar a receita mensal de vendas de cada loja
Copie e execute as seguintes instruções para consultar a receita total de cada loja em um determinado mês:
1 2 3 4 5 6 7 8
SET current_schema='retail_data'; SELECT DATE_TRUNC('month',datekey) AT TIME ZONE 'UTC' AS __timestamp, SUM(paidamount) AS sum__paidamount FROM v_sales_flow_details GROUP BY DATE_TRUNC('month',datekey) AT TIME ZONE 'UTC' ORDER BY SUM(paidamount) DESC;
- Consultar a receita de vendas e a relação preço-aluguel de cada loja
Copie e execute a seguinte instrução para consultar a receita de vendas e a relação de preço-aluguel de cada loja:
1 2 3 4 5 6 7 8 9 10
SET current_schema='retail_data'; SELECT firname AS firname, storename AS storename, SUM(paidamount) AS sum__paidamount, AVG(RENTAMOUNT)/SUM(PAIDAMOUNT) AS rentamount_sales_rate FROM v_sales_flow_details GROUP BY firname, storename ORDER BY SUM(paidamount) DESC;
- Analisar a receita de vendas de cada cidade
Copie e execute a seguinte instrução para analisar e consultar a receita de vendas de todas as províncias:
1 2 3 4 5 6 7
SET current_schema='retail_data'; SELECT citycode AS citycode, SUM(paidamount) AS sum__paidamount FROM v_sales_flow_details GROUP BY citycode ORDER BY SUM(paidamount) DESC;
- Analisar e comparando a relação de preço-aluguel e a taxa de conversão do fluxo de clientes de cada loja
1 2 3 4 5 6 7 8 9
SET current_schema='retail_data'; SELECT brandname AS brandname, firname AS firname, SUM(PAIDAMOUNT)/AVG(RENTAREA) AS sales_rentarea_rate, SUM(ITEMCOUNT)/SUM(INFLOWVALUE) AS poscount_flow_rate, AVG(RENTAMOUNT)/SUM(PAIDAMOUNT) AS rentamount_sales_rate FROM v_sales_flow_details GROUP BY brandname, firname ORDER BY sales_rentarea_rate DESC;
- Analisar marcas no setor de varejo
1 2 3 4 5 6 7 8
SET current_schema='retail_data'; SELECT categoryname AS categoryname, brandname AS brandname, SUM(paidamount) AS sum__paidamount FROM v_sales_flow_details GROUP BY categoryname, brandname ORDER BY sum__paidamount DESC;
- Consultar informações diárias de vendas de cada marca
1 2 3 4 5 6 7 8 9 10 11
SET current_schema='retail_data'; SELECT brandname AS brandname, DATE_TRUNC('day', datekey) AT TIME ZONE 'UTC' AS __timestamp, SUM(paidamount) AS sum__paidamount FROM v_sales_flow_details WHERE datekey >= '2016-01-01 00:00:00' AND datekey <= '2016-01-30 00:00:00' GROUP BY brandname, DATE_TRUNC('day', datekey) AT TIME ZONE 'UTC' ORDER BY sum__paidamount ASC LIMIT 50000;