I’ve continued building on my MariaDB GIS and node.js example application that I wrote about two weeks back, https://blog.mariadb.org/node-js-mariadb-and-gis/. The application shows how to load GPX information into MariaDB, using some MariaDB GIS functionality, and making use of the node.js platform together with MariaDB’s non-blocking client.

With the GPX data converted into GIS points in the MariaDB database, I wanted to further expand a little on both the GIS aspect and also look at how some additional data could be shown in the application by using jQuery’s Ajax calls to update a piece of the web based application UI.

To start with, an interesting thing to do when you have a bunch of GIS points in a database table is to do distance calculation with the end result being to get the complete distance of the track formed by the points. There of course exists a bunch of different formulas for this, but since MariaDB yet doesn’t have the third coordinate in GIS, which is altitude (or elevation), I chose to use the concept of the Great Circle Distance, http://en.wikipedia.org/wiki/Great-circle_distance  and the Haversine approach. The algorithm for counting the distance between two points in this way is:

Image1: Haversine formula from http://en.wikipedia.org/wiki/Great-circle_distance

Since we need to make the distance calculations for all distances between the points it makes sense to create a database function for counting the distance between two points:

With the function in place in the database, we can test it with a query that actually will be the base of the query the application will be using to retrieve the distance for the whole track:

In the SELECT query I’ve given the id of the first point of the track and then done an INNER JOIN over the same table to be able to get the second point and calculating the distance between the points. I’ve made sure when inserting the points into the database that they are ordered in such a way that the next point on a track after the previous one always has the following pointId, so that I for example now in this case can tell the query that the join is done on pointId + 1. The outcome of running the SELECT –query is:

The next step is to do this for every point on the track and sum the distances together to get the full length of the track. This is done by changing the query slightly so that there is no specific pointId restriction and making use of the SUM function to sum all the point distances:

With that in place, let’s move to the application side. For the background of setting the whole application up in node.js, please refer to my previous blog post, https://blog.mariadb.org/node-js-mariadb-and-gis/. On the application side I’ll start with defining a new URL mapping through which the distance information will be retrieved. This happens in app.js where a new row is added to the URL mapping section:

In the URL mapping the common.trackInfo –function is called, which is a really simple function just calling data methods for getting a database connection, querying the distance and closing the database connection. Inside the data method [name of method for retrieving distance] the SELECT query for summing up the distances between the points can be seen. The only parameter being given to the query is trackId, which is read from the URL querystring in the normal node.js way of req.param(“trackId”).

On the UI side, let’s make use of the page that plots the track onto Google Maps. In that web page Google’s implementation of jQuery is used, which can be seen in the source code:

Also notice in the source code how the points that are being plotted onto the map are requested through a $.getJSON function call. I’m going to do something similar for getting the distance and displaying it. First though let’s create a link through which the retrieval of the distance is fired and add a placeholder for the distance information by adding a div –block in the HTML: 

With that in place let’s take a look at the jQuery function that will get us the distance:

The function calls the url /trackinfo URL mapping, which returns a JSON formatted output holding the distance information. The distance is easily picked out from JSON and finally placed in the div –block.

Image2: A part of the web page where the distance is shown

As you can see, it’s very straight forward to use MariaDB with node.js and make use of jQuery. Also there are many interesting things that can be done by using the GIS capabilities of MariaDB. In MariaDB 10.1 the third coordinate will be present, which then means that the height differences could be considered in the distance calculations and the outcome would be more precise. In this particular case we were looking at a GPX track from a half marathon run I did. I had a running watch on me, which gathered the information for the track. It showed the final distance of the run to be 21.23 kilometers, while the distance counted with the Haversine -algorithm approach was 21.15 kilometers. The difference could very well be that the watch actually included the altitude into the calculations, but I’m of course not sure about that since I don’t know what algorithms it uses.

This example application’s source code is available on Github. Try it out if you’re interested in MariaDB GIS or using node.js and jQuery with MariaDB.

Screenshot 3: The GPX track shown on Google Maps

The availability of the node.js binding for MariaDB’s non-blocking client library together with the GIS capabilities of MariaDB inspired me to make an example of using node.js and MariaDB to import so-called GPX tracks to a MariaDB database and then show them on a map. GPX tracks are what are stored by many GPS devices including running watches and smartphones.

My project makes use of MariaDB’s non-blocking client library together with the node.js platform and on top of that uses the GIS functionality found in MariaDB 5.5 and 10.0.

