MySQL 存储数组类型数据

本文其实是标题党, 由于个人经历原因, 一直使用其他类型数据库, 自由 json 等数据类型的支持, 所以在遇到类似需求的时候总是要寻找一个和固有思维相匹配的解决方案.

需要的数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[
{
"service": "blog-api",
"other_key": "other...",
"address": ["http://192.168.31.188", "http://192.168.31.189"]
},
{
"service": "blog-db",
"other_key": "other...",
"address": [
"mongodb://192.168.31.188/blog",
"mongodb://192.168.31.189/blog"
]
}
]

这样的话, 如果使用传统 mongodb, 那么肯定不会有任何迟疑, 问题是我们是 MySQL.

表结构设计

service 表

1
2
3
4
5
CREATE TABLE blog_services (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
service VARCHAR(64) NOT NULL DEFAULT '' UNIQUE,
other_key ...
);

address 表

1
2
3
4
CREATE TABLE blog_address (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
address VARCHAR(64) NOT NULL DEFAULT '',
);

写一个 SQL

1
2
3
4
5
6
7
SELECT
s.service,
s.other_key,
GROUP_CONCAT(DISTINCT(a.address)) as address
FROM blog_services s
LEFT JOIN blog_address a
GROUP BY s.service;

执行结果为

1
2
3
4
service    other_key    address
------------------------------------
blog-api other... http://192.168.31.188,http://192.168.31.189
blog-db other... mongodb://192.168.31.188/blog,mongodb://192.168.31.189/blog

剩下的事儿

将查询出来的数据, 在代码层 map 循环一下, 以 , 分隔成数组即可.

这里需要注意的是, 默认 GROUP_CONCAT 方法是 , 分隔的, 这就意味数据本身应该不包含 ,. 如果需要自定义分割符,

GROUP_CONCAT(DISTINCT(a.address) SEPARATOR '|')

参考文章

  1. 如何在 MySQL 中存储数组
  2. MySQL 中 GROUP BY 结合 GROUP_CONCAT 的使用
Donate - Support to make this site better.
捐助 - 支持我让我做得更好.