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 9.4. Mosaicos multidimensionales para números flotantes temporales.


La Figura 9.4, “Mosaicos multidimensionales para números flotantes temporales.” 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 .

Operaciones de intervalos

  • Obtener un conjunto de intervalos que cubre el rango o el período con intervalos de la misma amplitud o duración alineados con el origen

    bucketList(bounds unitspan,width number,origin number=0) → {(index,span)}

    bucketList(bounds tstzspan,duration interval,origin timestamptz='2000-01-03') →

    {(index,span)}

    El resultado es un conjunto de pares (index,span). 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.

    SELECT (bl).index, (bl).span
    FROM (SELECT bucketList(intspan '[15, 25]', 2) AS bl) t;
    -- 1 | [14,16)
    -- 2 | [16,18)
    -- 3 | [18,20)
    -- ...
    SELECT bucketList(floatspan '[-10, -1]', 2.5, -7);
    -- (1,"[-12, -9.5)")
    -- (2,"[-9.5, -7)")
    -- (3,"[-7, -4.5)")
    -- ...
    SELECT (bl).index, (bl).span
    FROM (SELECT bucketList(tstzspan '[2001-01-15, 2001-01-25]','2 days') AS bl) t;
    -- 1 | [2001-01-15, 2001-01-17)
    -- 2 | [2001-01-17, 2001-01-19)
    -- 3 | [2001-01-19, 2001-01-21)
    -- ...
    SELECT bucketList(tstzspan '[2001-01-15, 2001-01-25]', '2 days', '2001-01-02');
    -- (1,"[2001-01-14, 2001-01-16)")
    -- (2,"[2001-01-16, 2001-01-18)")
    -- (3,"[2001-01-18, 2001-01-20)")
    -- ...
    
  • Obtener el valor inicial del intervalo que contiene el número de entrada.

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

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

    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.

    spanBucket(value number,width number,origin number=0) → span

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

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

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

    timestamptz

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

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

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

    tstzspan

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

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

