数据库设计。请问如何处理?

时间:2015-04-09 14:24:16

标签: mysql database-design

我正在设计一个管理车队的数据库(MySQL)。

公司在整个城市有许多车库,每个车库都有车辆维修(运营)。操作可以是3种类型的服务中的任何一种。

Table Vehicle,Table Garagae,Table Operation,Table Operation Type 1,Table Operation Type 2,Table Operation type 3.

每个操作都有车辆ID,车库ID,但是如何根据用户选择的服务类型将其链接到其他表(服务表)?

我还想添加一个结算表,但我对如何设计这些表之间的关系感到很遗憾。

3 个答案:

答案 0 :(得分:0)

如果我完全理解它,我会建议这样的事情(首先你不应该有三个操作表):

Vehicles Table
- id
- garage_id

Garages Table
- id

Operations/Services Table
- id
- vehicle_id
- garage_id
- type

Customer Table
- id
- service_id

billings Table
- id
- customer_id

答案 1 :(得分:0)

您需要六张桌子:

vechicle: id, ...
garage: id, ...

operation: id, vechicle_id, garage_id, operation_type (which can be 
one of the tree options/operations available, with the possibility to be extended)

customer: id, ...

billing: id, customer_id, total_amount
billingoperation: id, billing_id, operation_id, item_amount

你绝对不应该为操作创建三个表。将来如果您想引入一个涉及在数据库中创建新表的新操作。

答案 2 :(得分:0)

为了记录,我不同意所有说你不应该拥有多个操作表的人。只要做得好,我认为这完全没问题。事实上,我现在正在使用我的某个产品。

如果我理解,在你的问题的核心,你会问如何进行表继承,因为Op Type 1和Op Type 2(等)是一个操作。简短的回答是你无法做到。更长的答案是,你不能......至少没有一些辅助逻辑。

我假设你有某种程序可以从数据库中提取数据,而不是你手工编写sql命令。在此假设下工作,让我们将其用作数据库的子集:

Garage
------
GarageId | GarageLocation | etc. 
---------|----------------|------
1        | 123 Main St.   | XX   

Operation
---------
OperationId | GarageId | TimeStarted | TimeEnded | OperationTypeDescId | OperationTypeId 
------------|----------|-------------|-----------|---------------------|----------------
2           | 1        | noon        | NULL      | 2                   | 2


OperationTypeDesc
-------------
OperationTypeDescId | Name  | Description
--------------------|-------|-------------------------
1                   | OpFoo | Do things with the stuff
2                   | OpBar | Do stuff with the things


OpFoo
-----
OpID | Thing1 | Thing2
-----|--------|-------
1    | 123    | abc

OpBar
-----
OpID | Stuff1 | Stuff2
-----|--------|-------
1    | 456    | def
2    | 789    | ghi

使用此设置,您可以获得以下信息:

  • 车库有它的信息,简单明了
  • 操作具有唯一ID(OperationId),执行它的车库,引用操作描述的ID以及OperationType ID(稍后会详细介绍)。
  • 预先填充的操作类型表。每种类型都有一个唯一的ID(OperationTypeDescId),操作的名称,以及该操作的可读描述。
  • OperationTypeDesc中每行的1个表。为方便起见,表名应与名称列
  • 相同

现在我们可以开始了解继承发挥作用的地方。在操作表中,OperationTypeId引用相关表格的OpId ..."相关表格"由OperationTypeDescId确定。

一个例子:我们说我们有上面的数据集。在这个例子中,我们知道在123 Main St.的一个车库里发生了一次操作。我们知道它从中午开始,但还没有结束。我们知道操作的类型是" OpBar"。由于我们知道我们正在进行OpBar操作而不是OpFoo操作,因此我们只关注与OpBar相关的属性,即stuff1和stuff2。由于Operations的OperationTypeId是2,我们知道Stuff1是789而Stuff2是ghi。

现在是棘手的部分。在您的计划中,这将需要Reflection。如果您不知道那是什么,那就是从该类型的NAME中获取Type的做法。在我们的示例中,我们知道要查看的表(OpBar),因为它在OperationTypeDesc表中的名称。换句话说,你不会自动知道要查看的表格;反射告诉你那些信息。

修改 Csaba说"将来如果你想引入一个新的操作,将涉及在数据库中创建一个新表"。那是正确的。您还需要向OperationTypeDesc表添加一个新行。 Csaba暗示这是一件坏事,我不同意 - 只有一些条款。如果您要经常添加新的操作类型,那么是的,他提出了一个非常好的观点。你不想经常创建新表。但是,如果您提前知道将执行哪些类型的操作,并且很少添加新类型的操作,那么我认为这是要走的路。所有操作共有的所有信息都在Operation表中,所有特定于操作的信息都会进入相关的"子表"。

还有一个非常重要的注意事项。由于这是如何设计的,你,人类必须意识到设计。每当您创建新的操作类型时,它都不像创建新表那么简单。具体来说,您必须确保新的表名和OperationTypeDesc" Name"入口是一样的。把它想象成一个额外的约束 - 一个" INTEGER" column只能包含int,否则db不会允许数据。以同样的方式,"名称"列只能包含现有表的名称。你必须意识到这种约束,因为它不能(轻易)自动实施。