本人在开发一个给单词添加同族词汇以及近义词反义词的功能:
然后由于数据表设计的不当,导致出现这样的问题:
上图中同义词反义词,都是给单词sophisticated绑定的。
结果查询naive,它的近义词反义词也和上图一模一样。
这就是因为本人在设计数据表时忽略了一个问题:
很多单词一词多义,每个意思会有相对应的近义词和反义词,但第一个意思对应的近义词,其相关的近义词可能跟第二个意思的近义词完全没有关联。
例如sophisticated单词有复杂的、老练的这两层含义,当做老练的意思,其反义词可以是naive,意思为缺乏经验的,但naive单词的反义词,根本就没有“复杂”这一层含义。
CREATE TABLE `word_en_synonym` ( `id` INT NOT NULL AUTO_INCREMENT, `synonym_group_id` INT NOT NULL COMMENT '关系组id', `word_id` INT NOT NULL COMMENT '单词id', `is_synonym` TINYINT NOT NULL DEFAULT '1' COMMENT '1-同义词 0-反义词', `status` TINYINT NOT NULL DEFAULT '1' COMMENT '状态 1 正常 0 删除', `create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE INDEX `uk_lib_word_en_synonym_0_synonym_group_id_2` (`synonym_group_id`, `word_id`) ) COMMENT='单词同义词表' COLLATE='utf8mb4_general_ci' ENGINE=InnoDB AUTO_INCREMENT=0 ;
每个单词都必须独立维护其同义词和反义词,于是数据库表调整如下:
CREATE TABLE `word_en_synonym` (
`id` INT NOT NULL AUTO_INCREMENT,
`word_id` INT NOT NULL COMMENT '单词id',
`relate_word_id` INT NOT NULL COMMENT '关联单词id',
`is_synonym` TINYINT NOT NULL DEFAULT 1 COMMENT '1-同义词 0-反义词',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态 1 正常 0 删除',
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE INDEX uk_lib_word_en_synonym_0_word_id_2(word_id, relate_word_id)
)
COMMENT='单词同义词表'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=0
;
不过业务上仍然需要注意一点:
单词A的近义词有单词B,那么单词B的近义词就一定有A
所以实现业务的时候,要把反向绑定的数据也同时添加了,这样就不用给B单词添加近义词时重复操作一遍。
本文为翟码农个人博客下技术主题里mysql分类的原创文章,通过实践说明数据库表设计的重要性,转载还请注明出处:http://www.zhai14.com/blog/error-design-of-the-table-on-synonym-and-antonym-of-an-word.html
之所以记录下来,是因为数据接口写好了,我才发现这一问题。
这就是数据库设计的重要性,需要在开发功能之前,就提前将功能的实现细节思考清楚。
没有想清楚的后果,就是: