5.14. Mosaicos multidimensionales

Los mosaicos multidimensionales es el mecanismo que se utiliza para dividir el dominio de valores temporales en intervalos o mosaicos de un número variable de dimensiones. En el caso de una sola dimensión, el dominio se puede dividir por valor o por tiempo utilizando intervalos del mismo ancho o la misma duración, respectivamente. Para los números temporales, el dominio se puede dividir en mosaicos bidimensionales del mismo ancho para la dimensión de valor y la misma duración para la dimensión de tiempo. Para los puntos temporales, el dominio se puede dividir en el espacio en mosaicos bidimensionales o tridimensionales, dependiendo del número de dimensiones de las coordenadas espaciales. Finalmente, para los puntos temporales, el dominio se puede dividir por espacio y por tiempo usando mosaicos tridimensionales o tetradimensionales. Además, los valores temporales también se pueden fragmentar de acuerdo con una malla multidimensional definida sobre el dominio subyacente.

Los mosaicos multidimensionales se pueden utilizar para diversos fines. Por ejemplo, se pueden utilizar para calcular histogramas multidimensionales, donde los valores temporales se agregan de acuerdo con la partición subyacente del dominio. Por otro lado, el mosaico multidimensional se puede utilizar para distribuir un conjunto de datos en un grupo de servidores, donde cada servidor contiene una partición del conjunto de datos. La ventaja de este mecanismo de partición es que conserva la proximidad en el espacio y el tiempo, a diferencia de los mecanismos de partición tradicionales basados ​​en hash utilizados en entornos de big data.

Figura 5.2. Mosaicos multidimensionales para números flotantes temporales.


La Figura 5.2 ilustra un mosaico multidimensional para números flotantes temporales. El dominio bidimensional se divide en mosaicos que tienen el mismo tamaño para la dimensión de valor y la misma duración para la dimensión de tiempo. Suponga que este esquema de mosaicos se usa para distribuir un conjunto de datos en un clúster de seis servidores, como sugiere el patrón gris en la figura. En este caso, los valores se fragmentan para que cada servidor reciba los datos de mosaicos contiguos. Esto implica en particular que cuatro nodos recibirán un fragmento del número flotante temporal que se muestra en la figura. Una ventaja de esta distribución de datos basada en mosaicos multidimensionales es que reduce los datos que deben intercambiarse entre nodos cuando se procesan consultas, un proceso que generalmente se denomina reshuffling.

Muchas de las funciones de esta sección son funciones de retorno de conjuntos (también conocidas como funciones de tabla) ya que normalmente devuelven más de un valor. En este caso, las funciones están marcadas con el símbolo .

5.14.1. Operaciones de intervalos

  • Obtener un conjunto de parejas (índice, intervalo) que cubre el rango o el período con intervalos de la misma amplitud o duración alineados con el origen .

    Si el origen no se especifica, su valor se establece por defecto en 0 para los rangos y en lunes 3 de enero de 2000 para los períodos. Los índices empiezan en 1.

    bucketList(bounds range,width number,origin number=0): setof index_range

    bucketList(bounds period,duration interval,origin timestamptz='2000-01-03'):

    setof index_period

    SELECT (bl).index, (bl).range
    FROM (SELECT bucketList(tint '[15@2000-01-01, 25@2000-01-10]'::intrange, 2) AS bl) t;
    -- 1 | [14,16)
       2 | [16,18)
       3 | [18,20)
       ...
    SELECT bucketList(tfloat '[-1@2000-01-01, -10@2000-01-10]'::floatrange, 2, -7);
    -- (1,"[-11,-9)")
       (2,"[-9,-7)")
       (3,"[-7,-5)")
       ...
    SELECT (bl).index, (bl).period
    FROM (SELECT bucketList(tfloat '[1@2000-01-15, 10@2000-01-25]'::period,'2 days') AS bl) t;
    -- 1 | [2000-01-15, 2000-01-17)
       2 | [2000-01-17, 2000-01-19)
       3 | [2000-01-19, 2000-01-21)
       ...
    SELECT bucketList(tfloat '[1@2000-01-15, 10@2000-01-25]'::period, '2 days', '2000-01-02');
    -- (1,"[2000-01-14, 2000-01-16)")
       (2,"[2000-01-16, 2000-01-18)")
       (3,"[2000-01-18, 2000-01-20)")
       ...
    
  • Obtener el valor inicial del intervalo que contiene el número de entrada.

    Si el origen no se especifica, su valor se establece por defecto en 0.

    valueBucket(value number,width number, origin number=0): number

    SELECT valueBucket(3, 2);
    -- 2
    SELECT valueBucket(3.5, 2.5, 1.5);
    -- 1.5
    
  • Obtener el rango en el espacio de intervalos que contiene el número de entrada.

    Si el origen no se especifica, su valor se establece por defecto en 0.

    rangeBucket(value number,width number,origin number=0): range

    SELECT rangeBucket(2, 2);
    -- [2,4)
    SELECT rangeBucket(2, 2, 1);
    -- [1,3)
    SELECT rangeBucket(2, 2.5);
    -- [0,2.5)
    SELECT rangeBucket(2, 2.5, 1.5);
    -- [1.5,4)
    
  • Obtener el valor inicial del intervalo que contiene la marca de tiempo de entrada.

    Si el origen no se especifica, su valor se establece por defecto en lunes 3 de enero de 2000.

    timeBucket(time timestamptz,duration interval,origin timestamptz='2000-01-03'):

    timestamptz

    SELECT timeBucket(timestamptz '2020-05-01', interval '2 days');
    -- 2020-04-29 01:00:00+02
    SELECT timeBucket(timestamptz '2020-05-01', interval '2 days', timestamptz '2020-01-01');
    -- 2020-04-30 01:00:00+02
    
  • Obtener el período en el espacio de intervalos que contiene la marca de tiempo de entrada.

    Si el origen no se especifica, su valor se establece por defecto en lunes 3 de enero de 2000.

    periodBucket(time timestamptz,duration interval,origin timestamptz='2000-01-03'):

    period

    SELECT periodBucket('2000-01-04', interval '1 week');
    -- [2000-01-03, 2000-01-10)
    SELECT periodBucket('2000-01-04', interval '1 week', '2000-01-07');
    -- [1999-12-31, 2000-01-07)
    

