一个档案管理系统,涉及到人员管理,人员除了保存姓名、年龄等基础信息外,还会根据每个人的分类管理不同的属性。比如:
“党员” : “入党时间、党支部”等属性
“医生” : “参加工作时间,医院、科室”等
“教师” : “参加工作时间,学校、科目”等
(!参考了这个帖子)[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 的那种设计,大家还有好的办法没有?
1
wangxiaoer OP 大家现在都不关注这种纯技术问题了还是这个问题太低级了?
|
2
Moorj 2018-01-04 14:33:05 +08:00
别的编程问题不会答,数据库我会一丢丢。。。但我路子比较野,我是自学的数据库,抛砖引玉吧
我会建立如下 表:字段 人员信息:姓名、年龄.....(纯粹的个人信息)、人员 id 党员:人员 id、入党时间、党支部 医生:人员 id、参加工作时间,医院、科室 教师:人员 id、参加工作时间,学校、科目 通过人员 id,把人员信息和他的各个属性链接起来 这样可以 1 个人可以同时具有多个身份,不会冲突,也可以互相检索,每个表增加的速度也均衡 如果后期增加角色身份,增加表单即可 |
3
Moorj 2018-01-04 14:36:41 +08:00
另外你这个跟商品是非常不一样的,同一个商品不可能同时拥有冲突的几种特性,比如红色、蓝色不能同时存在,而人可以既是党员、又是医生、也是教师,所以要分别建表
|
4
Moorj 2018-01-04 14:50:36 +08:00
精简方案 2
人员信息:姓名、年龄.....(纯粹的个人信息)、人员 id 履历:人员 id、身份 id、时间、地点 1、地点 2 身份:身份、身份 id 后期新增角色,增加身份表中的记录即可 履历中具有完整的身份记录,这个表会增加的最多 |
5
Moorj 2018-01-04 14:54:59 +08:00
仔细看了下,方案 2 跟楼主的方案是一样的,如果没有后期的数据量优化问题的话,基本这就是最优解了
|
6
wangxiaoer OP @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 多个表,然后将查询结果映射成对象有点麻烦。 |
7
l00t 2018-01-04 17:05:51 +08:00
@wangxiaoer 常见的设计形式,你给的 stackoverflow 的链接中已经列得很全了。纵表形式的优点无非是增减属性不用改表结构,缺点则是数据量大。横表则相反。join 和映射成对象有什么麻烦的?不做 join 你可以多次查询啊。第一次查基本信息,并取出一个类别字串。然后根据类别字串里标记的类别,去取对应的几个表的记录,并不需要在数据库里 join。
|
8
wangxiaoer OP @l00t 如果几十上百个类别,初期建表用自动化的方式吗?手工的话工作量太大了
|
9
Moorj 2018-01-04 19:43:08 +08:00
@wangxiaoer 写个脚本自动填充即可
|
10
l00t 2018-01-04 20:34:38 +08:00
@wangxiaoer 建表工作量?你指什么工作量…… 写建表语句的工作?这个不是很容易写个程序翻译成 SQL 语句的嘛…… 现写一个都行, 你在数据库里直接可视化建表也行,我不明白这有什么工作量的…… 不论怎样,哪怕几十上百个类别,你开工前对于每个类别要有哪些属性总得有个谱吧,基本的设计总得有吧。直接开个数据库做设计,做完导出成建表语句,并没有什么额外的工作量啊。
|
11
batnss 2018-01-04 21:32:48 +08:00
mysql5.7 json 类型解救你
|