「スカラー値を抽出する」とは、配列内の各項目を個別にインデックス化することを意味しますか?つまり、... &
必要な数だけ項目を抽出できます。これらは複合値(JSON)ではなく、スカラー(文字列など)として格納されます。
CREATE TABLE mytags (
id INT NOT NULL AUTO_INCREMENT,
tags JSON,
PRIMARY KEY (id)
);
INSERT INTO mytags (tags) VALUES
('["tag1", "tag2", "tag3"]'),
('["tag1", "tag3", "tag5", "tag7"]'),
('["tag2", "tag5"]');
SELECT * FROM mytags;
+----+----------------------------------+
| id | tags |
+----+----------------------------------+
| 1 | ["tag1", "tag2", "tag3"] |
| 2 | ["tag1", "tag3", "tag5", "tag7"] |
| 3 | ["tag2", "tag5"] |
+----+----------------------------------+
のは一つだけのアイテム(JSONオブジェクトから最初の値)でインデックスを作成してみましょう:
ALTER TABLE mytags
ADD COLUMN tags_scalar VARCHAR(255) GENERATED ALWAYS AS (json_extract(tags, '$[0]')),
ADD INDEX tags_index (tags_scalar);
SELECT * FROM mytags;
+----+----------------------------------+-------------+
| id | tags | tags_scalar |
+----+----------------------------------+-------------+
| 1 | ["tag1", "tag2", "tag3"] | "tag1" |
| 2 | ["tag1", "tag3", "tag5", "tag7"] | "tag1" |
| 3 | ["tag2", "tag5"] | "tag2" |
+----+----------------------------------+-------------+
今、あなたはVARCHAR列tags_scalar
にインデックスを持っています。値もスキップすることができ、引用符、含まれています
ALTER TABLE `testy`.`mytags`
DROP COLUMN `tags_scalar`,
DROP INDEX `tags_index`;
ALTER TABLE mytags
ADD COLUMN tags_scalar VARCHAR(255) GENERATED ALWAYS AS (json_extract(tags, '$[0]', '$[1]', '$[2]')),
ADD INDEX tags_index (tags_scalar);
SELECT * from mytags;
+----+----------------------------------+--------------------------+
| id | tags | tags_scalar |
+----+----------------------------------+--------------------------+
| 1 | ["tag1", "tag2", "tag3"] | ["tag1", "tag2", "tag3"] |
| 2 | ["tag1", "tag3", "tag5", "tag7"] | ["tag1", "tag3", "tag5"] |
| 3 | ["tag2", "tag5"] | ["tag2", "tag5"] |
+----+----------------------------------+--------------------------+
または自動生成するany other valid expressionを使用します。
ALTER TABLE `testy`.`mytags`
DROP COLUMN `tags_scalar`,
DROP INDEX `tags_index`;
ALTER TABLE mytags
ADD COLUMN tags_scalar VARCHAR(255) GENERATED ALWAYS AS (json_unquote(json_extract(tags, '$[0]'))),
ADD INDEX tags_index (tags_scalar);
SELECT * FROM mytags;
+----+----------------------------------+-------------+
| id | tags | tags_scalar |
+----+----------------------------------+-------------+
| 1 | ["tag1", "tag2", "tag3"] | tag1 |
| 2 | ["tag1", "tag3", "tag5", "tag7"] | tag1 |
| 3 | ["tag2", "tag5"] | tag2 |
+----+----------------------------------+-------------+
すでに想像できるように、生成された列はJSONから複数の項目を含めることができます"tag1tag3tag5tag7"のように簡単に索引付けして検索できるものを取得するために、JSON構造体から文字列を削除します。
[...](すべてインデックスにするには配列の最大長を知っている必要があります)
。上述のように、あなたが知っている必要はありません - NULL値は、任意の有効な式を使用してスキップすることができます。もちろん、それは常に知っている方が良いです。
ここでアーキテクチャの決定があります:JSONデータ型が目標を達成するのに最も適切ですか?この特定の問題を解決するには? JSONは正しいツールですか?それは検索をスピードアップするつもりですか?
可変長配列のインデックスを作成するにはどうすればよいですか?
あなたは、キャスト文字列を主張する場合:
ALTER TABLE `testy`.`mytags`
DROP COLUMN `tags_scalar`,
DROP INDEX `tags_index`;
ALTER TABLE mytags
ADD COLUMN tags_scalar VARCHAR(255) GENERATED ALWAYS AS (replace(replace(replace(cast(tags as char), '"', ''), '[', ''), ']', '')),
ADD INDEX tags_index (tags_scalar);
SELECT * from mytags;
+----+----------------------------------+------------------------+
| id | tags | tags_scalar |
+----+----------------------------------+------------------------+
| 1 | ["tag1", "tag2", "tag3"] | tag1, tag2, tag3 |
| 2 | ["tag1", "tag3", "tag5", "tag7"] | tag1, tag3, tag5, tag7 |
| 3 | ["tag2", "tag5"] | tag2, tag5 |
+----+----------------------------------+------------------------+
この方法か、あなたが最も適し索引構造(some options)を適用VARCHARまたはTEXTの列、で終わる別。
さらに読書:
いや、スカラーは、単純な値(対複雑なデータ構造)です。 –
mysqlのデータを使って何かをしたいのであれば、それをjsonとして保存しないでください。正規化されたデータとして保存し、必要に応じてjsonとして吐き出します。 – Strawberry
ストロベリーのコメントは重要な点を強調しています。例えば、 '' ["tag2"、 "tag5"] ''と' ["tag5"、 "tag2"]' 'は同じデータですか? –