A time series is a sequence of data points, typically consisting of successive measurements made over a time interval.

Examples of time series are ocean tides, counts of sunspots, and the daily closing value of the Dow Jones Industrial Average. Time series are used in statistics, signal processing, pattern recognition, econometrics, mathematical finance, weather forecasting, earthquake prediction, electroencephalography, control engineering, astronomy, communications engineering, and largely in any domain of applied science and engineering which involves temporal measurements.

The Informix TimeSeries DataBlade was designed to help developers better handle time-related data, such as mobile apps.

Example deployed in this page: Create a time series to store geolocation data that are received from mobile devices.

1 Considerations

The TimeSeries module needs the scheduler for some internal operations.

In consequence can not be exists the " stop"" file at sysadmin folder.

Copy
rm $INFORMIXDIR/etc/sysadmin/stop

After " stop" file is deleted the auto-statistics tasks will be active. If you do not need this tasks you can execute the following SQL command:

Copy
dbaccess sysadmin;
UPDATE ph_task SET tk_enable='f' WHERE tk_name LIKE '%Statistics%';

2 Register the TimeSeries DataBlade

From version 12.10 of IDS onwards, the BTS module is automatically integrated into databases and it does not require further registration. To setup the BTS on a database, simply connect to a database where you need spatial options and execute:

Copy
EXECUTE FUNCTION SYSBldPrepare('TimeSeries.*'    ,'create');

For versions after 11.70, additional steps are required.

3 Create the calendar pattern

Run DBAccess or DBStudio to connect to the target database. Verify that CalendarPatterns system table is available:

Copy
SELECT * FROM CalendarPatterns

Create the calendar time pattern inserting a row into CalendarPatterns:

Copy
INSERT INTO CalendarPatterns VALUES ('patt_1min', '{1 on , 59 off}, second')
  • patt_1min: is the calendar pattern name.
  • {1 on , 59 off}, second: specifies the pattern time slot of 1 minute.

4 Create the calendar

Create the calendar inserting a row into CalendarTable system table:

Copy
INSERT INTO CalendarTable (c_name, c_calendar)
     VALUES ('cal_1min_2014', 'startdate(2014-01-01 00:00:00), pattstart(2014-01-01 00:00:00), pattname(patt_1min)')
  • cal_1min_2014: is the name of the calendar.

5 Create the time series

5.1 Row data type

Create the time series struct defining a row data type:

Copy
CREATE ROW TYPE mobile_data_type (
    device_last_date        DATETIME YEAR TO FRACTION(5),
    device_last_user        CHAR(20)       NOT NULL,
    device_last_battery     SMALLINT       NOT NULL,
    device_last_gps_enabled SMALLINT       NOT NULL,
    device_last_gps_lat     DECIMAL(14,10) NOT NULL,
    device_last_gps_lng     DECIMAL(14,10) NOT NULL,
    device_last_network     SMALLINT       NOT NULL,
    device_last_activity    SMALLINT       NOT NULL
)

No default values are allowed.

5.2 TimeSeries data type

Create a raw table which contains the column of TimeSeries data type:

Copy
CREATE TABLE wic_mobile_devices_data_hist_ts (
    device_uuid CHAR(40),
    device_data TimeSeries(mobile_data_type)
)

5.3 Container

Before you execute the procedure is necessary to create a specific DBSpace to store data.

Copy
touch /INFORMIXDEV/d_tsdata_00
chmod 660 /INFORMIXDEV/d_tsdata_00
onspaces -c -d d_tsdata -p /INFORMIXDEV/d_tsdata_00 -k 16 -s 8192000 -o 0

A dbspace must be created to store the time series.

Create the time series container:

Copy
EXECUTE PROCEDURE TSContainerCreate ('mobile_data_ct', 'd_tsdata', 
                                     'mobile_data_type', 0, 0)
  • mobile_data_cont: is the name of the container.
  • d_tsdate: is the name of the dbspace that holds the container.
  • mobile_data_type: is the name of the row type.
  • 0: is the size of the container, in KB. If you specify 0 or a negative number, 16 KB is used.
  • 0: is the increment by which the container grows, in KB. If you specify 0 or a negative number, 16 KB is used.

5.4 Initialization

Insert a row into user-defined table to initialize the time series:

Copy
INSERT INTO wic_mobile_devices_data_hist_ts 
 VALUES ('device_1', "origin(2014-11-09 17:14:00.00000), calendar(cal_1min_2014), container(mobile_data_ct), threshold(0), irregular, []")
  • origin(2014-11-09 17:14:00.00000): specifies the first time slot.
  • irregular: means that only time slots corresponding to received data from mobile devices, will be generated. So there will not be empty slots. If devices do not send data for some minutes, no slots will be created.
