Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
This guide requires VillageSQL 0.0.4 or later.
MySQL has no built-in way to represent a point or region in n-dimensional space. You can chain AND conditions across multiple numeric columns, but that only handles containment — it doesn’t extend to distance queries, and it doesn’t let you treat a row’s attributes as a unified geometric value. VillageSQL’s vsql_cube extension adds a cube custom type that makes both kinds of queries natural.

The Problem

Say you have a product catalog where each product has a price, an average rating, and a review count. A buyer wants products priced 5050–200, rated at least 3.5, with at least 50 reviews. That’s a three-way AND:
The AND chain finds matches. But if you want the 5 products most similar to a given one — closest in price, rating, and review count simultaneously — there’s no natural SQL answer. You’d have to pull candidates into application code and compute distances there.

With VillageSQL: the cube type

The cube type stores a point or box in n-dimensional space. A point is a location; a box is a region defined by two corner coordinates. Both live in a regular column.
cube is a MySQL reserved word, so backtick it in DDL. The dimension parameter (3) is required — bare cube without a number isn’t supported.

Inserting data

cube_point_nd() builds a point from a comma-separated string of coordinates:
The coordinates here are (price, rating, review_count) — one point per product.

Range queries with cube_contains

Define your search region as a box. cube_box_nd() takes two comma-separated strings: the lower corner and the upper corner.
cube_contains(@region, attrs) returns 1 when the product’s point falls inside the box — equivalent to all three AND conditions at once, but also composable with distance queries.

Nearest-neighbor with cube_distance

To find the most similar products to a given one, measure Euclidean distance in attribute space:
A note on scaling: price is in the hundreds, rating is 0–5, and review count can be in the thousands. Raw Euclidean distance will be dominated by review count. Normalize all three dimensions to a common scale (e.g., 0–1) before inserting if you want balanced similarity scoring.

Checking overlap

cube_overlaps() returns 1 if two boxes share any space — useful for checking whether a product qualifies for any of several promotion bands:

Troubleshooting

See also