Creating spatial index (PostGIS vs MySQL) - mysql

Is it possible to create index in MySQL similar to this one (PostGIS):
CREATE INDEX spatial_indx_test ON spatial_test USING gist(st_makeline(st_makepoint(x1,y1), st_makepoint(x2,y2)));
where x1,x2,y1,y2 are double-typed numbers stored in the table: spatial_test. Basically is there a way to make index on data that is not directly a column in a table? I've tried smth like this:
CREATE SPATIAL INDEX spatial_indx_test ON spatial_test (LineString(Point(x1,y1), Point(x2,y2));
however it doesn't work in MySQL. Is there any workaround for that?

You can create spation index on the geometry eg:
CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g))
ENGINE=MyISAM;
you can find more here http://dev.mysql.com/doc/refman/5.7/en/creating-spatial-indexes.html and here https://dev.mysql.com/doc/refman/5.7/en/using-spatial-indexes.html

Related

Cannot set spatial index to geometry type - #1464

I use MySQL version 5.5.49. They type of the column is geometry and the engine of the table is InnoDB.
I try something like
ALTER TABLE geom ADD SPATIAL INDEX(field);
or
ALTER TABLE geom ADD SPATIAL INDEX table (field);
or
CREATE SPATIAL INDEX sp_index ON table(field);
and I get the error
#1464 - The used table type doesn't support SPATIAL indexes
Does this has to do with the engine of the table, the version of MySQL or am I missing something?
I read The used table type doesn't support SPATIAL indexes that is the engine that causes the problem. Do I really have to change the engine? InnoDB is more suitable for my needs.

When to add index in a mysql table?

I have a doubt on create table syntax and more in deep when to create index on it.
More in deep I need to create a table by scratch loading ~1 milion record taken from a CSV.
The question is: when should I create an index on the table?
Or better:
- Do I have to prefer to use INDEX syntax on CREATE TABLE statement and then fill the table
or
- Do I have to create table, fill it and then use ALTER TABLE ADD INDEX statement?
Which is faster?
It is good to create index after storing data (specially large data).
Creating index before, will burden more overhead on DBMS.

Table structure for Geo Spatial Data