Example
  • 2014-11-09 17: 14 initial slot
  • 2014-11-09 17: 15 device data recieved
  • 2014-11-09 17: 16 no data received
  • 2014-11-09 17: 17 no data received
  • 2014-11-09 17: 18 device data recieved
  • ...

No slots will be generated for minutes 16 and 17.

6 Add time series elements

Add time series elements through the UPDATE statement with the built-in function PutElem:

Copy
UPDATE wic_mobile_devices_data_hist_ts 
SET device_data = PutElem(device_data, 
                         row('2014-11-09 17:14:00.00000'::DATETIME YEAR TO FRACTION(5), 
                         'john',0,1,0,0,0,0)::mobile_data_type) 
WHERE device_uuid = 'device_1';
UPDATE wic_mobile_devices_data_hist_ts 
SET device_data = PutElem(device_data, 
                         row('2014-11-09 17:19:00.00000'::DATETIME YEAR TO FRACTION(5), 
                         'john',0,1,0,0,0,0)::mobile_data_type) 
WHERE device_uuid = 'device_1'

At this point, the content of the table wic_mobile_device_hist_data_ts, that is displayed by DBAccess, is:

Copy
SELECT * FROM wic_mobile_devices_data_hist_ts
Copy
device_uuid  device_1
device_data  origin(2014-11-09 17:14:00.00000), calendar(cal_1min_2014), 
             container(mobile_data_ct), threshold(0), irregular, 
             [('john',0,1,0,0000000000,0,0000000000,0,0)@2014-11-09 17:14:00.00000, 
              ('john',0,1,0,0000000000,0,0000000000,0,0)@2014-11-09 17:19:00.00000, 
              ('john',0,1,0,0000000000,0,0000000000,0,0)@2014-11-09 17:19:00.00000]

If time series had been initialized as regular, the content would be:

Copy
device_uuid  device_1
device_data  origin(2014-11-09 17:14:00.00000), calendar(cal_1min_2014), 
             container(mobile_data_ct), threshold(0), regular, 
             [('john',0,1,0,0000000000,0,0000000000,0,0),NULL,NULL,NULL,NULL, 
              ('john',0,1,0,0000000000,0,0000000000,0,0)]

Each NULL means empty slot. No data was recieved in that minute.

PutElemNoDups updates the row if the data already exists at the given time interval. Otherwise a new row is inserted:

Copy
UPDATE wic_mobile_devices_data_hist_ts 
   SET device_data = PutElemNoDups(device_data,
                      row('2014-11-10 00:45:00.00000',
                          'john',14,12,10,9,8,7)::mobile_data_type) 
 WHERE device_uuid = 'device_1'

There is the option to create a view in order to enter values of time series with INSERT statement:

Copy
EXECUTE PROCEDURE tscreatevirtualtab ('wic_mobile_devices_data_hist_ts_vti', 
'wic_mobile_devices_data_hist_ts','origin(2014-11-09 17:14:00.00000), calendar(cal_1min_2014), container(mobile_data_ct)');
Copy
INSERT INTO wic_mobile_devices_data_hist_ts_vti
     VALUES ('test3','2014-11-09 17:20:00','john',0,1,0,0,0,0)

7 Loading data with BulkLoad function

Copy
UPDATE wic_mobile_devices_data_hist_ts  
   SET device_data = BulkLoad(device_data , 'data.unl') 
 WHERE device_uuid ='device_1'

The data file format follows the row type convention and each line of the data file contains all the data for one element of the TimeSeries. Below shows you the data file content for the wic_mobile_devices_data_hist_ts update used in the previous example.

Copy
row(2014-11-10 00:00:00.00000, john, 6,8,8,10,0,0)
row(2014-11-10 00:15:00.00000, john, 8,10,12,10,0,0)
row(2014-11-10 00:30:00.00000, john, 8,9,12,10,0,0)
row(2014-11-10 00:45:00.00000, john, 7,6,12,9,0,0)

8 TimeSeries functions

8.1 DelRange

The Delrange function is the ideal function to use if you want to purge the TimeSeries data in any given range. DelRange removes the elements from the pages and also frees up the pages once they are empty.

Copy
UPDATE wic_mobile_devices_data_hist_ts
   SET device_data = DelRange(device_data,
                              '2014-11-10 00:00:00':: datetime year to fraction(5),
                              '2014-11-10 00:15:00'::datetime year to fraction(5))
 WHERE device_uuid = 'device_1'