5.14.2. Operaciones de malla

  • Obtener un conjunto de parejas (índice, mosaico) que cubre el cuadro delimitador con mosaicos multidimensionales del mismo tamaño y duración.

    Si el origen de las dimensiones de valores y/o de tiempo no se especifican, su valor se establece por defecto en 0 o 'Point (0 0 0)' para la dimensión de valores (según el tipo de cuadro delimitador) y en el lunes 3 de enero de 2000 para la dimensión de tiempo.

    multidimGrid(bounds tbox,size float,duration interval,vorigin float=0,

    torigin timestamptz='2000-01-03'): setof index_box

    multidimGrid(bounds stbox,size float,sorigin geometry='Point(0 0 0)'):

    setof index_box

    multidimGrid(bounds stbox,size float,duration interval,sorigin geometry='Point(0 0 0)',

    torigin timestamptz='2000-01-03'): setof index_box

    En el caso de una malla espacio-temporal, el SRID de las coordenadas de los mosaicos está determinado por el del cuadro de entrada y el tamaño se da en las unidades del SRID. Si se especifica el origen de las coordenadas espaciales, que debe ser un punto, su dimensionalidad y SRID deben ser iguales al del cuadro delimitador, de lo contrario se genera un error.

    SELECT (gr).index, (gr).box
    FROM (SELECT multidimGrid(tfloat '[15@2000-01-15, 25@2000-01-25]'::tbox, 2.0, '2 days')
      AS gr) t;
    -- 1 | TBOX((14,2000-01-15),(16,2000-01-17))
       2 | TBOX((16,2000-01-15),(18,2000-01-17))
       3 | TBOX((18,2000-01-15),(20,2000-01-17))
       ...
    SELECT multidimGrid(tfloat '[15@2000-01-15, 25@2000-01-25]'::tbox, 2.0, '2 days', 11.5);
    -- (1,"TBOX((13.5,2000-01-15),(15.5,2000-01-17))")
       (2,"TBOX((15.5,2000-01-15),(17.5,2000-01-17))")
       (3,"TBOX((17.5,2000-01-15),(19.5,2000-01-17))")
       ...
    SELECT multidimGrid(tgeompoint '[Point(3 3)@2000-01-15,
      Point(15 15)@2000-01-25]'::stbox, 2.0);
    -- (1,"STBOX((2,2),(4,4))")
       (2,"STBOX((4,2),(6,4))")
       (3,"STBOX((6,2),(8,4))")
       ...
    SELECT multidimGrid(tgeompoint 'SRID=3812;[Point(3 3)@2000-01-15,
      Point(15 15)@2000-01-25]'::stbox, 2.0, geometry 'Point(3 3)');
    -- (1,"SRID=3812;STBOX((3,3),(5,5))")
       (2,"SRID=3812;STBOX((5,3),(7,5))")
       (3,"SRID=3812;STBOX((7,3),(9,5))")
       ...
    SELECT multidimGrid(tgeompoint '[Point(3 3 3)@2000-01-15,
      Point(15 15 15)@2000-01-25]'::stbox, 2.0, geometry 'Point(3 3 3)');
    -- (1,"STBOX Z((3,3,3),(5,5,5))")
       (2,"STBOX Z((5,3,3),(7,5,5))")
       (3,"STBOX Z((7,3,3),(9,5,5))")
       ...
    SELECT multidimGrid(tgeompoint '[Point(3 3)@2000-01-15,
      Point(15 15)@2000-01-25]'::stbox, 2.0, interval '2 days');
    -- (1,"STBOX T((2,2,2000-01-15),(4,4,2000-01-17))")
       (2,"STBOX T((4,2,2000-01-15),(6,4,2000-01-17))")
       (3,"STBOX T((6,2,2000-01-15),(8,4,2000-01-17))")
       ...
    SELECT multidimGrid(tgeompoint '[Point(3 3 3)@2000-01-15,
      Point(15 15 15)@2000-01-25]'::stbox, 2.0, '2 days', 'Point(3 3 3)', '2000-01-15');
    -- (1,"STBOX ZT((3,3,3,2000-01-15),(5,5,5,2000-01-17))")
       (2,"STBOX ZT((5,3,3,2000-01-15),(7,5,5,2000-01-17))")
       (3,"STBOX ZT((7,3,3,2000-01-15),(9,5,5,2000-01-17))")
       ...
    
  • Obtener el mosaico de la malla multidimensional que contiene el valor y la marca de tiempo.

    Si el origen de las dimensiones de valores y/o de tiempo no se especifican, su valor se establece por defecto en 0 o 'Point(0 0 0)' para la dimensión de valores y en el lunes 3 de enero de 2000 para la dimensión de tiempo, respectivamente.

    multidimTile(value float,time timestamptz,size float,duration interval,

    vorigin float=0.0,torigin timestamptz='2000-01-03'): tbox

    multidimTile(point geometry,size float,sorigin geometry='Point(0 0 0)'): stbox

    multidimTile(point geometry,time timestamptz,size float,duration interval,sorigin

    geometry='Point(0 0 0)',torigin timestamptz='2000-01-03'): stbox

    En el caso de una malla espacio-temporal, el SRID de las coordenadas de los mosaicos está determinado por el punto de entrada y la amplitud espacial se da en las unidades del SRID. Si se especifica el origen de las coordenadas espaciales, que debe ser un punto, su dimensionalidad y SRID deben ser iguales al del cuadro delimitador, de lo contrario se genera un error.

    SELECT multidimTile(15, '2000-01-15', 2, interval '2 days');
    -- TBOX((14,2000-01-15),(16,2000-01-17))
    SELECT multidimTile(15, '2000-01-15', 2, interval '2 days', 1, '2000-01-02');
    -- TBOX((15,2000-01-14),(17,2000-01-16))
    SELECT multidimTile(geometry 'Point(1 1 1)', 2.0);
    -- STBOX Z((0,0,0),(2,2,2))
    SELECT multidimTile(geometry 'Point(1 1)', '2000-01-01', 2.0, interval '2 days');
    -- STBOX T((0,0,2000-01-01),(2,2,2000-01-03))
    SELECT multidimTile(geometry 'Point(1 1)', '2000-01-01', 2.0, '2 days', 'Point(1 1)',
      '2000-01-02');
    -- STBOX T((1,1,1999-12-31),(3,3,2000-01-02))
    

