Tratamiento de los valores nulos – NULL

Se representa por el marcador NULL y es la forma que los sistemas gestores de bases de datos relacionales   indicar que no existe información en un campo. Esta falta de información puede venir dada porque no es aplicable o el desconocimiento del propio valor.

El uso de valores nulos puede causar dos tipos de problemas:

  1. Problemas de eficiencia al consultar valores que poseen valores nulos. Ejemplo solo un tipo de producto tiene descuento todos los demás no les aplica, si realizamos la consulta a todos los valores de la tabla provocamos ineficiencias. Solución revisar el modelo de datos.
  2. Problemas en la construcción de consultas sino se tiene en cuenta la posibilidad de nulos. Ejemplo en un caso de una consulta a un pampo binario pasamos de tener 2 posibles respuestas a tener 3.

 

Tratamiento nulos en las tablas de dimensiones

La metodología de diseño de modelos dimensionales recomienda que todas las columnas de las dimensiones tengan un valor por defecto:

  • Cadenas de caracteres: valor Desconocido o No Aplicable (N/A), dependiendo de su naturaleza.
  • Datos numéricos: se suele utilizar un valor 0.
  • Fechas: se suele utilizar una fecha lejana (1900-01-01) o temprana (9999-12-31) en el tiempo.

Nota: estos valores son orientativos y suelen acordarse con los usuarios a la hora de diseñar el almacen de datos.

 

Tratamiento de nulos en las tablas de hechos

Se sigue un procedimiento similar al anterior, aunque en este caso hay que tener en cuenta las tablas con claves subrogadas, en estos casos se suele utiliza el valor -1 y se genera una fila con valores desconocidos.

id nombre precio fecha
-1 desconocido desconocido 9999-12-31

Las razones para utilizar estos mecanismos son:

  • Evitar violar la integridad referencial entre dimensiones y hechos.
  • Facilitar el uso de INNER JOIN en lugar de LEFT OUTER JOIN, lo que mejora el rendimiento de las consultas.
  • Asegurarse de que los resultados siempre son correctos, independientemente de la dimensión que se utilice en el análisis.
  • Facilitar la detección de problemas de calidad de los datos

 

Ejemplo de cambio de nulos por valores por defecto:

...
FOR v_row_product_stg IN 
    SELECT vw_product_stg.product_code,
           vw_product_stg.product_name,
           vw_product_stg.price,
           CASE WHEN vw_product_stg.category_code IS NULL THEN 'UNKWN'      ELSE vw_product_stg.category_code END,
           CASE WHEN vw_product_stg.category_name IS NULL THEN 'UNKNOWN'    ELSE vw_product_stg.category_name END,
           CASE WHEN vw_product_stg.subcategory_code IS NULL THEN 'UNKWN'   ELSE vw_product_stg.subcategory_code END,
           CASE WHEN vw_product_stg.subcategory_name IS NULL THEN 'UNKNOWN' ELSE vw_product_stg.subcategory_name END
      FROM ventas_stg.vw_product_stg  
    LOOP

  BEGIN
    v_row_product_dim.id_product_dim = v_row_product_dim.id_product_dim + 1;
    v_row_product_dim.start_date = '1900-01-01 00:00:00'::timestamp;
    v_row_product_dim.end_date = '4000-01-01 00:00:00'::timestamp;
    
    v_row_product_dim.product_date_code = CAST(v_row_product_stg.product_code || '-' ||
                                               v_row_product_dim.start_date::TEXT || '-' ||
                                               to_char(v_row_product_dim.start_date , 'HH12:MI:SS') AS TEXT);
   
    -- Asignamos los detalles de producto a la variable de tipo registro para insertar/actualizar
    v_row_product_dim.product_code = v_row_product_stg.product_code;
    v_row_product_dim.product_name = v_row_product_stg.product_name;
    v_row_product_dim.price = v_row_product_stg.price;
    v_row_product_dim.category_code = v_row_product_stg.category_code;
    v_row_product_dim.category_name = v_row_product_stg.category_name;
    v_row_product_dim.subcategory_code = v_row_product_stg.subcategory_code;
    v_row_product_dim.subcategory_name = v_row_product_stg.subcategory_name;
    BEGIN
    -- Intentamos insertar valores en la dimension de productos dentro de un nuevo bloque 
    INSERT INTO ventas_dw.tb_product_dim SELECT v_row_product_dim.*;
    RAISE NOTICE 'Insertar producto: %', v_row_product_dim; 

    EXCEPTION 
        WHEN unique_violation THEN
...           
    
  END LOOP;

Otros artículos que pueden ser de interés:

Autor: Diego Calvo