What is the suggested way to structure a table in a MYSQL Database containing Geo Spatial data. As a POC i am working to insert the data as in the image as below into a database table.
This below is the snapshot of the table creation of Phpmyadmin table creation
looking for suggestions to create table for geospatial data as in screenshots.
EDIT: I am working on XAMPP V1.8.3 Windows8 running MYSQL version 5.6.16.
Created Table geomduplicate and columns and inserted data as in screenshot with the below sql
CREATE TABLE geomduplicate1(
zip INTEGER(3) NOT NULL PRIMARY KEY,
latitude NUMERIC(9,6),
longitude NUMERIC(10,6),
city VARCHAR(10),
state VARCHAR(2),
county VARCHAR(9)
);
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(501,40.922326,-72.637078,'Holtsville','NY','Suffolk');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(544,40.922326,-72.637078,'Holtsville','NY','Suffolk');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(601,18.165273,-66.722583,'Adjuntas','PR','Adjuntas');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(602,18.393103,-67.180953,'Aguada','PR','Aguada');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(603,18.455913,-67.14578,'Aguadilla','PR','Aguadilla');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(604,18.49352,-67.135883,'Aguadilla','PR','Aguadilla');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(605,18.465162,-67.141486,'Aguadilla','PR','Aguadilla');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(606,18.172947,-66.944111,'Maricao','PR','Maricao');
REPLACE INTO geomduplicate1(zip,latitude,longitude,city,state,county) VALUES
(610,18.288685,-67.139696,'Anasco','PR','Anasco');
and the data was successfully inserted in mysql database.
Store it is as a geometry data type. MySQL supports Geometry (generic), as well as Point, Linestring and Polygon data types, see creating spatial data types. A single longitude or latitude value can not be a geometry on its own, as you have it in your screen shot.
If you go the route of using geometry types, it gives you two advantages over having separate latitude and longitude fields: you can add a spatial index and you will be able to use some of MySQL's spatial operator functions such as ST_Buffer, ST_Intersects, ST_Distance to do further analysis. Spatial indexes are based on R-trees and will perform far better than two B-tree indexes on non spatial columns, latitude and longitude -- and this performance difference will grow as your table size grows.
You can still get the latitude and longitude values back by using the X and Y point functions so you will not lose anything by storing your data as a Point.
If you already have your data in two separate lat/lon columns, and you want to go the geometry/point datatype route, you can use the Point function to create the Point datatype:
alter table mytable add column pt POINT;
update mytable set pt=Point(longitude, latitude);
alter table mytable modify pt POINT NOT NULL;
create spatial index ix_spatial_mytable_pt ON mytable(pt);
Note that the Point function was only introduced in MySQL 5.1.x (it isn't too well documented, so I'm not sure of exact version), and before that you had to use concat with the GeomFromText function, see Moving lat/lon text columns into a 'point' type column for some more information on this, although note that Quassnoi's answer has lon and lat the wrong way round -- it is Point(lon, lat) not the other way, though this is a very common mistake.
NOTE: Until recently, you could only index a spatial column if using the MyISAM engine.
EDIT: In the upcoming release, MySQL 5.7.5, InnoDB will finally support indexes on spatial data types (and not just store spatial types without an index, which is considerably less useful). This means you can have foreign keys, ACID guarantees, spatial indexes all in one engine, which has been a long time in coming.
Since version 5.6 MySQL's innodb engine supports spatial data.
Refer the following links -
http://dev.mysql.com/doc/refman/5.6/en/creating-spatial-columns.html
https://dev.mysql.com/doc/refman/5.5/en/gis-data-formats.html
https://dev.mysql.com/doc/refman/5.5/en/populating-spatial-columns.html

Full text search index independent of the table

In SQLite, we can create full text search indices as new objects, like so
CREATE VIRTUAL TABLE search_data USING fts4;
INSERT INTO search_data (description) select description from data;
In MySQL, the only way to do the same seems to be to alter the existing table like so
ALTER TABLE data ADD FULLTEXT(description);
What I am looking for is a way to create the full text index in MySQL as a new independent object without having to duplicate the data of the tables (like I can do in SQLite).
How can I do that?
You can give a name to an index, but the name is valid only within the table (e.g. you can have two indexes with the same name in if they are in different tables). Indexes don't have "global" names.
If you don't want to use ALTER TABLE you can use CREATE INDEX, for example:
create fulltext index INDEXNAME on TABLENAME (COLUMN);

Is there a convenient way to create spatial index with Sqlalchemy or Geoalchemy?

Yesterday someone told me that Geoalchemy was a good choice to support spatial extensions if I want to use Sqlalchemy. It really did good. Thanks for him a lot.
But I have not found a convenient way to create spatial index with Geoalchemy. Must I run this SQL directly?
CREATE SPATIAL INDEX sp_index ON my_class (
geom_col
);
Is there a convenient way to do it without directly writing the SQL?
Thanks!
When creating a table with table.create() GeoAlchemy will automatically create an index for the geometry column.
Also, SQLAlchemy Index instances have a create method. See the "Indexes" section in http://docs.sqlalchemy.org/en/rel_0_7/core/schema.html#metadata-constraints. I'm not sure if you'll be able to create a spatial index in MySQL with that but it's worth a try.
With GeoAlchemy, there are 2 steps you should take to create Spatial Index on the geometry column
add attr 'spatial_index' to the geometry column
Call the GeometryDDL extension
Example:
# note that spatial_index will set the column to not null
class Building(Base):
geom = GeometryColumn(Point(2, spatial_index=True))
GeometryDDL(Building.__table__)