Operaciones de mosaicos

  • Obtener un conjunto de mosaicos que cubre el cuadro delimitador con mosaicos multidimensionales del mismo tamaño y duración

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

    torigin timestamptz='2000-01-03') → {(index,tile)}

    tileList(bounds stbox,xsize float,[ysize float,zsize float,]

    sorigin geompoint='Point(0 0 0)') → {(index,tile)}

    tileList(bounds stbox,xsize float,[ysize float,zsize float,]duration interval,

    sorigin geompoint='Point(0 0 0)',torigin='2000-01-03') → {(index,tile)}

    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.

    En el caso de una malla espacio-temporal, ysize y zsize son opcionales, se supone que el tamaño de las dimensiones faltantes es igual a xsize. 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).tile
    FROM (SELECT tileList(tfloat '[15@2001-01-15, 25@2001-01-25]'::tbox, 2.0, '2 days')
      AS gr) t;
    -- 1 | TBOX XT([14,16),[2001-01-15,2001-01-17))
    -- 2 | TBOX XT([16,18),[2001-01-15,2001-01-17))
    -- 3 | TBOX XT([18,20),[2001-01-15,2001-01-17),)
    -- ...
    SELECT tileList(tfloat '[15@2001-01-15, 25@2001-01-25]'::tbox, 2.0, '2 days', 11.5);
    -- (1,"TBOX XT([13.5,15.5),[2001-01-15,2001-01-17))")
    -- (2,"TBOX XT([15.5,17.5),[2001-01-15,2001-01-17))")
    -- (3,"TBOX XT([17.5,19.5),[2001-01-15,2001-01-17))")
    -- ...
    SELECT tileList(tgeompoint '[Point(3 3)@2001-01-15,
      Point(15 15)@2001-01-25]'::stbox, 2.0);
    -- (1,"STBOX X((2,2),(4,4))")
    -- (2,"STBOX X((4,2),(6,4))")
    -- (3,"STBOX X((6,2),(8,4))")
    -- ...
    SELECT tileList(tgeompoint 'SRID=3812;[Point(3 3)@2001-01-15,
      Point(15 15)@2001-01-25]'::stbox, 2.0, geometry 'Point(3 3)');
    -- (1,"SRID=3812;STBOX X((3,3),(5,5))")
    -- (2,"SRID=3812;STBOX X((5,3),(7,5))")
    -- (3,"SRID=3812;STBOX X((7,3),(9,5))")
    -- ...
    SELECT tileList(tgeompoint '[Point(3 3 3)@2001-01-15,
      Point(15 15 15)@2001-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 tileList(tgeompoint '[Point(3 3)@2001-01-15,
      Point(15 15)@2001-01-25]'::stbox, 2.0, interval '2 days');
    -- (1,"STBOX XT(((2,2),(4,4)),[2001-01-15,2001-01-17))")
    -- (2,"STBOX XT(((4,2),(6,4)),[2001-01-15,2001-01-17))")
    -- (3,"STBOX XT(((6,2),(8,4)),[2001-01-15,2001-01-17))")
    -- ...
    SELECT tileList(tgeompoint '[Point(3 3 3)@2001-01-15,
      Point(15 15 15)@2001-01-25]'::stbox, 2.0, interval '2 days',
      'Point(3 3 3)', '2001-01-15');
    -- (1,"STBOX ZT(((3,3,3),(5,5,5)),[2001-01-15,2001-01-17))")
    -- (2,"STBOX ZT(((5,3,3),(7,5,5)),[2001-01-15,2001-01-17))")
    -- (3,"STBOX ZT(((7,3,3),(9,5,5)),[2001-01-15,2001-01-17))")
    -- ...
    
  • Obtener el mosaico de la malla multidimensional que contiene el valor y la marca de tiempo

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

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

    tile(point geometry,xsize float,[ysize float,zsize float],

    sorigin geompoint='Point(0 0 0)') → stbox

    tile(point geometry,time timestamptz,xsize float,[ysize float,zsize float,]duration

    interval,sorigin geompoint='Point(0 0 0)',torigin timestamptz='2000-01-03') → stbox

    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.

    En el caso de una malla espacio-temporal, ysize y zsize son opcionales, se supone que el tamaño de las dimensiones faltantes es igual a xsize. 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 tile(15, '2001-01-15', 2, interval '2 days');
    -- TBOX XT([14,16),[2001-01-15,2001-01-17))
    SELECT tile(15, '2001-01-15', 2, interval '2 days', 1, '2001-01-02');
    -- TBOX XT([15,17),[2001-01-14,2001-01-16))
    SELECT tile(geometry 'Point(1 1 1)', 2.0);
    -- STBOX Z((0,0,0),(2,2,2))
    SELECT tile(geometry 'Point(1 1)', '2001-01-01', 2.0, interval '2 days');
    -- STBOX XT((0,0),(2,2),[2001-01-01,2001-01-03))
    SELECT tile(geometry 'Point(1 1)', '2001-01-01', 2.0, interval '2 days',
      'Point(1 1)', '2001-01-02');
    -- STBOX XT(((1,1),(3,3)),[2000-12-31,2001-01-02))
    

Operaciones de fragmentación