5.14.3. Operaciones de fragmentación

Estas operaciones fragmentan un valor temporal con respecto a una secuencia de intervalos (ver la Sección 5.14.1) o una malla multidimensional (ver la Sección 5.14.2).

  • Fragmentar el número temporal con respecto a intervalos de valores.

    valueSplit(value tnumber,width number,origin number=0): setof number_tnumber

    Si el origen de los valores no se especifica, su valor se establece por defecto en 0.

    SELECT (sp).number, (sp).tnumber
    FROM (SELECT valueSplit(tint '[1@2012-01-01, 2@2012-01-02, 5@2012-01-05, 10@2012-01-10]',
      2) AS sp) t;
    --  0 | {[1@2012-01-01 00:00:00+01, 1@2012-01-02 00:00:00+01)}
        2 | {[2@2012-01-02 00:00:00+01, 2@2012-01-05 00:00:00+01)}
        4 | {[5@2012-01-05 00:00:00+01, 5@2012-01-10 00:00:00+01)}
       10 | {[10@2012-01-10 00:00:00+01]}
    SELECT valueSplit(tfloat '[1@2012-01-01, 10@2012-01-10)', 2.0, 1.0);
    -- (1,"{[1@2012-01-01 00:00:00+01, 3@2012-01-03 00:00:00+01)}")
       (3,"{[3@2012-01-03 00:00:00+01, 5@2012-01-05 00:00:00+01)}")
       (5,"{[5@2012-01-05 00:00:00+01, 7@2012-01-07 00:00:00+01)}")
       (7,"{[7@2012-01-07 00:00:00+01, 9@2012-01-09 00:00:00+01)}")
       (9,"{[9@2012-01-09 00:00:00+01, 10@2012-01-10 00:00:00+01)}")
    
  • Fragmentar el valor temporal con respecto a intervalos de tiempo.

    timeSplit(value ttype,duration interval,origin timestamptz='2000-01-03'):

    setof time_temp

    Si el origen del tiempo no se especifica, su valor se establece por defecto en el lunes 3 de enero de 2000.

    SELECT (ts).time, (ts).temp
    FROM (SELECT timeSplit(tfloat '[1@2012-01-01, 10@2012-01-10)', '2 days') AS ts) t;
    -- 2011-12-31 | [1@2012-01-01, 2@2012-01-02)
       2012-01-02 | [2@2012-01-02, 4@2012-01-04)
       2012-01-04 | [4@2012-01-04, 6@2012-01-06)
       ...
    SELECT (ts).time, astext((ts).temp) AS temp
    FROM (SELECT timeSplit(tgeompoint '[Point(1 1)@2012-01-01, Point(10 10)@2012-01-10]',
      '2 days', '2012-01-01') AS ts) AS t;
    -- 2012-01-01 | [POINT Z (1 1 1)@2012-01-01, POINT Z (3 3 3)@2012-01-03)
       2012-01-03 | [POINT Z (3 3 3)@2012-01-03, POINT Z (5 5 5)@2012-01-05)
       2012-01-05 | [POINT Z (5 5 5)@2012-01-05, POINT Z (7 7 7)@2012-01-07)
       ...
    

    Observe que se puede fragmentar un valor temporal en intervalos de tiempo cíclicos (en lugar de lineales). Los siguientes dos ejemplos muestran cómo fragmentar un valor temporal por hora y por día de la semana.

    SELECT (ts).time::time as hour, merge((ts).temp) as temp
    FROM (SELECT timeSplit(tfloat '[1@2012-01-01, 10@2012-01-03]', '1 hour') AS ts) t
    GROUP BY hour ORDER BY hour;
    
    -- 00:00:00 | {[1@2012-01-01 00:00:00+01, 1.1875@2012-01-01 01:00:00+01),
                   [5.5@2012-01-02 00:00:00+01, 5.6875@2012-01-02 01:00:00+01)}
       01:00:00 | {[1.1875@2012-01-01 01:00:00+01, 1.375@2012-01-01 02:00:00+01),
                   [5.6875@2012-01-02 01:00:00+01, 5.875@2012-01-02 02:00:00+01)}
       02:00:00 | {[1.375@2012-01-01 02:00:00+01, 1.5625@2012-01-01 03:00:00+01),
                   [5.875@2012-01-02 02:00:00+01, 6.0625@2012-01-02 03:00:00+01)}
       03:00:00 | {[1.5625@2012-01-01 03:00:00+01, 1.75@2012-01-01 04:00:00+01),
                   [6.0625@2012-01-02 03:00:00+01, 6.25@2012-01-02 04:00:00+01)}
       ...
    SELECT EXTRACT(DOW FROM (ts).time) as dow_no, TO_CHAR((ts).time, 'Dy') as dow,
      asText(setPrecision(merge((ts).temp), 2)) as temp
    FROM (SELECT timeSplit(tgeompoint '[Point(1 1)@2012-01-01, Point(10 10)@2012-01-14)',
      '1 hour') AS ts) t
    GROUP BY dow, dow_no ORDER BY dow_no;
    -- 0 | Sun | {[POINT(1 1)@2012-01-01, POINT(1.69 1.69)@2012-01-02),
                  [POINT(5.85 5.85)@2012-01-08, POINT(6.54 6.54)@2012-01-09)}
       1 | Mon | {[POINT(1.69 1.69)@2012-01-02, POINT(2.38 2.38)@2012-01-03),
                  [POINT(6.54 6.54)@2012-01-09, POINT(7.23 7.23)@2012-01-10)}
       2 | Tue | {[POINT(2.38 2.38)@2012-01-03, POINT(3.08 3.08)@2012-01-04),
                  [POINT(7.23 7.23)@2012-01-10, POINT(7.92 7.92)@2012-01-11)}
       ...
    
  • Fragmentar el número temporal con respecto a los mosaicos de una malla de valores y de tiempo.

    valueTimeSplit(value tumber,width number,duration interval,vorigin number=0,

    torigin timestamptz='2000-01-03'): setof number_time_tnumber

    Si el origen de los valores y/o el tiempo no se especifican, su valor se establece por defecto en 0 y en el lunes 3 de enero de 2000, respectivamente.

    SELECT (sp).number, (sp).time, (sp).tnumber
    FROM (SELECT valueTimeSplit(tint '[1@2012-01-01, 2@2012-01-02, 5@2012-01-05,
      10@2012-01-10]', 5, '5 days') AS sp) t;
    -- 0 | 2011-12-31 | [1@2012-01-01, 2@2012-01-02, 2@2012-01-05)
       5 | 2012-01-05 | [5@2012-01-05, 5@2012-01-10)
      10 | 2012-01-10 | [10@2012-01-10]
    SELECT (sp).number, (sp).time, (sp).tnumber
    FROM (SELECT valueTimeSplit(tfloat '[1@2012-01-01, 10@2012-01-10)', 5.0, '5 days', 1.0,
      '2012-01-01') AS sp) t;
    -- 1 | 2012-01-01 | [1@2012-01-01, 6@2012-01-06)
       6 | 2012-01-06 | [6@2012-01-06, 10@2012-01-10)
    
  • Fragmentar el punto temporal con respecto a los mosaicos de una malla espacial.

    spaceSplit(value tgeompoint,width float,origin geometry='Point(0 0 0)',

    bitmatrix=TRUE): setof point_tpoint

    Si el origen del espacio no se especifica, su valor se establece por defecto en 'Point(0 0 0)'. Si no se especifica el argumento bitmatrix, el cálculo utilizará una matriz de bits para acelerar el proceso.

    SELECT ST_AsText((sp).point) AS point, astext((sp).tpoint) AS tpoint
    FROM (SELECT spaceSplit(tgeompoint '[Point(1 1)@2020-03-01, Point(10 10)@2020-03-10]',
      2.0) AS sp) t;
    -- POINT(0 0) | {[POINT(1 1)@2020-03-01, POINT(2 2)@2020-03-02)}
       POINT(2 2) | {[POINT(2 2)@2020-03-02, POINT(4 4)@2020-03-04)}
       POINT(4 4) | {[POINT(4 4)@2020-03-04, POINT(6 6)@2020-03-06)}
       ...
    SELECT ST_AsText((sp).point) AS point, astext((sp).tpoint) AS tpoint
    FROM (SELECT spaceSplit(tgeompoint '[Point(1 1 1)@2020-03-01,
      Point(10 10 10)@2020-03-10]', 2.0, 'Point(1 1 1)') AS sp) t;
    -- POINT Z (1 1 1) | {[POINT Z (1 1 1)@2020-03-01, POINT Z (3 3 3)@2020-03-03)}
       POINT Z (3 3 3) | {[POINT Z (3 3 3)@2020-03-03, POINT Z (5 5 5)@2020-03-05)}
       POINT Z (5 5 5) | {[POINT Z (5 5 5)@2020-03-05, POINT Z (7 7 7)@2020-03-07)}
       ...
    
  • Fragmentar el punto temporal con respecto a los mosaicos de una malla espacio-temporal.

    spaceTimeSplit(value tgeompoint,size float,duration interval,sorigin

    geometry='Point(0 0 0)',torigin timestamptz='2000-01-03', bitmatrix=TRUE):

    setof point_time_tpoint

    Si el origen del espacio y/o el tiempo no se especifica, su valor se establece por defecto en 'Point(0 0 0)' y en el lunes 3 de enero de 2000, respectivamente. Si no se especifica el argumento bitmatrix, el cálculo utilizará una matriz de bits para acelerar el proceso.

    SELECT ST_AsText((sp).point) AS point, (sp).time, astext((sp).tpoint) AS tpoint
    FROM (SELECT spaceTimeSplit(tgeompoint '[Point(1 1)@2020-03-01, Point(10 10)@2020-03-10]',
      2.0, '2 days') AS sp) t;
    -- POINT(0 0) | 2020-03-01 | {[POINT(1 1)@2020-03-01, POINT(2 2)@2020-03-02)}
       POINT(2 2) | 2020-03-01 | {[POINT(2 2)@2020-03-02, POINT(3 3)@2020-03-03]}
       POINT(2 2) | 2020-03-03 | {[POINT(3 3)@2020-03-03, POINT(4 4)@2020-03-04)}
       ...
    SELECT ST_AsText((sp).point) AS point, (sp).time, astext((sp).tpoint) AS tpoint
    FROM (SELECT spaceTimeSplit(tgeompoint '[Point(1 1 1)@2020-03-01,
      Point(10 10 10)@2020-03-10]', 2.0, '2 days', 'Point(1 1 1)', '2020-03-01') AS sp) t;
    -- POINT Z(1 1 1) | 2020-03-01 | {[POINT Z(1 1 1)@2020-03-01, POINT Z(3 3 3)@2020-03-03)}
       POINT Z(3 3 3) | 2020-03-03 | {[POINT Z(3 3 3)@2020-03-03, POINT Z(5 5 5)@2020-03-05)}
       POINT Z(5 5 5) | 2020-03-05 | {[POINT Z(5 5 5)@2020-03-05, POINT Z(7 7 7)@2020-03-07)}
       ...