无模式数据表设计

最近做项目,需要完成一种需求:用户可以为某种任意的model添加任何多个tag。一般来说常规的范式化设计在这种情况下使用一个字段一条记录来存储所有的tag,该记录中使用某种分隔符(如英文逗号,“|”等符号)来分隔各个tag,然后通过程序逻辑来解析tag。
这种做法最容易被想到,但也最容易出问题。
有几大问题是不可避免的:
1. 使用逻辑处理数据不能使用数据库的完整性依赖;
2. 不能保证用户输入永远合法;
3. 由于用户输入长度不定,因此可保存的tag数目不定。
因此,需要一种更加好的解决方案,该方案要对多种model具有兼容性,并且可以扩展任意多种类的tag。

设计一张table tags:


tags = {
:id => integer,
:tag_name => string,
:tag_type => integer
}

该表用于保存各种tag的具体类型和名字,比如:
tag_name => "北京", tag_type => 1
tag_name => "移动互联网", tag_type => 2
(在配置文件中写入locaiton = 1, market = 2)

然后设计一张关联table entity_tags:

entity_tags = {
:id => integer,
:entity_type => string,
:entity_id => integer,
:tag_id => integer
}
set foreign_key :tag_id references tags.id

这张表中,entity_type为使用tags的实体的类名,比如User;entity_id为实体的id;tag_id为外键,用于关联tags表。

如此,每当某个实体添加一个tag,首先去tags表中找相关类型的tag是否存在,如果不存在,则新增一个tag,然后去entity_tags表中生成一条关联信息,比方说:
tags(:id => 1, :tag_name => "北京", :tag_type => 1)
entity_tags(:id => 1, :entity_type => 'User', :entity_id => 1, :tag_id => 1)
entity_tags(:id => 2, :entity_type => 'Company', :entity_id => 1, :tag_id => 1)
如此一来,User表中id为1的记录和Company表中id为1的记录都拥有了一个location tag“北京”(假设:tag_type => 1 表示location)
并且,无论怎样添加,tags表中都将为每种tag生成一条唯一的记录,所有的实体和tag关联都保存在entity_tags中,非常易于增删改查。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值