从实体关系图中的属性中提取实体

t.O*_*t.O 6 database-design

我正在开发一个数据库模型,我需要在其中捕获有关停车场内停车位租赁合同的信息。因此,我定义了一个名为 PARKING CONTRACT 的实体。

要求 (r.) 说,每份停车合同都应为恰好 1 辆车签署,而这辆车又恰好由 1 位车主拥有。

要完全定义停车合同,r。比如说,我需要记录车主和他的车的各种信息。每位车主:全名、地址、护照号等。 每辆车:技术护照号、注册号、品牌等。

根据 r。(这些细节就不赘述了,这里我是根据需要定义的属性来判断的!),车主可以通过护照号码唯一识别;汽车可以通过注册号来识别。

我首先认为将 CAR OWNER 和 CAR 建模为单独的实体会很好,然后想到了这个:

.-----------------.                      .-------.                 .------------.
| PARKING CONTRACT|     Is signed for    |  CAR  |   Is owned by   |  CAR OWNER |
|                 |O_____________________|       |O________________|            |
'-----------------' 1                   1'-------' 1..*           1'------------'
Run Code Online (Sandbox Code Playgroud)

但后来我意识到,通过这种设计,我们可以随心所欲地存放尽可能多的车主,而他们中的任何人都没有任何车辆的停车合同。我认为这不好 - 为什么数据库应该能够存储有关从未有任何停车合同的人的信息。

我在这里看到的另一个选项是不将 CAR 和 CAR OWNER 提取到单独的实体中,而是将有关它们的所有信息保存在 PARKING CONTRACT 表中,对于每个 PARKING CONTRACT。

但是这个选项似乎也不太好,因为 PARKING CONTRACT 表,恕我直言,变成了一个试图处理太多不同信息的嵌合体。

此外,我已阅读本手册:https : //support.ca.com/cadocs/0/CA%20ERwin%20Data%20Modeler%20r8-ENU/Bookshelf_Files/PDF/ERwin_Methods.pdf

在第 38 页上,它告诉您,当您最终得到诸如停车合同签名者护照号码之类的属性名称时,则表明存在设计问题。

问题是:处理这种情况的最常见方法是什么?这两种方法中的任何一种是首选吗?或者,也许,有一种完全不同的第三种方法?为什么这种方法是首选?谢谢!

Joe*_*own 6

除非您有充分的理由不这样做,否则您应该规范化您的数据库架构。当您规范化您的数据库模式时,您可以避免在重复数据时可能出现的数据一致性问题。

谷歌术语:插入异常更新异常删除异常。您将看到许多非规范化数据库可能导致的各种问题的示例。

关于CONTRACT与以下分开的建模CAR:我发现从数据模型开始的最佳位置之一是将您的系统关心的每个有形(或重要的无形)事物视为自己的表。

严峻的现实是业务规则会改变,但您的企业关心的事情不会改变——至少不会以几乎相同的速度改变。因此,您希望您的数据能够反映您的业务所关心事物的现实情况。

人不是合同。当然,今天你的老板说每辆车每人一份合同。当你的老板购买(或建造)一个新的停车场并且那辆车同时签订了合同时会发生什么?当一个人出售有合同的汽车时会发生什么?合同是人签的,不是车签的?合同是与汽车有关还是与车主有关?当你的老板告诉你他想开始跟踪未来日期的合同以便汽车可以同时拥有当前合同和明年的合同时,会发生什么?

你不具备正常化。你可以试着用一张大桌子来处理所有事情。您可以将所有内容写在电子表格或纸上。但是,如果您想构建一个对未来灵活的系统,请从规范化开始。


关于你的表的 ID:永远不要使用任何外部的东西作为 ID,除非你完全肯定它永远不会改变。车辆 VIN 可以作为标识符。没有什么会导致 VIN 改变,并且它保证是唯一的。护照号码是一个糟糕的身份证,因为(a)它肯定会随着时间的推移而改变,(b)你不能确定它是唯一的。当主键更改时,会引起各种头痛。这就是为什么很多人为他们的表分配内部的、无意义的代理键


编辑:其他需要考虑的事情:

您应该考虑的另一件事是,您不应该尝试为对您的系统不重要的事物建模(并为其维护数据)。

That is just making work for yourself now and down the road. Your system will be more complicated to build, maintain, upgrade and use.

Consider the following ERD:

ERD

The relationship between CAR and OWNER is not important to your system! At first this seems a little bit counterintuitive, but think about this: Does your boss care who actually owns a car? No! What they care about is who (PERSON) signed a contract to pay to have which CAR parked in his garage. Therefore the relationships that are actually important are between CONTRACT and CAR, and CONTRACT and OWNER. The relationship between CAR and OWNER is not directly significant to your system, unless you have a business rule somewhere that says something about how contracts stay with cars, not owners when people sell their cars. That is probably dicey from a legal perspective.


Wri*_*ree 1

根据您的模型,看起来一个车主不太可能拥有超过一辆车(我猜最多有两辆车,如果车主是私人的话),而且我猜停车合同不能存在超过一辆车(这些是我所做的一些假设,如果我错了,请纠正我)..在这种情况下,只需一张包含所有列的表就可以了..

我想提的一些规则是:如果您看到一个 car_owner 或一辆车可以在其他地方重复使用的用例(可能在持续时间表中以确定停车时间),那么拆分表以标准化是有意义的,如果在所有情况下,整个数据模型中只有一个 car\car_owner 实例作为唯一元组,则使用单个表就可以了。

为了优化存储,您可以为经常重复的值定义子表(例如 Car_Make)。然而,这应该适用于小数据模式。

  1. 由于一辆车不能有多个停车合同,因此可以将 CAR 作为停车合同表的一部分

    创建表 PARKINGCONT_TBL(contract_id,,car_regnumber,,owner_id [FOR_KEY TO OWNER_TBL]

    创建表 OWNER_TBL(owner_id,)

  2. 不应出现在没有合同的情况下添加客户的问题,因为无论插入什么(应用程序)都应该创建合同(而不是客户),因此仅在创建合同时才添加所有者(无法强制执行此操作,因为所有者和合约之间不存在依赖关系,创建一个将导致循环依赖)