这篇本来应该是给xiang和kaka的回复,不过回复的小框框实在是太小了,呵呵,就发到这里,当作《扩展表设计》的续篇吧。
假设一个M系统,系统中有许多模块都需要用到扩展数据。首先,我们把每个需要使用扩展数据模块的代号存在扩展表的主表中:
OID INF_CODE INF_URL INF_STATUS INF_DESC
1111... CUSTOMERDATA ... USE CUSTOMER DATA //用于客户数据
1122... CPUDATA ... USE CPU DATA //用于CPU数据
OID是当前模块的扩展表的GUID,INF_CODE相当于一个标识符。INF_STATUS是表示被使用/不被使用。
接下来,对每一个模块,我们要存下它所需要存数据的栏位:
OID FLD_INFOID FLD_CODE FLD_NAME FLD_SEQN FLD_DATATYPE FLD_STATUS FLD_DESC
2211... 1111... WIFE_NAME 妻子姓名 0 string USE 客户妻子姓名
2212... 1111... CID_SEX 孩子性别 1 dropdown USE 客户孩子性别
2221... 1122... OLD_FRE 打磨前频率 0 decimal USE CPU打磨前频率
2222... 1122... REM_BRA 打磨批次 1 string USE 打磨批次
这里OID是当前栏位的GUID。FLD_INFOID是关联到前面主表的OID的外键,表示当前这一列属于哪一个模块。FLD_DATATYPE是限定当前列所填值的类型。FLD_SEQN是这一列的显示顺序。
对于dropdown类型的值,把他们可选的下拉值存在选择值表中。这里存的是关于孩子性别的选择项:)
OID OPT_FLDOID OPT_VALUE OPT_KEY OPT_DEFAULT OPT_STATUS OPT_DESC
3321... 2212... 男 MALE TRUE USE 性别:男
3322... 2212... 女 FEMALE FALSE USE 性别:女
OID是选择值的GUID。OPT_FLDOID是关联到上面栏位表OID的外键,表示当前的选项是哪一列的。
前面的三张表就完成了各个模块的扩展表的格式(即列信息)定义:列、数据类型、顺序、可选值。接下来,就需要存取扩展表的数据(也就是行信息)了。
不论数据是多么的扩展,任何一条扩展数据都要对应到具体的实例上。比如说,客户模块的扩展数据,就需要对应到是客户INTEL的还是客户AMD的,毕竟INTEL和AMD的妻子和孩子可不能共用呀。因此,在扩展数据的明细表之前,我们首先需要定义扩展数据和模块中的具体实例的连接关系。这就是扩展信息表的作用。
假设客户数据表中INTEL的OID是0001...,AMD的OID是0002...。CPU数据表中XEON的OID是0003...,HAMMER的OID是0004...。
OID REC_INFOOID REC_OBJOID REC_STATUS REC_DESC
4411... 1111... 0001... USE 客户:INTEL
4412... 1111... 0002... USE 客户:AMD
4421... 1122... 0003... USE CPU:XEON
4422... 1122... 0004... USE CPU:HAMMER
OID是一条扩展信息的GUID,REC_INFOOID是关联到前面第一个主表的某一个模块的外键。独特的REC_OBJOID是对应到具体模块的数据表中具体实例的OID。如果当前这条扩展信息是客户模块的,则此处关联客户数据表中的OID。如果当前这条扩展信息是CPU模块的,则此处关联CPU数据表的OID。这里虽然不是外键,但是表示的却是外键的含义。
上面的扩展信息表定义了扩展表每一行信息的归属。最后,我们需要真正的填入扩展信息的明细——也就是行内每一列的数据了。这就是最后一张表,也是数据量最大的一张表:扩展信息明细表。
OID RCD_RECORDOID RCD_FLDOID RCD_RECODE
5511... 4411... 2211... AUDERY //INTEL的妻子姓名
5512... 4411... 2212... 3322... //INTEL的孩子性别:女,从选择值表取出
5513... 4412... 2211... HERBEN //AMD的妻子姓名
5514... 4412... 2212... 3321... //AMD的孩子性别:男,从选择值表取出
5521... 4421... 2221... 800 //XEON打磨前频率:800Hz
5522... 4421... 2222... 04-09-08 //XEON打磨批次:04-09-08
5523... 4422... 2221... 2400 //HAMMER打磨前频率:2400Hz
5524... 4422... 2222... 04-09-14 //HAMMER打磨批次:04-09-14
OID是具体明细的GUID。RCD_RECORDOID是对应上一个扩展信息表的OID的外键,表示属于哪一个具体实例。RCD_FLDOID是关联到扩展栏位的OID,表示当前的数据是哪一列下的数据。RCD_RECODE存储的就是具体的明细值了。注意到两个孩子性别,数据都是存的选择值表的对应选项的OID。由于他们的栏位信息已经表明其类型为dropdown,我们就可以从选择值表中取出其应有的数据。
后两张表的信息就是扩展表的行信息了。如果取出来看,我们可以得到以下的结果:
客户数据的扩展表信息:
客户INTEL的扩展表信息:
妻子姓名 孩子性别
AUDERY 女
客户AMD的扩展表信息:
妻子姓名 孩子性别
HERBEN 男
CPU数据模块的扩展表信息:
XEON的扩展表信息:
打磨前频率 打磨批次
800 04-09-08
HAMMER的扩展表信息:
打磨前频率 打磨批次
2400 04-09-14
可惜看到,上面的行和列信息都是从扩展表五张表中取出的。这样,我们就实现了“用表来存表”的功能。同时,这些数据也很容易添加到具体实例的显示内容里(比如可以将INTEL的扩展信息和INTEL的原始信息一起展现),对应付需求变更和数据库结构改变也很有效果。
注:以上数据纯属虚构,只是为了说明有些时候,有些数据不方便直接添加到原来的主表中(比如客户妻子和孩子的信息就不方便直接加入客户数据表中,CPU打磨的信息更不方便直接显示出来),但有些也确实有用(客户的妻子孩子的信息对进行CRM也是有帮助的。)这也算是扩展表的一些特殊用处吧。
注:GUID应该是36位的唯一标识符,此处受长度和视觉效果所限,进行了简化处理
转载于:https://www.cnblogs.com/Gigabyte/archive/2004/09/16/43899.html