TiDB不支持JSON字段默认值
Posted | stdout
The BLOB, TEXT, and JSON columns cannot be assigned a default value.
虽然 MySQL 5.7 也是这么说的:
A JSON column cannot have a non-NULL default value.
Prior to MySQL 8.0.13, a JSON column cannot have a non-NULL default value.
The default value specified in a DEFAULT clause can be a literal constant or an expression. With one exception, enclose expression default values within parentheses to distinguish them from literal constant default values. Examples:
虽然语法很丑但是很实用啊。
所以这种语句
ALTER TABLE mytable MODIFY COLUMN my_json JSON DEFAULT (json_object());
在 TiDB 里就没法支持。这也带来一个问题,就是要 upsert 这个 字段的时候,写起来就很拧巴,以 peewee
这个ORM为例:
MyTable.update({
'my_json' = fn.json_set(
fn.COALESCE(MyTable.my_json, Cast('{}', 'JSON')),
'%.some_key', 'some_value',
)})
必须用 COALESCE 预防默认值为 NULL
的情况。太麻烦了。
btw 玩MySQL/TiDB的 JSON 有个坑的,那就是 json 的 null
是有值的,和 sql 的 NULL
是不同的。
也就是说
select json_extract('{}', '$.hey') IS NULL;
select json_extract('{"hey": null}', '$.hey') = Cast('null' as JSON);
要注意。
btw2 MySQL的JSON数据抽取 ->>
是返回真正的值,等价于TiDB里的 json_unquote(json_extract(t.json_field, '$.key1.key2'))
Comments