8.2 Deltrim

The Deltrim function is similar to Delrange. The difference is that it removes the elements from the pages but doesn't free the pages once they are empty.

Copy
UPDATE wic_mobile_devices_data_hist_ts
   SET device_data = Deltrim(device_data,
                              '2014-11-10 00:30:00':: datetime year to fraction(5),
                              '2014-11-10 00:45:00'::datetime year to fraction(5))
 WHERE device_uuid = 'device_1'

8.3 NullCleanup

NullCleanup is the ideal function to use if you want to free up the pages to which there are no elements written, or where elements have been deleted and pages have become empty.

  • To free up the empty pages in given date time range:
Copy
UPDATE wic_mobile_devices_data_hist_ts
   SET device_data = NullCleanup(device_data,
                                '2014-11-10 00:30:00':: datetime year to fraction(5),
                                '2014-11-10 00:45:00'::datetime year to fraction(5))
 WHERE device_uuid ='device_1'
  • To free up the empty pages in total TimeSeries
Copy
UPDATE wic_mobile_devices_data_hist_ts
   SET device_data = NullCleanup(device_data)
 WHERE device_uuid ='device_1'

8.4 TSToXML

The TSToXML function returns an XML representation of a time series.

Copy
SELECT TSToXML('devicedata', device_uuid, Clip(device_data,
               '2014-01-01 00:00:00'::datetime year to second,
               '2015-01-01 13:30:00'::datetime year to second ))
  FROM wic_mobile_devices_data_hist_ts
 WHERE device_uuid ='device_1';

Output:

Copy
<devicedata>
   <id>device_1</id>
   <AllData>1</AllData>
   <mobile_data_type>
      <device_last_date>2014-11-10 00:45:00.00000</device_last_date>
      <device_last_user>john</device_last_user>
      <device_last_battery>14</device_last_battery>
      <device_last_gps_enabled>12</device_last_gps_enabled>
      <device_last_gps_lat>10,0000000000</device_last_gps_lat>
      <device_last_gps_lng>9,0000000000</device_last_gps_lng>
      <device_last_network>8</device_last_network>
      <device_last_activity>7</device_last_activity>
   </mobile_data_type>
   <mobile_data_type>
      <device_last_date>2014-11-10 00:50:00.00000</device_last_date>
      <device_last_user>john                </device_last_user>
      <device_last_battery>14</device_last_battery>
      <device_last_gps_enabled>12</device_last_gps_enabled>
      <device_last_gps_lat>10,0000000000</device_last_gps_lat>
      <device_last_gps_lng>9,0000000000</device_last_gps_lng>
      <device_last_network>8</device_last_network>
      <device_last_activity>7</device_last_activity>
   </mobile_data_type>
</devicedata>

9 Renaming a database with time series fields

If there are problems to rename a database that has timeseries field can do the following. Delete the table that contains the timeseries column.

Copy
DROP TABLE wic_mobile_devices_data_hist_ts_vti;
DROP TABLE wic_mobile_devices_data_hist_ts;

Run the following function with the specific version that has been installed of the blade.

Copy
EXECUTE FUNCTION SYSBldPrepare('TimeSeries.6.00.FC3','drop');

Then perform the rename:

Copy
RENAME DATABASE wic_conf_dist to wic_conf;

And then to create them again in the wic_conf with the specific version that was uninstalled.

Copy
EXECUTE FUNCTION SYSBldPrepare('TimeSeries.6.00.FC3','create');

And create the table again.

Copy
CREATE TABLE wic_mobile_devices_data_hist_ts (device_uuid CHAR(40),
                                              device_data TimeSeries(mobile_data_type));
EXECUTE PROCEDURE tscreatevirtualtab ('wic_mobile_devices_data_hist_ts_vti', 
                                      'wic_mobile_devices_data_hist_ts');

10 Clean timeseries tables and references

Then TSContainerDestroy procedure deletes the container row from the TSContainerTable table and removes the container and its corresponding system catalog rows.

Syntax

Copy
TSContainerDestroy(container_name varchar(128,1));
  • container_name: The name of the container to destroy.

You can destroy a container only if no time series exist in that container; even an empty time series prevents a container from being destroyed.

Only users with update privileges on the TSContainerTable table can run this procedure.

Example

The following example destroys the container ctnr_stock:

Copy
execute procedure TSContainerDestroy('ctnr_stock');

11 More information

For more information visit these links: