如何设计小型仿Facebook数据库ER图 解决非注册家庭成员关联问题
小型仿Facebook平台数据库优化设计方案
核心设计思路
将「自然人主体」与「平台注册账号」两个概念完全解耦,所有关联资料、地址、关系的表都绑定统一的自然人ID,仅注册账号单独存储登录相关信息,从根源上解决冗余和后续更新成本高的问题。
具体表结构设计
PersonTB:所有自然人(含注册用户、非注册家庭成员)的全局唯一主体表
核心字段:person_idBIGINT 主键,全局唯一标识is_registeredTINYINT(1) 标记是否为平台注册用户,默认0(非注册)create_time、update_time通用时间字段UserTB:仅存储注册用户的登录专属信息
核心字段:user_idBIGINT 主键person_idBIGINT 外键关联PersonTB.person_id,加唯一约束username、password_hash、register_time、last_login_time等登录相关字段ProfileTB:存储所有自然人的个人资料,复用同一套结构
核心字段:profile_idBIGINT 主键person_idBIGINT 外键关联PersonTB.person_idname、gender、birthday、avatar_url等通用资料字段AddressTB:存储所有自然人的地址信息,复用同一套结构
核心字段:address_idBIGINT 主键person_idBIGINT 外键关联PersonTB.person_idcountry、province、city、detail_address、zip_code等地址字段FamilyTB:存储家庭成员关联关系
核心字段:relation_idBIGINT 主键from_person_idBIGINT 外键关联PersonTB.person_id,代表发起添加的用户to_person_idBIGINT 外键关联PersonTB.person_id,代表被添加的家庭成员relation_typeVARCHAR(32) 存储关系类型,如brother、dad、sister等
可加联合唯一约束(from_person_id, to_person_id)避免重复添加同一关系
方案优势
- 彻底消除表结构冗余:不需要为非注册家庭成员单独创建Profile、Address类的表,所有人员的通用信息都复用同一套表结构
- 非注册用户转注册成本为0:当非注册家庭成员需要注册平台账号时,仅需要在
UserTB中插入一条关联对应person_id的记录,同步修改PersonTB中is_registered标记为1即可,无论后续有多少张关联人员信息的表,都不需要做任何字段更新,完全避免了批量改表的运维风险 - 关系查询逻辑更简洁:查询任意用户的家庭成员列表时,直接通过
FamilyTB关联PersonTB、ProfileTB、AddressTB即可拿到完整信息,不需要额外判断成员是否为注册用户,也不需要跨多套表联合查询
内容的提问来源于stack exchange,提问作者Xin
相关产品推荐
相关产品推荐