Estas operaciones fragmentan un valor temporal con respecto a una secuencia de intervalos (ver la “Operaciones de intervalos”) o una mosaico multidimensional (ver la “Operaciones de mosaicos”).

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

    valueSplit(tnumber,width number,origin number=0) → {(number,tnumber)}

    El resultado es un conjunto de pares (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@2001-01-01, 2@2001-01-02, 5@2001-01-05, 10@2001-01-10]',
      2) AS sp) t;
    --  0 | {[1@2001-01-01 00:00:00+01, 1@2001-01-02 00:00:00+01)}
    --  2 | {[2@2001-01-02 00:00:00+01, 2@2001-01-05 00:00:00+01)}
    --  4 | {[5@2001-01-05 00:00:00+01, 5@2001-01-10 00:00:00+01)}
    -- 10 | {[10@2001-01-10 00:00:00+01]}
    SELECT valueSplit(tfloat '[1@2001-01-01, 10@2001-01-10)', 2.0, 1.0);
    -- (1,"{[1@2001-01-01 00:00:00+01, 3@2001-01-03 00:00:00+01)}")
    -- (3,"{[3@2001-01-03 00:00:00+01, 5@2001-01-05 00:00:00+01)}")
    -- (5,"{[5@2001-01-05 00:00:00+01, 7@2001-01-07 00:00:00+01)}")
    -- (7,"{[7@2001-01-07 00:00:00+01, 9@2001-01-09 00:00:00+01)}")
    -- (9,"{[9@2001-01-09 00:00:00+01, 10@2001-01-10 00:00:00+01)}")
    
  • Fragmentar el valor temporal con respecto a intervalos de tiempo

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

    {(time,temp)}

    El resultado es un conjunto de pares (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@2001-02-01, 10@2001-02-10)', '2 days') AS ts) t;
    -- 2001-01-31 | [1@2001-02-01, 2@2001-02-02)
    -- 2001-02-02 | [2@2001-02-02, 4@2001-02-04)
    -- 2001-02-04 | [4@2001-02-04, 6@2001-02-06)
    -- ...
    SELECT (ts).time, astext((ts).temp) AS temp
    FROM (SELECT timeSplit(tgeompoint '[Point(1 1)@2001-02-01, Point(10 10)@2001-02-10]',
      '2 days', '2001-02-01') AS ts) AS t;
    -- 2001-02-01 | [POINT(1 1)@2001-02-01, POINT(3 3)@2001-02-03)
    -- 2001-02-03 | [POINT(3 3)@2001-02-03, POINT(5 5)@2001-02-05)
    -- 2001-02-05 | [POINT(5 5)@2001-02-05, POINT(7 7)@2001-02-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@2001-01-01, 10@2001-01-03]', '1 hour') AS ts) t
    GROUP BY hour ORDER BY hour;
    /* 00:00:00 | {[1@2001-01-01 00:00:00+01, 1.1875@2001-01-01 01:00:00+01),
                   [5.5@2001-01-02 00:00:00+01, 5.6875@2001-01-02 01:00:00+01)} */
    /* 01:00:00 | {[1.1875@2001-01-01 01:00:00+01, 1.375@2001-01-01 02:00:00+01),
                   [5.6875@2001-01-02 01:00:00+01, 5.875@2001-01-02 02:00:00+01)} */
    /* 02:00:00 | {[1.375@2001-01-01 02:00:00+01, 1.5625@2001-01-01 03:00:00+01),
                   [5.875@2001-01-02 02:00:00+01, 6.0625@2001-01-02 03:00:00+01)} */
    /* 03:00:00 | {[1.5625@2001-01-01 03:00:00+01, 1.75@2001-01-01 04:00:00+01),
                   [6.0625@2001-01-02 03:00:00+01, 6.25@2001-01-02 04:00:00+01)} */
    /* ... */
    SELECT EXTRACT(DOW FROM (ts).time) AS dow_no, TO_CHAR((ts).time, 'Dy') AS dow,
      asText(round(merge((ts).temp), 2)) AS temp
    FROM (SELECT timeSplit(tgeompoint '[Point(1 1)@2001-01-01, Point(10 10)@2001-01-14)',
      '1 hour') AS ts) t
    GROUP BY dow, dow_no ORDER BY dow_no;
    /* 0 | Sun | {[POINT(1 1)@2001-01-01, POINT(1.69 1.69)@2001-01-02),
                  [POINT(5.85 5.85)@2001-01-08, POINT(6.54 6.54)@2001-01-09)} */
    /* 1 | Mon | {[POINT(1.69 1.69)@2001-01-02, POINT(2.38 2.38)@2001-01-03),
                  [POINT(6.54 6.54)@2001-01-09, POINT(7.23 7.23)@2001-01-10)} */
    /* 2 | Tue | {[POINT(2.38 2.38)@2001-01-03, POINT(3.08 3.08)@2001-01-04),
                  [POINT(7.23 7.23)@2001-01-10, POINT(7.92 7.92)@2001-01-11)} */
    /* ... */
    
  • Fragmentar el número temporal con respecto a los mosaicos de una malla de valores y de tiempo

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

    torigin timestamptz='2000-01-03') → {(number,time,tnumber)}

    El resultado es un conjunto de triples (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@2001-02-01, 2@2001-02-02, 5@2001-02-05,
      10@2001-02-10]', 5, '5 days') AS sp) t;
    --  0 | 2001-02-01 | {[1@2001-02-01, 2@2001-02-02, 2@2001-02-05)}
    --  5 | 2001-02-01 | {[5@2001-02-05, 5@2001-02-06)}
    --  5 | 2001-02-06 | {[5@2001-02-06, 5@2001-02-10)}
    -- 10 | 2001-02-06 | {[10@2001-02-10]}
    SELECT (sp).number, (sp).time, (sp).tnumber
    FROM (SELECT valueTimeSplit(tfloat '[1@2001-02-01, 10@2001-02-10)', 5.0, '5 days', 1.0,
      '2001-02-01') AS sp) t;
    -- 1 | 2001-01-01 | [1@2001-01-01, 6@2001-01-06)
    -- 6 | 2001-01-06 | [6@2001-01-06, 10@2001-01-10)
    
  • Fragmentar el punto temporal con respecto a los mosaicos de una malla espacial

    spaceSplit(tgeompoint,xsize float,[ysize float,zsize float,]

    origin geompoint='Point(0 0 0)',bitmatrix boolean=true) → {(point,tpoint)}

    El resultado es un conjunto de pares (point,tpoint). Si el origen del espacio no se especifica, su valor se establece por defecto en 'Point(0 0 0)'. Los argumentos ysize y zsize son opcionales, se supone que el tamaño de las dimensiones faltantes es igual a xsize. 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)@2001-03-01, Point(10 10)@2001-03-10]',
      2.0) AS sp) t;
    -- POINT(0 0) | {[POINT(1 1)@2001-03-01, POINT(2 2)@2001-03-02)}
    -- POINT(2 2) | {[POINT(2 2)@2001-03-02, POINT(4 4)@2001-03-04)}
    -- POINT(4 4) | {[POINT(4 4)@2001-03-04, POINT(6 6)@2001-03-06)}
    -- ...
    SELECT ST_AsText((sp).point) AS point, astext((sp).tpoint) AS tpoint
    FROM (SELECT spaceSplit(tgeompoint '[Point(1 1 1)@2001-03-01,
      Point(10 10 10)@2001-03-10]', 2.0, geometry 'Point(1 1 1)') AS sp) t;
    -- POINT Z(1 1 1) | {[POINT Z (1 1 1)@2001-03-01, POINT Z (3 3 3)@2001-03-03)}
    -- POINT Z(3 3 3) | {[POINT Z (3 3 3)@2001-03-03, POINT Z (5 5 5)@2001-03-05)}
    -- POINT Z(5 5 5) | {[POINT Z (5 5 5)@2001-03-05, POINT Z (7 7 7)@2001-03-07)}
    -- ...
    
  • Fragmentar el punto temporal con respecto a los mosaicos de una malla espacio-temporal

    spaceTimeSplit(tgeompoint,xsize float,[ysize float,ysize float,]

    duration interval,sorigin geompoint='Point(0 0 0)',

    torigin timestamptz='2000-01-03',bitmatrix boolean=true) → {(point,time,tpoint)}

    El resultado es un conjunto de triples (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. Los argumentos ysize y zsize son opcionales, se supone que el tamaño de las dimensiones faltantes es igual a xsize. 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)@2001-02-01, Point(10 10)@2001-02-10]',
      2.0, interval '2 days') AS sp) t;
    -- POINT(0 0) | 2001-01-31 | {[POINT(1 1)@2001-02-01, POINT(2 2)@2001-02-02)}
    -- POINT(2 2) | 2001-01-31 | {[POINT(2 2)@2001-02-02]}
    -- POINT(2 2) | 2001-02-02 | {[POINT(2 2)@2001-02-02, POINT(4 4)@2001-02-04)}
    -- ...
    SELECT ST_AsText((sp).point) AS point, (sp).time, astext((sp).tpoint) AS tpoint
    FROM (SELECT spaceTimeSplit(tgeompoint '[Point(1 1 1)@2001-02-01,
      Point(10 10 10)@2001-02-10]', 2.0, interval '2 days', 'Point(1 1 1)',
      '2001-03-01') AS sp) t;
    -- POINT Z(1 1 1) | 2001-02-01 | {[POINT Z(1 1 1)@2001-02-01, POINT Z(3 3 3)@2001-02-03)}
    -- POINT Z(3 3 3) | 2001-02-01 | {[POINT Z(3 3 3)@2001-02-03]}
    -- POINT Z(3 3 3) | 2001-02-03 | {[POINT Z(3 3 3)@2001-02-03, POINT Z (5 5 5)@2001-02-05)}
    -- ...