To start with let’s go through the software and components I’m using:

  • Node.js – The popular Node.js platform built on Chrome’s JavaScript runtime. An event-driven and non-blocking architecture
  • Express.js – a web application framework for node.js (similar to Sinatra in Ruby). Puts a nice structure on the application and makes configuration easy.
  • Jade – A node.js template engine for outputting in most cases HTML, but can also be used for other XML structured languages
  • node-mariasql – A node.js binding to MariaDB’s non-blocking (MySQL-compatible) client library created by Brian White
  • xml2js – Node module for parsing XML
  • Google Maps – To show the end result on a map

The source code for my application can be found on Github: https://github.com/rasmushoj/nodejs-gpx-mariadb
I’ve licensed it under the MIT license, so feel free to grab it, copy it, reuse it or distribute it. If you build on top of it, it would of course be nice to know and it would appreciated if you dropped an email to me or added a comment here.

Installing the platform

I chose to use Ubuntu 13.10 x64 as the OS for the application. Below is outlined the steps for installing each of the components needed for this application. Before I begin going through them it’s always good to create a new OS user and not run as root. adduser is handy for the purpose. Remember also to add the user to the sudo group if you’re going to make the installation with this new user. In my case I chose to “sudo adduser rasmus sudo”.

Install MariaDB 10.0 by following the instructions found on the downloads repository for MariaDBRemember to choose the right Ubuntu release on that page, which in my case is 13.10 “saucy”. Then follow the instructions on the page. While doing this tutorial the version of MariaDB getting installed was 10.0.7. The application uses MariaDB’s root user with password password1 so you might want to do the same to get this example working without code changes. Create a database named running with the following commands:

In the GitHub repository for the application you’ll find running.sql in the root. Run that with the following command on the server to create the schema for the running -database:

Prepare the environment:
Update the apt repository: sudo apt-get update
Install a compiler: sudo apt-get install build-essential
Install curl which will be needed when installing node.js: sudo apt-get install curl

Install node.js and Node Package Manager (NPM):
sudo apt-get install nodejs
sudo apt-get install nodejs-legacy
sudo apt-get install npm

Install Express.js and Jade:
npm install express
npm install jade

Install the MariaDB non-blocking client:
npm install mariasql
(there might be a few compiler warnings, I at least had a few)

Finally install the xml2js module which we will need:
npm install xml2js

With that done, the platform is set up and the next step is to create an Express.js web application by running the command express nodegpxmariadb, where nodegpxmariadb is the name of the web application. I did it in the home directory of my user. Go to the nodegpxmariadb -directory and make sure all required modules are installed by running npm install.

Configuring the application

In app.js a few different things are specified.

All module dependencies are listed. For my application the two additions to the normal modules set up by express.js is a data.js and a common.js module in which I’ve put all the database handling. The module dependency is defined by adding these rows:

Now the common and data modules are available throughout the application. Common follows the principles of the express.js framework and is done as a so-called route which include the logic for url path mappings mentioned below.

The default  express.js environment configurations are in use like the server running on port 3000. Make sure JSON support is on. It should be there by default:

Another configuration needed is to tell express.js where to store uploaded files:

In addition app.js is the place where all the URL path mappings are defined. The following are needed:

As you can see most of the url path mappings point to the common module, where it’s defined what to do when there is an incoming request for the url path. For /showmap there is no server side logic needed so an html file can just be read and sent to the client.

Start the application

With the configuration in place the application can be started:

You should see a “Welcome to Express” -message if you open up the http://[server ip]:3000 in a browser.

Upload GPX file

Let’s take a closer look at what actually is done in the common.js module. Let’s start with the upload part. Exports.fileForm and exports.fileUpload are handling the displaying of an upload form and respectively actually doing the upload of the file chosen by the user.

node_upload
Screenshot 1: File upload


Parse GPX file

Once a file has been uploaded it gets more interesting. This is when the parsing of a GPX file starts. GPX files are full of tracking points with a certain interval. For example:

As seen above each track point is its own XML node, which holds the longitude and latitude coordinates, elevation, time and some other interesting information such as heart rate. An easy way to handle XML of this type (or in general) is to make use of the node.js library xml2js which parses XML and outputs JSON. It’s very straightforward. I make use of it in in the parseGPX –function.

When we have the GPX content in JSON it’s time to extract the track points and insert them into a MariaDB database. We start by calling the connect –method of the data –module to get a connection to MariaDB. After that we iterate over the JSON contents:

The lon variable holds the longitude coordinate of the trackpoint and lat the latitude. Unfortunately MariaDB doesn’t yet support the 3rd coordinate in GIS, elevation, otherwise we could have added it also. The lon and lat are given to the data.insertPoint –method which stores them as a GIS Point in the database:

Make sure you check out the data.js file for how to connect and disconnect to MariaDB.

Screenshot 2: Parsing the GPX file
Screenshot 2: Parsing the GPX file


Show on map

The final thing I wanted to do was to see how easily I could plot the stored GIS points on a map. To start with we need to retrieve all the GIS points from the database, which is done is data.js in the following way:

From the above we can see that an array is built which is passed directly as an http response and of course by default in JSON format. This is very good for Google Maps which now can point to a URL, which in this case is /track and read the JSON formatted array of points from there and plot a so-called Polyline connecting each of the points to a nice track.

Screenshot 3: The GIS points shown as a polyline on Google Maps
Screenshot 3: The GIS points shown as a polyline on Google Maps

A lot more could of course be done when having the GIS points stored in the database, including:

  • distances could be counted
  • I could view which of my runs that intersect with each other (well this is actually a MariaDB 10.1 feature since INTERSECT will be introduced there)
  • count how many of my runs are inside a certain area
  • time could be added so that duration and pace could be measured

To sum it up, I would say that whenever you think about creating your next app, being it a web application or a smartphone app with the need of a back-end node.js + MariaDB is a great choice and all the pieces needed are available. You’ll have a full blown and proven RDBMS backing up your application.

Also location awareness and other geographical functionality seems to be almost mandatory in new development. MariaDB includes quite a nice (and properly implemented) set of spatial data types, GIS functions and other relevant functionality.

There has been a lot of discussion about MariaDB 10.0 throughout the whole year. When will it be released, what will it include, what is the focus on MariaDB going forward, etc? My feeling is that people have in the past few months started to understand the value of MariaDB 10.0. There is a good group of people and companies that have been trying out and using the MariaDB 10.0 alpha releases and providing us with excellent feedback.

MariaDB 10.0 is a massive release with loads of new features which ease several pain points that MariaDB and MySQL users have run into over the years.

The highlights of MariaDB 10.0 can be divided into the following areas:

  • Replication enhancements
  • Storage engines
  • Optimizer enhancements
  • Administration improvements
  • Other important new features
  • Merged features and functionality from MySQL 5.6

I’ll go through each of these areas briefly to give an overview on what they include.

REPLICATION

Global Transaction Id – In replication, MariaDB 10.0 introduces a new building block, Global Transaction Id(GTID). The implementation is different from the corresponding functionality in MySQL 5.6 and the main goals of the implementation have been 1) make it easy to set up replication with GTID and easily provision new slaves and 2) support other replication features such as Multi-Source Replication (see below). The introduction of GTID also makes the slaves crash safe, which they haven’t been before.

Multi-Source Replication – With Multi-source replication, contributed by Lixun Peng and Taobao you can replicate data from many masters to one slave. This is very useful when you have sharded your data and want a complete copy of it on one server. For this very reason Tumblr, the microblogging site, nowadays part of Yahoo! is already using this feature. Check out the story.

Parallel Slave (sponsored by Google) – Finally, MariaDB 10.0 solves a long lasting replication challenge that even exists in MySQL 5.6. Until now, with enough writes (INSERT/UPDATE) happening on a master the slaves would not be able to keep up at the same pace and they would lag behind. With the parallel slave feature in 10.0 this challenge is now gone. The slaves will adapt to the speed of the master and apply binlog events in parallel. Transactions will be applied in parallel if they were executed in parallel on the master. Unlike MySQL 5.6, the transactions can concern the same database or even the same table.

STORAGE ENGINES

Many storage engine developers have been actively engaging with the developers of MariaDB lately and as a result there are several new storage engines in MariaDB 10.0 (in alphabetical order):

  • Cassandra Storage Engine: Combine data from Cassandra with your data in MariaDB, read and write Cassandra data, and connect many MariaDB servers to one Cassandra ring, creating a high-availability cluster.
  • Connect Storage Engine: Use Connect to handle data in files or behind ODBC as if that data was part of the data stored in MariaDB. Developed and contributed by Olivier Bertrand.
  • Sequence Storage Engine: Create numerical sequences that are stored in memory and can be used in your queries. For some use case examples check this article.
  • Spider Storage Engine: A storage engine with built in sharding capabilities. Developed and contributed by Kentoku Shiba.
  • TokuDB: A storage engine designed for high performance write-intensive workloads. Developed and contributed by Tokutek.

