マテリアライズド パスを使用して、SQl (私の場合は MySQL 5.7) にツリー構造を格納しています。パスをスラッシュで区切られたスラッグとして保存しています。私が読んだすべてのチュートリアルでは、行をパスでソートして正しい順序で抽出するように言われていましたが、パスの一部に同様のプレフィックスがある場合は機能しないようです。
いくつかのコード例:
CREATE TABLE categories (
id int(11),
parent_id int(11) DEFAULT NULL,
slug varchar(255),
path varchar(255)
);
INSERT INTO categories VALUES
(1, null, 'foo', '/foo'),
(2, 1, 'bar', '/foo/bar'),
(3, null, 'foo-it', '/foo-it'),
(4, 3, 'boy', '/foo-it/boy');
今、パスでソートすると、間違った順序になります:
SELECT * FROM categories ORDER BY path;
出力:
+------+-----------+--------+-------------+
| id | parent_id | slug | path |
+------+-----------+--------+-------------+
| 1 | NULL | foo | /foo |
| 3 | NULL | foo-it | /foo-it |
| 4 | 3 | boy | /foo-it/boy |
| 2 | 1 | bar | /foo/bar |
+------+-----------+--------+-------------+
4 rows in set (0.00 sec)
これは、ほとんどの (すべての?) 照合順序で - が / の前にあるために発生しているようです。
クレイジーなことは、UNIX の sort コマンドライン ユーティリティが正しいことを行うことです。すべてのパスをファイルに入れて並べ替えると、正しい出力が得られます。
$ sort paths.txt
/foo
/foo/bar
/foo-it
/foo-it/boy
MySQL でツリーを適切にソートする方法はありますか? unix の sort ユーティリティと同じ方法でソートするには? おそらく別の照合か何か?それとも他の裏技?