“Medir dimensões do tipo” na tabela de fatos “Acumulando instantâneo”

8

Eu tenho uma tabela de fatos de snapshot acumulativa que rastreia a entrada e saída de contêineres em um terminal .

Os contêineres podem entrar e sair de três maneiras diferentes , então pensei em criar uma tabela de dimensões específica que lista essas três maneiras possíveis ( trem, embarcação ou caminhão ).

Então li este artigo, que basicamente diz que essa técnica está errada, mas não consigo entender o porquê.

Primeiro artigo:

Às vezes, quando uma tabela de fatos tem uma lista longa de fatos que são escassamente preenchidos em qualquer linha individual, é tentador criar uma dimensão do tipo de medida que reduz a linha da tabela de fatos para um único fato genérico identificado pela dimensão do tipo de medida. Geralmente, não recomendamos essa abordagem. Embora remova todas as colunas de fatos vazias, multiplica o tamanho da tabela de fatos pelo número médio de colunas ocupadas em cada linha e dificulta muito os cálculos entre colunas. Essa técnica é aceitável quando o número de fatos em potencial é extremo (centenas), mas menos de um punhado seria aplicável a qualquer linha da tabela de fatos.

Entendo que, se uma " Dimensão do tipo de medida " for implementada para uma tabela de fatos de transação, ela poderá criar problemas como este outro artigo diz, mas não vejo nenhuma desvantagem se usada para um fato de instantâneo acumulado .

Segundo artigo: (algumas desvantagens da implementação de uma "Dimensão do tipo de medida")

  1. [...] Se escolhermos uma "Dimensão do tipo de medida", perderemos essa capacidade analítica. Se uma medida não for compatível com as outras, não podemos adicioná-las.
  2. [...] Quanto mais número de passes nosso SQL precisar executar para produzir um relatório, mais lento será o relatório.
  3. [...] Na ferramenta de BI, se você não colocar o filtro do tipo de medida, você está arriscando o usuário a obter "informações de lixo". Do ponto de vista da usabilidade, esse design é um lixo.

Resposta à resposta de Mark Storey-Smith

Abordagem muito agradável, eu nunca teria pensado nisso.

Outra coisa: toda entrada e saída de um veículo que leva contêiner para o terminal tem um ID único, que me fornece outras informações como: chegada prevista do veículo, chegada real, se for uma embarcação no cais, se for um caminhão no pedágio e muitas outras informações ...

Essas são três tabelas de fatos diferentes e devem estar vinculadas de alguma forma à tabela de fatos do contêiner.

Eu pensei que o ID da viagem fosse um degenerate dimension, então ele entraria diretamente na tabela de fatos do contêiner. Então, a minha dúvida é: devo adicionar 6 campos diferentes na tabela de fatos do contêiner (embarcação_voyage_in_key, embarcação_voyage_out_key, trem_voyage_in_key, trem_voyage_out_key, truck_voyage_in_key, truck_voyage_out_key) ou apenas 2 outros campos (viagem_in, viagem_várias)

Espero que minha dúvida esteja clara, obrigado.

Mattia Nocerino
fonte

Respostas:

3

Acredito que a orientação se refere a uma ampla tabela de fatos em que a maioria dos valores de medida é nula:

CREATE TABLE dbo.SparseFact
(
    Dim1Key     INT NOT NULL
    , Dim2Key   INT NOT NULL
    , Dim3Key   INT NOT NULL
    , Dim4Key   INT NOT NULL
    , Dim5Key   INT NOT NULL
    , Value1    INT NULL
    , Value2    INT NULL
    , Value3    INT NULL
    , Value4    INT NULL
    , Value5    INT NULL
    , Value6    INT NULL
    , Value7    INT NULL
    , Value8    INT NULL
    ..
    , Value101  INT NULL
    , Value102  INT NULL
    , Value103  INT NULL
);

A sugestão é que algumas pessoas vejam todos os valores nulos e decidam fazer isso:

CREATE TABLE dbo.DontDoThisFact
(
    Dim1Key             INT NOT NULL
    , Dim2Key           INT NOT NULL
    , Dim3Key           INT NOT NULL
    , Dim4Key           INT NOT NULL
    , Dim5Key           INT NOT NULL
    , MeasureTypeKey    INT NOT NULL
    , Value             INT NOT NULL
);

Não é bom.

No seu cenário, acho que estaria analisando algo assim, que é muito diferente do cenário descrito nos artigos que você referenciou.

CREATE TABLE dbo.InventoryFact
(
    ContainerKey        INT NOT NULL
    , TransportTypeKey  TINYINT NOT NULL
    , EntryDateTime     DATETIME NULL
    , ExitDateTime      DATETIME NULL
);

CREATE TABLE dbo.TransportType
(
    TransportTypeKey    TINYINT IDENTITY(1,1) NOT NULL
    , EntryTransport    CHAR(10) NOT NULL
    , ExitTransport     CHAR(10) NOT NULL
);

INSERT
    dbo.TransportType
SELECT
    EntryTransport
    , ExitTransport
FROM
    (
    SELECT EntryTransport = 'Train'
    UNION
    SELECT EntryTransport = 'Truck'
    UNION
    SELECT EntryTransport = 'Vessel'
    UNION
    SELECT EntryTransport = 'N/A'
    UNION
    SELECT EntryTransport = 'Unknown'
    ) en
CROSS JOIN
    (
    SELECT ExitTransport = 'Train'
    UNION
    SELECT ExitTransport = 'Truck'
    UNION
    SELECT ExitTransport = 'Vessel'
    UNION
    SELECT ExitTransport = 'N/A'
    UNION
    SELECT ExitTransport = 'Unknown'
    ) ex;

Para as perguntas adicionais ...

Eu acrescentaria ExpectedEntryDate, ExpectedExitDateao Container/InventoryFact. Menos certo, sem visibilidade de todos os elementos de dados, eu provavelmente iria colocar EntryVoyageIde ExitVoyageIdem uma dimensão lixo separado em conjunto, como uma linha juntamente com quaisquer outros itens de dados degenerados (identificadores para o caminhão, trem etc).

Eu acrescentaria 3 novas dimensões para VesselVoyage, TruckVoyagee TrainVoyagee 6 teclas Voyage (inbound / outbound) para este fato (que é 6 novas chaves, e não 6 linhas adicionais). Você então tem a opção de colocar Docke Tollboothna dimensão de viagem apropriada. Se você mantiver os dados genéricos nessas dimensões ( VesselFlag, TruckCapacity) e os específicos em uma dimensão de lixo eletrônico ( VesselName, VesselMMSI) , eles não explodirão em tamanho.

Mark Storey-Smith
fonte
Olá Mark, obrigado por esta resposta. Isso me dá outra dúvida de que eu não poderia caber nos comentários aqui. Eu atualizei minha pergunta .. poderia verificar? Muito obrigado, eu já verifiquei sua resposta como a boa!
Mattia Nocerino