OPTIMIZER

Engine Independent Persistent Statistics – Statistics are now provided separately from storage engines. Before, statistics were supplied by the storage engines themselves and the quality of the statistics were usually quite poor. Also the storage engine interface puts a lot of restrictions on them. Statistics are used by the query optimizer to choose the best execution plan for each SQL statement. Better statistics results in better execution plans and end users will experience faster results in general.

Histograms – To improve query optimization, MariaDB 10.0 introduces histograms. Histograms can be collected for both indexed and non indexed columns. Histogram data allows the query optimizer to make better query plan choices for complex multi-table queries.

Optimizations for EXISTS subqueries – the optimizer will convert EXISTS subqueries to IN, when possible. This conversion allows the usage of semi-join optimizations or Materialization optimization for certain classes of EXISTS subqueries.

ADMIN IMPROVEMENTS

10.0 includes a set of features that make the life of DBAs easier:

  • Roles – This is a big thing! Long awaited roles are introduced in MariaDB. DBAs can now create roles with certain permissions and assign users to the roles. Thanks to Google Summer of Code and developer Vicențiu Ciorbaru!
  • SHOW EXPLAIN – get the query plan of a running statement.
  • EXPLAIN in the Slow Query Log – write EXPLAIN output into the slow query log.
  • EXPLAIN INSERT/UPDATE/DELETE – EXPLAIN for INSERT/UPDATE/DELETE has been added in the same way as in MySQL 5.6, but the implementation is different.
  • SHOW PLUGIN SONAME – list all plugins despite them being installed or not.
  • SHUTDOWN – Finally use SQL to SHUTDOWN the server
  • KILL QUERY ID – Kill a specific query with its id, not the thread id (solves a nasty race condition).
  • Per-connection memory usage – List each connection with amount of memory used

OTHER IMPORTANT NEW FEATURES

There are also a bunch of new interesting features that don’t fall into the above categories:

New REGEXP – The switch to the modern regexp library PCRE together with the new SQL
functions REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR improve MariaDB text processing capabilities drastically. Developed during Google Summer of Code by Sudheera Palihakkara.

DELETE … RETURNING – Many users asked for the possibility for the DELETE statement to return the deleted rows in a resultset. It’s now possible by adding RETURNING at the end of the statement.

ALTER … IF [NOT] EXISTS – In your ALTER statements you can now add the IF or IF NOT keywords to e.g. add a column or create an index if it does or does not exist from before.

Named Dynamic Columns – In earlier versions of MariaDB Dynamic Columns, which allows for a different number of columns in each row, columns could only be referred to by number. Now the columns can be referred to by name.

Multiple GET_LOCK() – The use of many user level locks is now supported. Developed and contributed by Konstantin Osipov.

MERGED FROM MYSQL 5.6

Selected pieces of MySQL 5.6 have been merged into MariaDB 10.0. The main ones are:

  • InnoDB – Most InnoDB enhancements are now in MariaDB 10.0.
  • Performance Schema – The full new performance schema with all the new event filtering, instrumentation, and other goodies.
  • Online ALTER – Do many of your schema changes without interrupting the system
  • Filesort optimization for queries using the ORDER BY … LIMIT optimization – A useful optimization for showing only a few rows of a bigger result set.
  • Privileges for CREATE TEMPORARY TABLES
  • Character set extensions
  • GET DIAGNOSTICS
  • TO_BASE64(), FROM_BASE64

Obviously there exist many smaller enhancements in MariaDB 10.0 and other things merged from 5.6, but the above overview of new features and merges includes the biggest ones.

As you can see, the community has been very active in contributing to 10.0 and it’s absolutely fantastic to be able to have all these new features pulled together into MariaDB and having them available to all MariaDB 10.0 users by default. A big thank you to all contributors!

Go give it a try and download the MariaDB 10.0.5 Beta!

Download MariaDB 10.0.5

Release Notes Changelog What is MariaDB 10.0?

If you’re excited about MariaDB 10.0 and its features or MariaDB in general and have a great MariaDB story to share, about some interesting use of MariaDB or some specific feature you love, please let us know.

PS. If you are attending Percona Live in London make sure you come and celebrate the launch of the MariaDB 10.0 beta with us over a drink or two on Mon 11th Nov. More info here.