Postgres中如何让各类emoji按1个字符统计以实现单列单emoji约束
Postgres 统计emoji字形长度并设置单列单emoji约束方案
默认length()函数统计的是Unicode码点数量,而旗帜类emoji由2个区域指示符码点组成,带ZWJ(零宽连接符)的复合emoji由多个码点拼接而成,所以统计出来的长度远大于1,可通过以下方案实现所有emoji统一统计为长度1:
方案1:Postgres 13及以上版本(推荐)
Postgres 13 新增了原生grapheme_length()函数,直接统计Unicode字形簇数量,完全匹配需求:
测试代码:
SELECT grapheme_length('😁') AS len1, -- 返回1 grapheme_length('🇧🇷') AS len2, -- 返回1 grapheme_length('👩❤️💋👩') AS len3; -- 返回1
添加列约束的示例(假设表名为user_info,存储emoji的列名为emoji_avatar):
ALTER TABLE user_info ADD CONSTRAINT chk_single_emoji CHECK (grapheme_length(emoji_avatar) = 1);
方案2:Postgres 12及更低版本兼容方案
低版本可以借助Postgres正则的\X匹配符(专门匹配单个Unicode字形簇),配合regexp_match_all计数实现同等效果:
测试代码:
SELECT array_length(regexp_match_all('😁', '\X'), 1) AS len1, -- 返回1 array_length(regexp_match_all('🇧🇷', '\X'), 1) AS len2, -- 返回1 array_length(regexp_match_all('👩❤️💋👩', '\X'), 1) AS len3; -- 返回1
对应列约束写法:
ALTER TABLE user_info ADD CONSTRAINT chk_single_emoji CHECK (array_length(regexp_match_all(emoji_avatar, '\X'), 1) = 1);
可选补充校验
如果需要额外确保存储的内容确实是emoji,可以在约束中追加正则校验:
-- 以grapheme_length版本为例,低版本替换长度校验逻辑即可 ALTER TABLE user_info ADD CONSTRAINT chk_single_emoji CHECK ( grapheme_length(emoji_avatar) = 1 AND emoji_avatar ~ '\p{Emoji}' );
内容的提问来源于stack exchange,提问作者pir
相关产品推荐
相关产品推荐

