Although, the @TrinitronX answer is pretty elegant, it does not work for the wide range of possible semantic versioning values. In particular those, that consist of the pre-release part like 1.0.0-beta.1.
Another way is to keep a sorted list of versions in the MySQL database table. Let's create the following database table:
CREATE TABLE `versions` (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
version VARCHAR(255) COLLATE utf8mb4_bin NOT NULL,
sort_order BIGINT UNSIGNED NOT NULL,
UNIQUE KEY unique_version (version),
KEY idx_sort_order_version (sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Every time we add a new version to the versions DB table we calculate the sort_order value before inserting the record. In theory the complexity of this operation should be O(log n). Having this, we can get the sorted list of versions using the SQL query below:
SELECT `version` FROM `versions` ORDER BY sort_order;
I created the https://github.com/recipe/mysql-sermver project, to implement this idea in two MySQL stored functions:
1. VERSION_COMPARE(version1, version2)
This function supports the Semantic Versioning 2 as well as the most of the real life versions. It returns
0 if the both versions are equal,
1 if the version1 is greater than the version2,
-1 if the version2 is greater than the version1.
SELECT VERSION_COMPARE('1.0.0', '1.0.0');
0
SELECT VERSION_COMPARE('1.0.2-alpha', '1.0.2');
-1
SELECT VERSION_COMPARE('1.0.2-beta', '1.0.2-alpha');
1
2. GET_SORT_ORDER(version)
This function calculates the sort_order value of a newly added version, and can be used inside the BEFORE INSERT database trigger on the versions DB table.
DELIMITER //
CREATE TRIGGER bi_versions_set_sort_order BEFORE INSERT ON versions
FOR EACH ROW
BEGIN
DECLARE v BIGINT UNSIGNED;
IF NEW.sort_order = 0 THEN
SELECT GET_SORT_ORDER(NEW.version) INTO v;
SET NEW.sort_order = v;
END IF;
END //
How it works for the question above?
You need to install these two stored functions from the mysql-semver project to your MySQL database. Then you
can add new versions and select them ordered.
INSERT versions (version, sort_order)
VALUES
('1.1.2', 0),
('9.1', 0),
('2.2', 0),
('4', 0),
('1.2.3.4', 0),
('3.2.14', 0),
('3.2.1.4.2', 0);
SELECT `version` FROM `versions` ORDER BY sort_order;
+---------+
|version |
+---------+
|1.1.2 |
|1.2.3.4 |
|2.2 |
|3.2.1.4.2|
|3.2.14 |
|4 |
|9.1 |
+---------+
1.2.13or1.2.2?011.023.005instead of11.23.5) in a separate column just for sorting purposes?