MySQL JSON 타입 컬럼 사용 해보기
2021-08-07 17:14:25

최근에 MySQL에 컬럼 타입 중 JSON이 있다는 걸 알게 되었다

나온지는 오래 됫음 5.7후반부터 지원되었다고 함

NoSQL처럼 컬럼 제한 없이 자유롭게 쓰라는 의미로 만들어진 거 같은데.. 👀

그래서 10개 키를 가진 JSON 데이터 백만개를 저장 했을 경우 어떤지 비교 해보았다

1
2
3
4
5
6
{
"test1": "랜덤문자",
"test2": "랜덤문자",
"test3": "랜덤문자"
...
}
  1. id(INT), value(JSON) 컬럼에 저장
  2. id(INT), 키 이름(VARCHAR) 10개를 만들어서 저장

크기

저장 후 테이블 사이즈를 확인 해보니 JSON 컬럼 테이블이 꽤 높았다

  • JSON -> 246.75MB
  • 10개 컬럼 -> 146.67MB

실행속도

PK로 검색하는건 의미가 없어서 임의의 JSON 키 값을 검색했는데 차이는 거의 없었다

1
2
3
4
5
-- 0.00052sec
explain select * from test.none_json_table where test1 = '랜덤문자';

-- 0.00053sec
explain select * from test.json_table where json_extract(value, '$."test1"') = '랜덤문자';

타입스크립트에서 써보기

1
npm i mysql2 -S

mysql2를 설치하여 사용, 여담으로 npm mysql은 8.@버전 연결 지원이 안 됨 😭

인터페이스만 잘 정의해주면 특별한 건 없었다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { createConnection, RowDataPacket, FieldPacket, Connection } from "mysql2/promise";

interface Value {
test1: string;
test2: string;
test3: string;
test4: string;
test5: string;
test6: string;
test7: string;
test8: string;
test9: string;
test10: string;
}

interface JSONTable extends RowDataPacket {
id: number;
value: Value;
}

async function main() {
const connection = await createConnection({
host: "localhost",
user: "root",
database: "test",
});
try {
const [rows, fields]: [JSONTable[], FieldPacket[]] = await connection.query(
"SELECT id, value FROM test.json_table ORDER BY RAND() LIMIT ?",
[5]
);
for (let i = 0; i < rows.length; i++) {
console.log("id", rows[i].id, "test1", rows[i].value.test1);
}
console.log("table: ", fields[0].table);
} catch (err) {
throw err;
}

try {
const [rows, fields]: [JSONTable[], FieldPacket[]] = await connection.query(
`SELECT * from test.json_table where json_extract(value, '$."test2"') = ?`,
["09aeeecb68"]
);
console.log('rows', rows[0]);
} catch (err) {
throw err;
}

try {
await connection.query(
"UPDATE test.json_table SET value = JSON_SET(value, '$.test1', 'hihi!') WHERE id = ?",
[1]
);
} catch (err) {
throw err;
}
}

main();

참조