数据库关系模式建模

A市要建立房屋监测数据库,A市有很多个房子,房子的属性有地址,建成年份,每个房子由多个梁柱构件组成,梁柱的属性有长,宽,高,混凝土强度,钢筋型号和配筋率,每个房子有多个监测报告,报告的属性有监测年份,监测单位,在每份监测报告中,对应于这个房子的每个部位有一个监测结果,结果包括:开裂情况,钢筋腐蚀情况。如何进行建模?

抽象出来也就是关系A有两个外键B和C,AB,AC都是n对1的,而B和C有一个公共外键D,BD和CD都是n对1.

这样在对A进行insert/update的时候还需要判断选择的B和C是否对应于同一个D,如何改变关系模式才能避免做这种判断?

阅读 4.6k
2 个回答

如果是使用关系型数据库设计的话,可以列出以下四个实体:
1.A-房子{id, address, year}
2.B-梁柱{id, house_id, length, width, height, streghth, type, ratio}
3.C-报告{id, house_id, year, department}
4.D-监测结果{id, report_id, beam_id, crack, corrosion}
此时,AB,C 而言是1 对 nBDCD 都是1 对 n。进行 insert/update 操作无需进行判断。
但对 D 进行增改操作时,要进行 validation。我认为可以改为:
1.A-房子{id, address, year}
2.B-梁柱{id, house_id, monitor_id, length, width, height, streghth, type, ratio, crack, corrosion}
3.C-报告{id, house_id, year, department}
4.D-监测结果{id, report_id}
但是此时,梁柱和监测结果的对应关系有问题。所以我暂时也想不出来能免除判断的好的关系结构了。关注这个问题。
但是,如果可以使用 Nosql 的话,这个问题就好办多了。以 mongo 为例,可以直接设计一个名为 housecollection:

{
    "_id" : ""
    "address" : "",
    "year" : ""
    "beams" :[array]
        {
            "_id" : ""
            "length" : ""
            "width" : "",
            "height" : ""
            "streghth" : ""
            "type" : ""
            "ratio" : ""
            "results" : [array]
                {
                    "result_id": ""
                }
        }
    "reports" :[array]
        {
            "_id" : "",
            "year" : "",
            "department" : "",
            "results" : [array]
                {
                    "result_id": ""
                }
        }
}

再设计一个名为 reportcollection:

{
    "_id" : "",
    "crack" : "",
    "corrosion" : ""
}

此时插入监测报告的话,应该就不需要 validation 了。

house (房子)

  • house_id
  • ...

component (构件)

  • component_id
  • house_id
  • ...

component.house_id 外键关联至 house.house_id

report (房屋监测报告)

  • report_id
  • house_id
  • ...

report.house_id 外键关联至 house.house_id

report_component (构件监测报告)

  • report_component_id
  • report_id
  • component_id
  • ...

report_component.report_id 外键关联至 report.report_id
report_component.component_id 外键关联至 component.component_id

house <-> component: 一对多
house <-> report: 一对多
report <-> report_component: 一对多

所有外键都不允许级联删除

只有插入report_component的时候需要检查component_id是否合法,这个逻辑放到程序里面去检查即可
其它的数据有效性交给外键关联来负责即可

推荐问题
宣传栏