V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wangxiaoer
V2EX  ›  问与答

类似商品的数据库结构设计

  •  
  •   wangxiaoer · 2018-01-04 12:10:16 +08:00 · 1740 次点击
    这是一个创建于 2550 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个档案管理系统,涉及到人员管理,人员除了保存姓名、年龄等基础信息外,还会根据每个人的分类管理不同的属性。比如:

    “党员” : “入党时间、党支部”等属性

    “医生” : “参加工作时间,医院、科室”等

    “教师” : “参加工作时间,学校、科目”等

    (!参考了这个帖子)[https://www.v2ex.com/t/254792]

    然后自己的想法是 4 张表:

    1 人员基本信息:涵盖基础字段、所属类别

    2 类别:类别名称、父类

    3 分类-属性表:分类 id,属性 id

    4 属性值表:人员 id,属性 id,属性值

    这样设计的话,表 2,3 需要在系统运行前就创建好,也就是说需求如果有了变动,需要调整结构,表 1 和 4 的内容就是后续随着系统运行不断增加了。

    这个的缺陷:

    1 表 4 的属性值类型无法区分了,比如 “参加工作时间”属于 date 类型,“科目”属于字符串,但是因为存储在同一列,所以只能统一用字符串了。

    2 表 4 的数据随着系统运行会比表 1 数据增加的快几倍。


    感觉有点像 wordpress 的那种设计,大家还有好的办法没有?

    11 条回复    2018-01-04 21:32:48 +08:00
    wangxiaoer
        1
    wangxiaoer  
    OP
       2018-01-04 13:35:03 +08:00
    大家现在都不关注这种纯技术问题了还是这个问题太低级了?
    Moorj
        2
    Moorj  
       2018-01-04 14:33:05 +08:00
    别的编程问题不会答,数据库我会一丢丢。。。但我路子比较野,我是自学的数据库,抛砖引玉吧

    我会建立如下 表:字段

    人员信息:姓名、年龄.....(纯粹的个人信息)、人员 id
    党员:人员 id、入党时间、党支部
    医生:人员 id、参加工作时间,医院、科室
    教师:人员 id、参加工作时间,学校、科目


    通过人员 id,把人员信息和他的各个属性链接起来

    这样可以 1 个人可以同时具有多个身份,不会冲突,也可以互相检索,每个表增加的速度也均衡

    如果后期增加角色身份,增加表单即可
    Moorj
        3
    Moorj  
       2018-01-04 14:36:41 +08:00
    另外你这个跟商品是非常不一样的,同一个商品不可能同时拥有冲突的几种特性,比如红色、蓝色不能同时存在,而人可以既是党员、又是医生、也是教师,所以要分别建表
    Moorj
        4
    Moorj  
       2018-01-04 14:50:36 +08:00
    精简方案 2

    人员信息:姓名、年龄.....(纯粹的个人信息)、人员 id
    履历:人员 id、身份 id、时间、地点 1、地点 2
    身份:身份、身份 id


    后期新增角色,增加身份表中的记录即可

    履历中具有完整的身份记录,这个表会增加的最多
    Moorj
        5
    Moorj  
       2018-01-04 14:54:59 +08:00
    仔细看了下,方案 2 跟楼主的方案是一样的,如果没有后期的数据量优化问题的话,基本这就是最优解了
    wangxiaoer
        6
    wangxiaoer  
    OP
       2018-01-04 16:15:07 +08:00
    @Moorj #2 你说的属于 classic table inheritance,也是我之前考虑的 https://stackoverflow.com/questions/695752/how-to-design-a-product-table-for-many-kinds-of-product-where-each-product-has-m/695860#695860

    但是感觉这种建表工作量大,而且在检索的时候,需要 join 多个表,然后将查询结果映射成对象有点麻烦。
    l00t
        7
    l00t  
       2018-01-04 17:05:51 +08:00
    @wangxiaoer 常见的设计形式,你给的 stackoverflow 的链接中已经列得很全了。纵表形式的优点无非是增减属性不用改表结构,缺点则是数据量大。横表则相反。join 和映射成对象有什么麻烦的?不做 join 你可以多次查询啊。第一次查基本信息,并取出一个类别字串。然后根据类别字串里标记的类别,去取对应的几个表的记录,并不需要在数据库里 join。
    wangxiaoer
        8
    wangxiaoer  
    OP
       2018-01-04 19:25:30 +08:00 via Android
    @l00t 如果几十上百个类别,初期建表用自动化的方式吗?手工的话工作量太大了
    Moorj
        9
    Moorj  
       2018-01-04 19:43:08 +08:00
    @wangxiaoer 写个脚本自动填充即可
    l00t
        10
    l00t  
       2018-01-04 20:34:38 +08:00
    @wangxiaoer 建表工作量?你指什么工作量…… 写建表语句的工作?这个不是很容易写个程序翻译成 SQL 语句的嘛…… 现写一个都行, 你在数据库里直接可视化建表也行,我不明白这有什么工作量的…… 不论怎样,哪怕几十上百个类别,你开工前对于每个类别要有哪些属性总得有个谱吧,基本的设计总得有吧。直接开个数据库做设计,做完导出成建表语句,并没有什么额外的工作量啊。
    batnss
        11
    batnss  
       2018-01-04 21:32:48 +08:00
    mysql5.7 json 类型解救你
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2376 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:16 · PVG 10:16 · LAX 18:16 · JFK 21:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.