SlideShare a Scribd company logo
OKC MySQL Users Group
OKC MySQL
● Discuss topics about MySQL and related open source RDBMS
● Discuss complementary topics (big data, NoSQL, etc)
● Help to grow the local ecosystem through meetups and events
Where's Waldo?
MySQL and Geodata
What is Geodata?
● Encompasses a wide array of topics
● Revolves around geo-positioning data (latitude/longitude)
● Point data (single lat/lon)
● Bounded areas (think radius from point)
● Defined area (think city limits outline on map)
● Often includes some function of distance
● Distance between points
● All points within x, y
Why do we care?
● Here are some commonly asked questions based around
geodata:
● What are the 5 closest BBQ restaurants to my hotel?
● How far is it from here to the airport?
● How many restaurants are there within 25 miles of my
hotel?
● These are all fairly common questions – especially with the
prevalence of geo-enabled devices (anyone here ever enable
“Location Services”?)
Other Industries
● Oil/gas exploration
● Meteorology
● Logistics companies
● < INSERT YOUR INDUSTRY HERE >
● The point: geodata is so readily available, you are likely already
using it or will be soon!
High Level theory and formulas...
… everyone's favorite
● Distance between points on sphere (The Haversine Formula)
● Ok, everyone get out your calculators and slide rules...
en MySQL por favor...
● MySQL prior to 5.6
● Get out your calculators
● MySQL 5.6
● Introduced st_distance (built-in)
Enough with the theory already!
SET @src_lat = 37; SET @src_lng = -133;
SET @dest_lat = 38; SET @dest_lng = -133;
SELECT (3959 * acos(cos(radians(@src_lat)) *
cos(radians(@dest_lat)) * cos(radians(@dest_lng) -
radians(@src_lng)) + sin(radians(@src_lat)) *
sin( radians(@dest_lat)))) as GreatCircleDistance
+---------------------+
| GreatCircleDistance |
+---------------------+
| 69.09758508647379 |
+---------------------+
● Huzzah!! The distance between two latitude lines is 69 miles!
… lets put it all together
Find me all zip codes within 25 miles of my current zip code...
● Table Structure (pre 5.6)
CREATE TABLE `zipcodes_indexed` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ZIP` varchar(255) DEFAULT NULL,
`Latitude` decimal(10,8) DEFAULT NULL,
`Longitude` decimal(11,8) DEFAULT NULL,
`City` varchar(255) DEFAULT NULL,
`State` varchar(255) DEFAULT NULL,
`County` varchar(255) DEFAULT NULL,
`Type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `lat` (`Latitude`,`Longitude`),
KEY `city` (`City`,`State`),
KEY `state` (`State`)
) ENGINE=InnoDB
… lets put it all together
● Helper Function (pre 5.6)
DELIMITER $$
DROP FUNCTION IF EXISTS DistanceInMiles$$
CREATE FUNCTION DistanceInMiles (src_lat decimal(10,8), src_lng
decimal(11,8), dest_lat decimal(10,8), dest_lng decimal(11,8)) RETURNS
decimal(15,8) DETERMINISTIC
BEGIN
RETURN CAST((3959 * acos(cos(radians(src_lat)) * cos(radians(dest_lat)) *
cos(radians(dest_lng) - radians(src_lng)) + sin( radians(src_lat)) * sin(
radians(dest_lat)))) as decimal(15,8));
END $$
DELIMITER ;
… and results!
mysql> # Norman, OK Post Office (73071)
mysql> SET @srcLat = 35.254049;
Query OK, 0 rows affected (0.00 sec)
mysql> SET @srcLng = -97.300313;
Query OK, 0 rows affected (0.00 sec)
mysql> SET @dist = 25;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT z.ZIP, z.City, z.State,
-> DistanceInMiles(@srcLat, @srcLng, z.Latitude, z.Longitude) as distance
-> FROM zipcodes_indexed z
-> HAVING distance < @dist
-> ORDER BY distance
-> LIMIT 10;
+-------+---------------+-------+-------------+
| ZIP | City | State | distance |
+-------+---------------+-------+-------------+
| 73071 | NORMAN | OK | 0.00000000 |
| 73026 | NORMAN | OK | 1.45586169 |
| 73072 | NORMAN | OK | 4.30645795 |
| 73165 | OKLAHOMA CITY | OK | 5.84183161 |
| 73070 | NORMAN | OK | 7.15379176 |
| 73068 | NOBLE | OK | 7.15998471 |
| 73160 | OKLAHOMA CITY | OK | 7.83641939 |
| 73069 | NORMAN | OK | 7.91904816 |
| 73019 | NORMAN | OK | 8.72433716 |
| 73150 | OKLAHOMA CITY | OK | 10.62626848 |
+-------+---------------+-------+-------------+
10 rows in set (0.79 sec)
Not so great...
mysql> EXPLAIN SELECT z.ZIP, z.City, z.State,
-> DistanceInMiles(@srcLat, @srcLng, z.Latitude, z.Longitude) as distance
-> FROM zipcodes_indexed z
-> HAVING distance < @dist
-> ORDER BY distance
-> LIMIT 10G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: z
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 42894
filtered: 100.00
Extra: Using temporary; Using filesort
1 row in set, 1 warning (0.00 sec)
More math to the rescue!
● Rather than scan the whole table, lets just look at a small
rectangle of data (i.e. a bounding box):
1o
Latitude ~= 69 miles
1o
Longitude ~= cos(lat) * 69
$lat_range = radius / 69
$lng_range = abs(radius / (cos(lat) * 69))
$lon1 = $mylng + $lng_range
$lon2 = $mylng - $lng_range
$lat1 = $mylat +$lat_range
$lat2 = $mylat - $lat_range
… and respectable!
mysql> SELECT z.ZIP, z.City, z.State,
-> DistanceInMiles(@srcLat, @srcLng, z.Latitude, z.Longitude) as distance
-> FROM zipcodes_indexed z
-> WHERE z.Longitude BETWEEN -97.744004 AND -96.856621
-> AND z.Latitude BETWEEN 34.891730 AND 35.616367
-> HAVING distance < @dist
-> ORDER BY distance
-> LIMIT 10;
+-------+---------------+-------+-------------+
| ZIP | City | State | distance |
+-------+---------------+-------+-------------+
| 73071 | NORMAN | OK | 0.00000000 |
| 73026 | NORMAN | OK | 1.45586169 |
| 73072 | NORMAN | OK | 4.30645795 |
| 73165 | OKLAHOMA CITY | OK | 5.84183161 |
| 73070 | NORMAN | OK | 7.15379176 |
| 73068 | NOBLE | OK | 7.15998471 |
| 73160 | OKLAHOMA CITY | OK | 7.83641939 |
| 73069 | NORMAN | OK | 7.91904816 |
| 73019 | NORMAN | OK | 8.72433716 |
| 73150 | OKLAHOMA CITY | OK | 10.62626848 |
+-------+---------------+-------+-------------+
10 rows in set (0.00 sec)
Onwards and upwards to Spatial Data types!
Converting our table to geospatial...
● Non-Spatial way:
● Lat / Lon as individual decimal columns
● Composite B-Tree index covering each column
● Spatial way:
● Use the geometry type with a POINT object (single
lat/lon)
● Use the geometry type with a POLYGON object
(defined border)
● Use a SPATIAL index on the geometry column
(MyISAM only through 5.6, added to InnoDB in 5.7)
And voila!
CREATE TABLE `zipcodes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`zip` varchar(255) DEFAULT NULL,
`geo` geometry NOT NULL,
`city` varchar(255) DEFAULT NULL,
`state` varchar(255) DEFAULT NULL,
`county` varchar(255) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `geo` (`geo`),
KEY `city` (`city`,`state`),
KEY `state` (`state`)
) ENGINE=InnoDB
CREATE TABLE `zipcodes` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ZIP` varchar(255) DEFAULT NULL,
`Latitude` decimal(10,8) DEFAULT NULL,
`Longitude` decimal(11,8) DEFAULT NULL,
`City` varchar(255) DEFAULT NULL,
`State` varchar(255) DEFAULT NULL,
`County` varchar(255) DEFAULT NULL,
`Type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `lat` (`Latitude`,`Longitude`),
KEY `city` (`City`,`State`),
KEY `state` (`State`),
KEY `ZIP` (`ZIP`),
KEY `County` (`County`)
) ENGINE=InnoDB
Now, we can use GIS notation to find our zip code:
SELECT zip, city, state, county, type, astext(geo) lon_lat
FROM zipcodes
WHERE ST_CONTAINS(geo, POINT(-97.300313, 35.254049));
So what?
● We had already written a query do just that
● And this one is still doing the same amount of handler
operations!
● This opens up the opportunity to run other GIS based
calculations as we'll see now...
Not just points!
● In earlier slides, we based everything on a single lat/lon
coordinate
● Several “zip code” databases follow this model
● In recent years, the prevalence of full Polygon region databases
has increased
● Enter the US Census provided tl_2014_us_zcta510 schema...
Not just points...
CREATE TABLE `tl_2014_us_zcta510` (
`OGR_FID` int(11) NOT NULL AUTO_INCREMENT,
`SHAPE` geometry NOT NULL,
`zcta5ce10` varchar(5) DEFAULT NULL,
`geoid10` varchar(5) DEFAULT NULL,
`classfp10` varchar(2) DEFAULT NULL,
`mtfcc10` varchar(5) DEFAULT NULL,
`funcstat10` varchar(1) DEFAULT NULL,
`aland10` double DEFAULT NULL,
`awater10` double DEFAULT NULL,
`intptlat10` varchar(11) DEFAULT NULL,
`intptlon10` varchar(12) DEFAULT NULL,
UNIQUE KEY `OGR_FID` (`OGR_FID`),
SPATIAL KEY `SHAPE` (`SHAPE`),
KEY `zcta5ce10` (`zcta5ce10`)
) ENGINE=InnoDB
● This table defines full regions for zip codes as opposed to a
centered lat/lon for the post office
Difference in storage
● Old version for Norman zip code 73071:
● New version in region based version:
● Note that now, we have a full region as opposed to a point...
astext(geo): POINT(-97.300313 35.254049)
astext(shape): POLYGON((-97.44109 35.228675,-97.442413
35.228673,-97.442713 35.228669,-97.442722 35.229179,-
97.442729 35.229632,-97.442727 35.230083,-97.442726
35.230542,-97.442725 35.230998,-97.441071 35.23099,-
97.441072 35.231275,-97.441072 35.231437,-97.442724
35.231464,-97.442722 35.231912,-97.442647 35.231898,-
97.441073 35.231884,-97.441073 35.232346,...
GIS Functions
● st_contains
● Check if an object is entirely within another object
● st_within
● Check if an object is spatially within another object
● st_*
● Detailed list here:
http://dev.mysql.com/doc/refman/5.7/en/spatial-
relation-functions-object-shapes.html
Sample GIS Queries
● # Find me all the zipcodes (polygons) for my points of interest
SELECT raw.zcta5ce10 AS zipcode, pts.name
FROM my_points pts
JOIN tl_2014_us_zcta510 raw ON st_within(pts.loc, raw.SHAPE);
● # Find me all points of interest within a zip code (polygon)
SELECT raw.zcta5ce10 AS zipcode, pts.name
FROM my_points pts
JOIN tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, pts.loc)
WHERE raw.zcta5ce10 = "73071";
Sample GIS Queries
● # Find me all the points of interest within a county
SELECT raw.zcta5ce10 AS zipcode, pts.name
FROM my_points pts
JOIN tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, pts.loc)
WHERE raw.zcta5ce10 IN (SELECT ZIP from legacy.zipcodes_indexed
where County = "Cleveland");
Impact of SPATIAL Key
● I mentioned earlier that SPATIAL keys will be available within
InnoDB starting in 5.7
● Here is just quick sample of the same query, with and without a
SPATIAL key around a polygon
● Lets grab one of the earlier queries:
SELECT raw.zcta5ce10 AS zipcode, pts.name
FROM my_points pts
JOIN tl_2014_us_zcta510 raw ON st_within(pts.loc, raw.SHAPE);
Impact of SPATIAL Key
● With Key ● Without Key
+---------+-------+
| zipcode | name |
+---------+-------+
| 73071 | POI 2 |
| 73069 | POI 3 |
+---------+-------+
2 rows in set (0.00 sec)
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_read_first | 1 |
| Handler_read_key | 4 |
| Handler_read_last | 0 |
| Handler_read_next | 4 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 4 |
| Handler_write | 0 |
+----------------------------+-------+
+---------+-------+
| zipcode | name |
+---------+-------+
| 73069 | POI 3 |
| 73071 | POI 2 |
+---------+-------+
2 rows in set (1 min 4.36 sec)
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_read_first | 2 |
| Handler_read_key | 2 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 33149 |
| Handler_write | 0 |
+----------------------------+-------+
Now, on to some (useful) samples and demos!
Sample Usage
● Living in Oklahoma, the natural first choice for a quick
database generally revolves around... weather!
● This sample uses data from the readily available “current
conditions” flat files available from http://mesonet.org
Mesonet Collector
● Every five minutes (when new observations are posted), grab
the current CSV of all sites
● Load the raw CSV data into a “staging” table
● Clean up the data and move it to the main “observations” table
● Also, an intermediate step that was only run once extracted all
of the site information (lat/lon, name, etc) from the raw data to
populate a base site table (mesonet.sites)
Some Fun Queries
# Get all the mesonet sites in a county (based on GIS coords)
SELECT raw.zcta5ce10 AS zipcode, sites.name
FROM mesonet.sites
JOIN geopoly.tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, sites.pt)
WHERE raw.zcta5ce10 IN (
SELECT ZIP from legacy.zipcodes_indexed where County IN ("Oklahoma")
);
+---------+---------------------+
| zipcode | name |
+---------+---------------------+
| 73084 | Spencer |
| 73107 | Oklahoma City West |
| 73114 | Oklahoma City North |
| 73117 | Oklahoma City East |
+---------+---------------------+
4 rows in set (0.00 sec)
Some Fun Queries
# Get the AVG air temp for all sites in a county (based on GIS)
SELECT raw.zcta5ce10 AS zipcode, sts.name, AVG(TAIR)
FROM mesonet.sites sts
JOIN geopoly.tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, sts.pt)
JOIN mesonet.observations obs ON obs.stid = sts.stid
WHERE raw.zcta5ce10 IN (
SELECT ZIP from legacy.zipcodes_indexed where County IN ("Oklahoma")
)
GROUP BY sts.name;
+---------+---------------------+-----------+
| zipcode | name | AVG(TAIR) |
+---------+---------------------+-----------+
| 73117 | Oklahoma City East | 44.7393 |
| 73114 | Oklahoma City North | 44.3037 |
| 73107 | Oklahoma City West | 44.6729 |
| 73084 | Spencer | 44.0250 |
+---------+---------------------+-----------+
4 rows in set (0.01 sec)
And now is when things fall apart...
Err...
I mean it is time for the live demo!
GPX Parsing
● As I wanted another sample, I looked through my phone to find
an app I use with GPS frequently: MotionX-GPS (mainly for
hiking/hunting)
● This app lets you:
● Record waypoints
● Record full tracks
● Export tracks in GPX format (bonus)
GPX Parsing App
● Now to come up with something useful :)
● Off the top of my head, I thought it would be cool to record a
drive, then map those points out and see how many miles I had
driven in each zip code
● Exciting stuff, I know!
● Note some possible other uses would be real logistics tracking
(think fleet vehicles), tornado tracks, pipeline, etc
Adios slides, hello text editor and shell!
Thanks for coming!
Website: http://okcmysql.org
Twitter: @okcmysql
Email: mike@okcmysql.org

More Related Content

What's hot

Performance features12102 doag_2014
Performance features12102 doag_2014Performance features12102 doag_2014
Performance features12102 doag_2014
Trivadis
 
Intro To PostGIS
Intro To PostGISIntro To PostGIS
Intro To PostGIS
mleslie
 
On Beyond (PostgreSQL) Data Types
On Beyond (PostgreSQL) Data TypesOn Beyond (PostgreSQL) Data Types
On Beyond (PostgreSQL) Data Types
Jonathan Katz
 
Using PostGIS To Add Some Spatial Flavor To Your Application
Using PostGIS To Add Some Spatial Flavor To Your ApplicationUsing PostGIS To Add Some Spatial Flavor To Your Application
Using PostGIS To Add Some Spatial Flavor To Your ApplicationSteven Pousty
 
Why is postgis awesome?
Why is postgis awesome?Why is postgis awesome?
Why is postgis awesome?
Kasper Van Lombeek
 
Scaling PostreSQL with Stado
Scaling PostreSQL with StadoScaling PostreSQL with Stado
Scaling PostreSQL with StadoJim Mlodgenski
 
Day 6 - PostGIS
Day 6 - PostGISDay 6 - PostGIS
Day 6 - PostGIS
Barry Jones
 
ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...
Altinity Ltd
 
Creating Stunning Maps in GeoServer: mastering SLD and CSS styles
Creating Stunning Maps in GeoServer: mastering SLD and CSS stylesCreating Stunning Maps in GeoServer: mastering SLD and CSS styles
Creating Stunning Maps in GeoServer: mastering SLD and CSS styles
GeoSolutions
 
ClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei MilovidovClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei Milovidov
Altinity Ltd
 
Data Science Connect, July 22nd 2014 @IBM Innovation Center Zurich
Data Science Connect, July 22nd 2014 @IBM Innovation Center ZurichData Science Connect, July 22nd 2014 @IBM Innovation Center Zurich
Data Science Connect, July 22nd 2014 @IBM Innovation Center Zurich
Romeo Kienzler
 
Mysqlconf2013 mariadb-cassandra-interoperability
Mysqlconf2013 mariadb-cassandra-interoperabilityMysqlconf2013 mariadb-cassandra-interoperability
Mysqlconf2013 mariadb-cassandra-interoperabilitySergey Petrunya
 
Tricks every ClickHouse designer should know, by Robert Hodges, Altinity CEO
Tricks every ClickHouse designer should know, by Robert Hodges, Altinity CEOTricks every ClickHouse designer should know, by Robert Hodges, Altinity CEO
Tricks every ClickHouse designer should know, by Robert Hodges, Altinity CEO
Altinity Ltd
 
Accelerating Local Search with PostgreSQL (KNN-Search)
Accelerating Local Search with PostgreSQL (KNN-Search)Accelerating Local Search with PostgreSQL (KNN-Search)
Accelerating Local Search with PostgreSQL (KNN-Search)
Jonathan Katz
 
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
Altinity Ltd
 
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
Altinity Ltd
 
Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...
Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...
Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...
Altinity Ltd
 
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert HodgesWebinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Altinity Ltd
 

What's hot (20)

Performance features12102 doag_2014
Performance features12102 doag_2014Performance features12102 doag_2014
Performance features12102 doag_2014
 
Intro To PostGIS
Intro To PostGISIntro To PostGIS
Intro To PostGIS
 
On Beyond (PostgreSQL) Data Types
On Beyond (PostgreSQL) Data TypesOn Beyond (PostgreSQL) Data Types
On Beyond (PostgreSQL) Data Types
 
Using PostGIS To Add Some Spatial Flavor To Your Application
Using PostGIS To Add Some Spatial Flavor To Your ApplicationUsing PostGIS To Add Some Spatial Flavor To Your Application
Using PostGIS To Add Some Spatial Flavor To Your Application
 
Why is postgis awesome?
Why is postgis awesome?Why is postgis awesome?
Why is postgis awesome?
 
Scaling PostreSQL with Stado
Scaling PostreSQL with StadoScaling PostreSQL with Stado
Scaling PostreSQL with Stado
 
Vgg
VggVgg
Vgg
 
Day 6 - PostGIS
Day 6 - PostGISDay 6 - PostGIS
Day 6 - PostGIS
 
ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...
 
Pycon2011
Pycon2011Pycon2011
Pycon2011
 
Creating Stunning Maps in GeoServer: mastering SLD and CSS styles
Creating Stunning Maps in GeoServer: mastering SLD and CSS stylesCreating Stunning Maps in GeoServer: mastering SLD and CSS styles
Creating Stunning Maps in GeoServer: mastering SLD and CSS styles
 
ClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei MilovidovClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei Milovidov
 
Data Science Connect, July 22nd 2014 @IBM Innovation Center Zurich
Data Science Connect, July 22nd 2014 @IBM Innovation Center ZurichData Science Connect, July 22nd 2014 @IBM Innovation Center Zurich
Data Science Connect, July 22nd 2014 @IBM Innovation Center Zurich
 
Mysqlconf2013 mariadb-cassandra-interoperability
Mysqlconf2013 mariadb-cassandra-interoperabilityMysqlconf2013 mariadb-cassandra-interoperability
Mysqlconf2013 mariadb-cassandra-interoperability
 
Tricks every ClickHouse designer should know, by Robert Hodges, Altinity CEO
Tricks every ClickHouse designer should know, by Robert Hodges, Altinity CEOTricks every ClickHouse designer should know, by Robert Hodges, Altinity CEO
Tricks every ClickHouse designer should know, by Robert Hodges, Altinity CEO
 
Accelerating Local Search with PostgreSQL (KNN-Search)
Accelerating Local Search with PostgreSQL (KNN-Search)Accelerating Local Search with PostgreSQL (KNN-Search)
Accelerating Local Search with PostgreSQL (KNN-Search)
 
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
ClickHouse and the Magic of Materialized Views, By Robert Hodges and Altinity...
 
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
ClickHouse Unleashed 2020: Our Favorite New Features for Your Analytical Appl...
 
Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...
Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...
Big Data in Real-Time: How ClickHouse powers Admiral's visitor relationships ...
 
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert HodgesWebinar: Secrets of ClickHouse Query Performance, by Robert Hodges
Webinar: Secrets of ClickHouse Query Performance, by Robert Hodges
 

Similar to MySQL and GIS Programming

MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015
Dave Stokes
 
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
Dave Stokes
 
SQL Windowing
SQL WindowingSQL Windowing
SQL Windowing
Sandun Perera
 
クラウドDWHとしても進化を続けるPivotal Greenplumご紹介
クラウドDWHとしても進化を続けるPivotal Greenplumご紹介クラウドDWHとしても進化を続けるPivotal Greenplumご紹介
クラウドDWHとしても進化を続けるPivotal Greenplumご紹介
Masayuki Matsushita
 
Postgres Conference (PgCon) New York 2019
Postgres Conference (PgCon) New York 2019Postgres Conference (PgCon) New York 2019
Postgres Conference (PgCon) New York 2019
Ibrar Ahmed
 
MySQL 8.0 Preview: What Is Coming?
MySQL 8.0 Preview: What Is Coming?MySQL 8.0 Preview: What Is Coming?
MySQL 8.0 Preview: What Is Coming?
Gabriela Ferrara
 
A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013
Connor McDonald
 
Improved histograms in MariaDB 10.8
Improved histograms in MariaDB 10.8Improved histograms in MariaDB 10.8
Improved histograms in MariaDB 10.8
Sergey Petrunya
 
Dbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineersDbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineers
Riyaj Shamsudeen
 
Scaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQLScaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQL
Jim Mlodgenski
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
Connor McDonald
 
Practical JSON in MySQL 5.7 and Beyond
Practical JSON in MySQL 5.7 and BeyondPractical JSON in MySQL 5.7 and Beyond
Practical JSON in MySQL 5.7 and Beyond
Ike Walker
 
New SQL features in latest MySQL releases
New SQL features in latest MySQL releasesNew SQL features in latest MySQL releases
New SQL features in latest MySQL releases
Georgi Sotirov
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald Partitioning
InSync Conference
 
MySQLinsanity
MySQLinsanityMySQLinsanity
MySQLinsanity
Stanley Huang
 
My sql regis_handsonlab
My sql regis_handsonlabMy sql regis_handsonlab
My sql regis_handsonlab
sqlhjalp
 
Developers' mDay 2017. - Bogdan Kecman Oracle
Developers' mDay 2017. - Bogdan Kecman OracleDevelopers' mDay 2017. - Bogdan Kecman Oracle
Developers' mDay 2017. - Bogdan Kecman Oracle
mCloud
 
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
mCloud
 
Where the %$#^ Is Everybody? Geospatial Solutions For Oracle APEX
Where the %$#^ Is Everybody? Geospatial Solutions For Oracle APEXWhere the %$#^ Is Everybody? Geospatial Solutions For Oracle APEX
Where the %$#^ Is Everybody? Geospatial Solutions For Oracle APEX
Jim Czuprynski
 

Similar to MySQL and GIS Programming (20)

MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015MySQL 5.7 Tutorial Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015
 
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
 
SQL Windowing
SQL WindowingSQL Windowing
SQL Windowing
 
クラウドDWHとしても進化を続けるPivotal Greenplumご紹介
クラウドDWHとしても進化を続けるPivotal Greenplumご紹介クラウドDWHとしても進化を続けるPivotal Greenplumご紹介
クラウドDWHとしても進化を続けるPivotal Greenplumご紹介
 
Postgres Conference (PgCon) New York 2019
Postgres Conference (PgCon) New York 2019Postgres Conference (PgCon) New York 2019
Postgres Conference (PgCon) New York 2019
 
MySQL 8.0 Preview: What Is Coming?
MySQL 8.0 Preview: What Is Coming?MySQL 8.0 Preview: What Is Coming?
MySQL 8.0 Preview: What Is Coming?
 
A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013A few things about the Oracle optimizer - 2013
A few things about the Oracle optimizer - 2013
 
Improved histograms in MariaDB 10.8
Improved histograms in MariaDB 10.8Improved histograms in MariaDB 10.8
Improved histograms in MariaDB 10.8
 
Dbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineersDbms plan - A swiss army knife for performance engineers
Dbms plan - A swiss army knife for performance engineers
 
Scaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQLScaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQL
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
 
Practical JSON in MySQL 5.7 and Beyond
Practical JSON in MySQL 5.7 and BeyondPractical JSON in MySQL 5.7 and Beyond
Practical JSON in MySQL 5.7 and Beyond
 
New SQL features in latest MySQL releases
New SQL features in latest MySQL releasesNew SQL features in latest MySQL releases
New SQL features in latest MySQL releases
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald Partitioning
 
MySQLinsanity
MySQLinsanityMySQLinsanity
MySQLinsanity
 
My sql regis_handsonlab
My sql regis_handsonlabMy sql regis_handsonlab
My sql regis_handsonlab
 
Developers' mDay 2017. - Bogdan Kecman Oracle
Developers' mDay 2017. - Bogdan Kecman OracleDevelopers' mDay 2017. - Bogdan Kecman Oracle
Developers' mDay 2017. - Bogdan Kecman Oracle
 
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
 
Where the %$#^ Is Everybody? Geospatial Solutions For Oracle APEX
Where the %$#^ Is Everybody? Geospatial Solutions For Oracle APEXWhere the %$#^ Is Everybody? Geospatial Solutions For Oracle APEX
Where the %$#^ Is Everybody? Geospatial Solutions For Oracle APEX
 

Recently uploaded

Unleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdf
Unleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdfUnleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdf
Unleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdf
Enterprise Wired
 
Nanandann Nilekani's ppt On India's .pdf
Nanandann Nilekani's ppt On India's .pdfNanandann Nilekani's ppt On India's .pdf
Nanandann Nilekani's ppt On India's .pdf
eddie19851
 
Malana- Gimlet Market Analysis (Portfolio 2)
Malana- Gimlet Market Analysis (Portfolio 2)Malana- Gimlet Market Analysis (Portfolio 2)
Malana- Gimlet Market Analysis (Portfolio 2)
TravisMalana
 
Enhanced Enterprise Intelligence with your personal AI Data Copilot.pdf
Enhanced Enterprise Intelligence with your personal AI Data Copilot.pdfEnhanced Enterprise Intelligence with your personal AI Data Copilot.pdf
Enhanced Enterprise Intelligence with your personal AI Data Copilot.pdf
GetInData
 
Influence of Marketing Strategy and Market Competition on Business Plan
Influence of Marketing Strategy and Market Competition on Business PlanInfluence of Marketing Strategy and Market Competition on Business Plan
Influence of Marketing Strategy and Market Competition on Business Plan
jerlynmaetalle
 
原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样
原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样
原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样
u86oixdj
 
一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理
一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理
一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理
ahzuo
 
My burning issue is homelessness K.C.M.O.
My burning issue is homelessness K.C.M.O.My burning issue is homelessness K.C.M.O.
My burning issue is homelessness K.C.M.O.
rwarrenll
 
Global Situational Awareness of A.I. and where its headed
Global Situational Awareness of A.I. and where its headedGlobal Situational Awareness of A.I. and where its headed
Global Situational Awareness of A.I. and where its headed
vikram sood
 
原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样
原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样
原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样
u86oixdj
 
Everything you wanted to know about LIHTC
Everything you wanted to know about LIHTCEverything you wanted to know about LIHTC
Everything you wanted to know about LIHTC
Roger Valdez
 
Learn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queriesLearn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queries
manishkhaire30
 
The Building Blocks of QuestDB, a Time Series Database
The Building Blocks of QuestDB, a Time Series DatabaseThe Building Blocks of QuestDB, a Time Series Database
The Building Blocks of QuestDB, a Time Series Database
javier ramirez
 
一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理
一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理
一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理
slg6lamcq
 
State of Artificial intelligence Report 2023
State of Artificial intelligence Report 2023State of Artificial intelligence Report 2023
State of Artificial intelligence Report 2023
kuntobimo2016
 
一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理
一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理
一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理
mzpolocfi
 
一比一原版(UniSA毕业证书)南澳大学毕业证如何办理
一比一原版(UniSA毕业证书)南澳大学毕业证如何办理一比一原版(UniSA毕业证书)南澳大学毕业证如何办理
一比一原版(UniSA毕业证书)南澳大学毕业证如何办理
slg6lamcq
 
一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理
一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理
一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理
dwreak4tg
 
Analysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performanceAnalysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performance
roli9797
 
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data LakeViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
Walaa Eldin Moustafa
 

Recently uploaded (20)

Unleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdf
Unleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdfUnleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdf
Unleashing the Power of Data_ Choosing a Trusted Analytics Platform.pdf
 
Nanandann Nilekani's ppt On India's .pdf
Nanandann Nilekani's ppt On India's .pdfNanandann Nilekani's ppt On India's .pdf
Nanandann Nilekani's ppt On India's .pdf
 
Malana- Gimlet Market Analysis (Portfolio 2)
Malana- Gimlet Market Analysis (Portfolio 2)Malana- Gimlet Market Analysis (Portfolio 2)
Malana- Gimlet Market Analysis (Portfolio 2)
 
Enhanced Enterprise Intelligence with your personal AI Data Copilot.pdf
Enhanced Enterprise Intelligence with your personal AI Data Copilot.pdfEnhanced Enterprise Intelligence with your personal AI Data Copilot.pdf
Enhanced Enterprise Intelligence with your personal AI Data Copilot.pdf
 
Influence of Marketing Strategy and Market Competition on Business Plan
Influence of Marketing Strategy and Market Competition on Business PlanInfluence of Marketing Strategy and Market Competition on Business Plan
Influence of Marketing Strategy and Market Competition on Business Plan
 
原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样
原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样
原版制作(swinburne毕业证书)斯威本科技大学毕业证毕业完成信一模一样
 
一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理
一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理
一比一原版(UIUC毕业证)伊利诺伊大学|厄巴纳-香槟分校毕业证如何办理
 
My burning issue is homelessness K.C.M.O.
My burning issue is homelessness K.C.M.O.My burning issue is homelessness K.C.M.O.
My burning issue is homelessness K.C.M.O.
 
Global Situational Awareness of A.I. and where its headed
Global Situational Awareness of A.I. and where its headedGlobal Situational Awareness of A.I. and where its headed
Global Situational Awareness of A.I. and where its headed
 
原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样
原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样
原版制作(Deakin毕业证书)迪肯大学毕业证学位证一模一样
 
Everything you wanted to know about LIHTC
Everything you wanted to know about LIHTCEverything you wanted to know about LIHTC
Everything you wanted to know about LIHTC
 
Learn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queriesLearn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queries
 
The Building Blocks of QuestDB, a Time Series Database
The Building Blocks of QuestDB, a Time Series DatabaseThe Building Blocks of QuestDB, a Time Series Database
The Building Blocks of QuestDB, a Time Series Database
 
一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理
一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理
一比一原版(Adelaide毕业证书)阿德莱德大学毕业证如何办理
 
State of Artificial intelligence Report 2023
State of Artificial intelligence Report 2023State of Artificial intelligence Report 2023
State of Artificial intelligence Report 2023
 
一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理
一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理
一比一原版(Dalhousie毕业证书)达尔豪斯大学毕业证如何办理
 
一比一原版(UniSA毕业证书)南澳大学毕业证如何办理
一比一原版(UniSA毕业证书)南澳大学毕业证如何办理一比一原版(UniSA毕业证书)南澳大学毕业证如何办理
一比一原版(UniSA毕业证书)南澳大学毕业证如何办理
 
一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理
一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理
一比一原版(BCU毕业证书)伯明翰城市大学毕业证如何办理
 
Analysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performanceAnalysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performance
 
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data LakeViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
 

MySQL and GIS Programming

  • 2. OKC MySQL ● Discuss topics about MySQL and related open source RDBMS ● Discuss complementary topics (big data, NoSQL, etc) ● Help to grow the local ecosystem through meetups and events
  • 4. What is Geodata? ● Encompasses a wide array of topics ● Revolves around geo-positioning data (latitude/longitude) ● Point data (single lat/lon) ● Bounded areas (think radius from point) ● Defined area (think city limits outline on map) ● Often includes some function of distance ● Distance between points ● All points within x, y
  • 5. Why do we care? ● Here are some commonly asked questions based around geodata: ● What are the 5 closest BBQ restaurants to my hotel? ● How far is it from here to the airport? ● How many restaurants are there within 25 miles of my hotel? ● These are all fairly common questions – especially with the prevalence of geo-enabled devices (anyone here ever enable “Location Services”?)
  • 6. Other Industries ● Oil/gas exploration ● Meteorology ● Logistics companies ● < INSERT YOUR INDUSTRY HERE > ● The point: geodata is so readily available, you are likely already using it or will be soon!
  • 7. High Level theory and formulas... … everyone's favorite ● Distance between points on sphere (The Haversine Formula) ● Ok, everyone get out your calculators and slide rules...
  • 8. en MySQL por favor... ● MySQL prior to 5.6 ● Get out your calculators ● MySQL 5.6 ● Introduced st_distance (built-in)
  • 9. Enough with the theory already! SET @src_lat = 37; SET @src_lng = -133; SET @dest_lat = 38; SET @dest_lng = -133; SELECT (3959 * acos(cos(radians(@src_lat)) * cos(radians(@dest_lat)) * cos(radians(@dest_lng) - radians(@src_lng)) + sin(radians(@src_lat)) * sin( radians(@dest_lat)))) as GreatCircleDistance +---------------------+ | GreatCircleDistance | +---------------------+ | 69.09758508647379 | +---------------------+ ● Huzzah!! The distance between two latitude lines is 69 miles!
  • 10. … lets put it all together Find me all zip codes within 25 miles of my current zip code... ● Table Structure (pre 5.6) CREATE TABLE `zipcodes_indexed` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `ZIP` varchar(255) DEFAULT NULL, `Latitude` decimal(10,8) DEFAULT NULL, `Longitude` decimal(11,8) DEFAULT NULL, `City` varchar(255) DEFAULT NULL, `State` varchar(255) DEFAULT NULL, `County` varchar(255) DEFAULT NULL, `Type` varchar(255) DEFAULT NULL, PRIMARY KEY (`ID`), KEY `lat` (`Latitude`,`Longitude`), KEY `city` (`City`,`State`), KEY `state` (`State`) ) ENGINE=InnoDB
  • 11. … lets put it all together ● Helper Function (pre 5.6) DELIMITER $$ DROP FUNCTION IF EXISTS DistanceInMiles$$ CREATE FUNCTION DistanceInMiles (src_lat decimal(10,8), src_lng decimal(11,8), dest_lat decimal(10,8), dest_lng decimal(11,8)) RETURNS decimal(15,8) DETERMINISTIC BEGIN RETURN CAST((3959 * acos(cos(radians(src_lat)) * cos(radians(dest_lat)) * cos(radians(dest_lng) - radians(src_lng)) + sin( radians(src_lat)) * sin( radians(dest_lat)))) as decimal(15,8)); END $$ DELIMITER ;
  • 12. … and results! mysql> # Norman, OK Post Office (73071) mysql> SET @srcLat = 35.254049; Query OK, 0 rows affected (0.00 sec) mysql> SET @srcLng = -97.300313; Query OK, 0 rows affected (0.00 sec) mysql> SET @dist = 25; Query OK, 0 rows affected (0.00 sec) mysql> SELECT z.ZIP, z.City, z.State, -> DistanceInMiles(@srcLat, @srcLng, z.Latitude, z.Longitude) as distance -> FROM zipcodes_indexed z -> HAVING distance < @dist -> ORDER BY distance -> LIMIT 10; +-------+---------------+-------+-------------+ | ZIP | City | State | distance | +-------+---------------+-------+-------------+ | 73071 | NORMAN | OK | 0.00000000 | | 73026 | NORMAN | OK | 1.45586169 | | 73072 | NORMAN | OK | 4.30645795 | | 73165 | OKLAHOMA CITY | OK | 5.84183161 | | 73070 | NORMAN | OK | 7.15379176 | | 73068 | NOBLE | OK | 7.15998471 | | 73160 | OKLAHOMA CITY | OK | 7.83641939 | | 73069 | NORMAN | OK | 7.91904816 | | 73019 | NORMAN | OK | 8.72433716 | | 73150 | OKLAHOMA CITY | OK | 10.62626848 | +-------+---------------+-------+-------------+ 10 rows in set (0.79 sec)
  • 13. Not so great... mysql> EXPLAIN SELECT z.ZIP, z.City, z.State, -> DistanceInMiles(@srcLat, @srcLng, z.Latitude, z.Longitude) as distance -> FROM zipcodes_indexed z -> HAVING distance < @dist -> ORDER BY distance -> LIMIT 10G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: z partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 42894 filtered: 100.00 Extra: Using temporary; Using filesort 1 row in set, 1 warning (0.00 sec)
  • 14. More math to the rescue! ● Rather than scan the whole table, lets just look at a small rectangle of data (i.e. a bounding box): 1o Latitude ~= 69 miles 1o Longitude ~= cos(lat) * 69 $lat_range = radius / 69 $lng_range = abs(radius / (cos(lat) * 69)) $lon1 = $mylng + $lng_range $lon2 = $mylng - $lng_range $lat1 = $mylat +$lat_range $lat2 = $mylat - $lat_range
  • 15. … and respectable! mysql> SELECT z.ZIP, z.City, z.State, -> DistanceInMiles(@srcLat, @srcLng, z.Latitude, z.Longitude) as distance -> FROM zipcodes_indexed z -> WHERE z.Longitude BETWEEN -97.744004 AND -96.856621 -> AND z.Latitude BETWEEN 34.891730 AND 35.616367 -> HAVING distance < @dist -> ORDER BY distance -> LIMIT 10; +-------+---------------+-------+-------------+ | ZIP | City | State | distance | +-------+---------------+-------+-------------+ | 73071 | NORMAN | OK | 0.00000000 | | 73026 | NORMAN | OK | 1.45586169 | | 73072 | NORMAN | OK | 4.30645795 | | 73165 | OKLAHOMA CITY | OK | 5.84183161 | | 73070 | NORMAN | OK | 7.15379176 | | 73068 | NOBLE | OK | 7.15998471 | | 73160 | OKLAHOMA CITY | OK | 7.83641939 | | 73069 | NORMAN | OK | 7.91904816 | | 73019 | NORMAN | OK | 8.72433716 | | 73150 | OKLAHOMA CITY | OK | 10.62626848 | +-------+---------------+-------+-------------+ 10 rows in set (0.00 sec)
  • 16. Onwards and upwards to Spatial Data types!
  • 17. Converting our table to geospatial... ● Non-Spatial way: ● Lat / Lon as individual decimal columns ● Composite B-Tree index covering each column ● Spatial way: ● Use the geometry type with a POINT object (single lat/lon) ● Use the geometry type with a POLYGON object (defined border) ● Use a SPATIAL index on the geometry column (MyISAM only through 5.6, added to InnoDB in 5.7)
  • 18. And voila! CREATE TABLE `zipcodes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `zip` varchar(255) DEFAULT NULL, `geo` geometry NOT NULL, `city` varchar(255) DEFAULT NULL, `state` varchar(255) DEFAULT NULL, `county` varchar(255) DEFAULT NULL, `type` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), SPATIAL KEY `geo` (`geo`), KEY `city` (`city`,`state`), KEY `state` (`state`) ) ENGINE=InnoDB CREATE TABLE `zipcodes` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `ZIP` varchar(255) DEFAULT NULL, `Latitude` decimal(10,8) DEFAULT NULL, `Longitude` decimal(11,8) DEFAULT NULL, `City` varchar(255) DEFAULT NULL, `State` varchar(255) DEFAULT NULL, `County` varchar(255) DEFAULT NULL, `Type` varchar(255) DEFAULT NULL, PRIMARY KEY (`ID`), KEY `lat` (`Latitude`,`Longitude`), KEY `city` (`City`,`State`), KEY `state` (`State`), KEY `ZIP` (`ZIP`), KEY `County` (`County`) ) ENGINE=InnoDB Now, we can use GIS notation to find our zip code: SELECT zip, city, state, county, type, astext(geo) lon_lat FROM zipcodes WHERE ST_CONTAINS(geo, POINT(-97.300313, 35.254049));
  • 19. So what? ● We had already written a query do just that ● And this one is still doing the same amount of handler operations! ● This opens up the opportunity to run other GIS based calculations as we'll see now...
  • 20. Not just points! ● In earlier slides, we based everything on a single lat/lon coordinate ● Several “zip code” databases follow this model ● In recent years, the prevalence of full Polygon region databases has increased ● Enter the US Census provided tl_2014_us_zcta510 schema...
  • 21. Not just points... CREATE TABLE `tl_2014_us_zcta510` ( `OGR_FID` int(11) NOT NULL AUTO_INCREMENT, `SHAPE` geometry NOT NULL, `zcta5ce10` varchar(5) DEFAULT NULL, `geoid10` varchar(5) DEFAULT NULL, `classfp10` varchar(2) DEFAULT NULL, `mtfcc10` varchar(5) DEFAULT NULL, `funcstat10` varchar(1) DEFAULT NULL, `aland10` double DEFAULT NULL, `awater10` double DEFAULT NULL, `intptlat10` varchar(11) DEFAULT NULL, `intptlon10` varchar(12) DEFAULT NULL, UNIQUE KEY `OGR_FID` (`OGR_FID`), SPATIAL KEY `SHAPE` (`SHAPE`), KEY `zcta5ce10` (`zcta5ce10`) ) ENGINE=InnoDB ● This table defines full regions for zip codes as opposed to a centered lat/lon for the post office
  • 22. Difference in storage ● Old version for Norman zip code 73071: ● New version in region based version: ● Note that now, we have a full region as opposed to a point... astext(geo): POINT(-97.300313 35.254049) astext(shape): POLYGON((-97.44109 35.228675,-97.442413 35.228673,-97.442713 35.228669,-97.442722 35.229179,- 97.442729 35.229632,-97.442727 35.230083,-97.442726 35.230542,-97.442725 35.230998,-97.441071 35.23099,- 97.441072 35.231275,-97.441072 35.231437,-97.442724 35.231464,-97.442722 35.231912,-97.442647 35.231898,- 97.441073 35.231884,-97.441073 35.232346,...
  • 23. GIS Functions ● st_contains ● Check if an object is entirely within another object ● st_within ● Check if an object is spatially within another object ● st_* ● Detailed list here: http://dev.mysql.com/doc/refman/5.7/en/spatial- relation-functions-object-shapes.html
  • 24. Sample GIS Queries ● # Find me all the zipcodes (polygons) for my points of interest SELECT raw.zcta5ce10 AS zipcode, pts.name FROM my_points pts JOIN tl_2014_us_zcta510 raw ON st_within(pts.loc, raw.SHAPE); ● # Find me all points of interest within a zip code (polygon) SELECT raw.zcta5ce10 AS zipcode, pts.name FROM my_points pts JOIN tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, pts.loc) WHERE raw.zcta5ce10 = "73071";
  • 25. Sample GIS Queries ● # Find me all the points of interest within a county SELECT raw.zcta5ce10 AS zipcode, pts.name FROM my_points pts JOIN tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, pts.loc) WHERE raw.zcta5ce10 IN (SELECT ZIP from legacy.zipcodes_indexed where County = "Cleveland");
  • 26. Impact of SPATIAL Key ● I mentioned earlier that SPATIAL keys will be available within InnoDB starting in 5.7 ● Here is just quick sample of the same query, with and without a SPATIAL key around a polygon ● Lets grab one of the earlier queries: SELECT raw.zcta5ce10 AS zipcode, pts.name FROM my_points pts JOIN tl_2014_us_zcta510 raw ON st_within(pts.loc, raw.SHAPE);
  • 27. Impact of SPATIAL Key ● With Key ● Without Key +---------+-------+ | zipcode | name | +---------+-------+ | 73071 | POI 2 | | 73069 | POI 3 | +---------+-------+ 2 rows in set (0.00 sec) +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_read_first | 1 | | Handler_read_key | 4 | | Handler_read_last | 0 | | Handler_read_next | 4 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 4 | | Handler_write | 0 | +----------------------------+-------+ +---------+-------+ | zipcode | name | +---------+-------+ | 73069 | POI 3 | | 73071 | POI 2 | +---------+-------+ 2 rows in set (1 min 4.36 sec) +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_read_first | 2 | | Handler_read_key | 2 | | Handler_read_last | 0 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 33149 | | Handler_write | 0 | +----------------------------+-------+
  • 28. Now, on to some (useful) samples and demos!
  • 29. Sample Usage ● Living in Oklahoma, the natural first choice for a quick database generally revolves around... weather! ● This sample uses data from the readily available “current conditions” flat files available from http://mesonet.org
  • 30. Mesonet Collector ● Every five minutes (when new observations are posted), grab the current CSV of all sites ● Load the raw CSV data into a “staging” table ● Clean up the data and move it to the main “observations” table ● Also, an intermediate step that was only run once extracted all of the site information (lat/lon, name, etc) from the raw data to populate a base site table (mesonet.sites)
  • 31. Some Fun Queries # Get all the mesonet sites in a county (based on GIS coords) SELECT raw.zcta5ce10 AS zipcode, sites.name FROM mesonet.sites JOIN geopoly.tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, sites.pt) WHERE raw.zcta5ce10 IN ( SELECT ZIP from legacy.zipcodes_indexed where County IN ("Oklahoma") ); +---------+---------------------+ | zipcode | name | +---------+---------------------+ | 73084 | Spencer | | 73107 | Oklahoma City West | | 73114 | Oklahoma City North | | 73117 | Oklahoma City East | +---------+---------------------+ 4 rows in set (0.00 sec)
  • 32. Some Fun Queries # Get the AVG air temp for all sites in a county (based on GIS) SELECT raw.zcta5ce10 AS zipcode, sts.name, AVG(TAIR) FROM mesonet.sites sts JOIN geopoly.tl_2014_us_zcta510 raw ON st_contains(raw.SHAPE, sts.pt) JOIN mesonet.observations obs ON obs.stid = sts.stid WHERE raw.zcta5ce10 IN ( SELECT ZIP from legacy.zipcodes_indexed where County IN ("Oklahoma") ) GROUP BY sts.name; +---------+---------------------+-----------+ | zipcode | name | AVG(TAIR) | +---------+---------------------+-----------+ | 73117 | Oklahoma City East | 44.7393 | | 73114 | Oklahoma City North | 44.3037 | | 73107 | Oklahoma City West | 44.6729 | | 73084 | Spencer | 44.0250 | +---------+---------------------+-----------+ 4 rows in set (0.01 sec)
  • 33. And now is when things fall apart...
  • 34. Err... I mean it is time for the live demo!
  • 35. GPX Parsing ● As I wanted another sample, I looked through my phone to find an app I use with GPS frequently: MotionX-GPS (mainly for hiking/hunting) ● This app lets you: ● Record waypoints ● Record full tracks ● Export tracks in GPX format (bonus)
  • 36. GPX Parsing App ● Now to come up with something useful :) ● Off the top of my head, I thought it would be cool to record a drive, then map those points out and see how many miles I had driven in each zip code ● Exciting stuff, I know! ● Note some possible other uses would be real logistics tracking (think fleet vehicles), tornado tracks, pipeline, etc
  • 37. Adios slides, hello text editor and shell!
  • 38. Thanks for coming! Website: http://okcmysql.org Twitter: @okcmysql Email: mike@okcmysql.org