数据库设计建议


8

我正在为我们的销售团队设计一个数据库,以用作快速的工作报价工具。我想对设计的特定方面提供一些反馈。

报价基本上是通过选择预定义“装配”的列表来建立的,每个装配都有一个议定的价格。主窗体的简化视图如下所示:

                                                  +------------ --- ---+
                                                  | Assembly options   |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly  | unit cost  | quantity | total cost | 1 | 2 | 3 |     |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55      | £10'000    | 2        | £25'500    | 1 | 1 |   |     |  | 
| RDOL2.2    | £2'000     | 1        |  £1'500    |   | 1 |   |     |  | 
| DOL5.0     | £1'000     | 1        |  £1'200    |   |   | 1 |     |  | 
+------------+------------+----------+------------+---+---+---+ --- +--+

用户选择预定义的装配,输入数量并选择所需的“选项”。每个程序集最多可能具有50个可用选项。选项也是具有自己价格的预定义装配(子装配)。每行的“总成本”计算为(主装配成本*数量)+任何选项的成本。

当用户将光标移动到选项框中时,他们会知道该选项的名称和价格。

现在,这变得复杂了。每个程序集都有自己的可用选项列表。即,“ VSD55”的选项1代表与DOL5.0的选项1不同的子组件。

至于程序集,这里是我正在使用的简化表:

+-----------------+    +------------------------+    +-----------------------------+
| assembly        |    | assembly_option        |    | assembly_option_link        |
+-----------------+    +------------------------+    +-----------------------------+
| assembly_id (PK)|    | assembly_option_id (PK)|    | assembly_option_link_id (PK)|
| assembly_name   |    | assembly_option_name   |    | assembly_id (FK)            |
| unit_cost       |    | option_number          |    | assembly_option_id (FK)     |
+-----------------+    | unit_cost              |    +-----------------------------+
                       +------------------------+

表“ assembly_option_link”基本上定义了每个程序集可用的选项。

现在对于“ quote”表:

 +-----------------+    +------------------------+    
 | quote           |    | quote_assembly         |    
 +-----------------+    +------------------------+    
 | quote_id (PK)   |    | quote_assembly_id (PK) |
 | quote_name      |    | assembly_id (FK)       |
 +-----------------+    | quantity               |
                        +------------------------+    

现在,棘手的部分是如何存储任何选定的选项。我是否应该使用所有50个选项字段来扩展“ quote_assembly”表,即使这违反了规范化规则。永远不会选择具有全部50个选项的装配体,因此这似乎效率也很低。从正面来看,此解决方案允许用户输入表单直接映射到表,从而简化了编码。

我认为“标准化”解决方案将是创建另一个这样的表:

+------------------------------+
| quote_assembly_option        |
+------------------------------+
| quote_assembly_option_id (PK)|
| quote_assembly_id (FK)       |
| assembly_option_id (FK)      |
| quantity                     |
+------------------------------+

该解决方案意味着仅存储选定的选项。另外,我可以存储实际的“ assembly_option_id”,而不是存储option_number。然后,这使计算总报价成本变得更加简单,因为我不需要在“ option_number”和“ assembly_option_id”之间进行转换来查找装配选件成本。但是,此解决方案的主要缺点是,它与用户输入表单的搭配不太好。我想我需要应用一些精美的编码才能将表格与表格连接起来。

有人可以在这里提供任何设计建议吗?我希望我对自己的解释足够好。

更多信息
这也是一份详细的报价报告,可将任何选定的选项扩展为主装配件下的单独行项目。例如:

+---------------------------------+------------+----------+------------+
| assembly                        | unit cost  | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55                           | £10'000    | 2        |   £20'000  |
|   - Seal leak protection        | £ 5'000    | 1        |   £ 5'000  |   <-option 1
|   - Motor over temp protection  | £   500    | 1        |   £   500  |   <-option 2
+---------------------------------+------------+----------+------------+
|                                 |            |          |   £25'500  |
+---------------------------------+------------+----------+------------+

Answers:


3
                                                  +------------ --- ---+
                                                  | Assembly options   |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly  | unit cost  | quantity | total cost | 1 | 2 | 3 |     |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55      | £10'000    | 2        | £20'000    | 1 | 1 |   |     |  | 

如果有人将报价单交给我,我的第一个问题是“ VSD55的选项1是什么?” 答案将是“我不知道”。该信息不在报价中。如果这个人不太可能提出第二个问题,那么这个问题就是“这需要多少钱?” 同样,答案将是“我不知道”。很快就会出现非常令人不安的沉默,在那期间,给我报价的人会想像被火车撞倒会有多大的感觉。

选项必须是报价中的行项目,以及它们的单价,数量和总价。选项必须命名而不是编号。他们也应该直接出现在其父集下,而不是散布在地狱和佐治亚州的一半地区。

如果您想花我一点钱,那么最好弄清楚我应该得到的钱。

用户界面表单上的50个复选框没有(很多)错误。这使得选择选项变得容易。但是,UI代码应读取复选框,然后将正确的信息插入规范化表中。


听起来您正在提供有关业务流程的建议,但这些建议不是您可以选择的,David试图用这种方法来封装他所分配的项目的最佳方法。〜现在,我同意dba应该在有能力的地方影响设计,但是有时候这无济于事。还请记住,这是一个内部工具(请参见第一行)
jcolebrand

1
足够公平的评论,让我发笑!当然,我们的报价报告确实可以满足您的建议。此后,我已将这个细节添加到原始问题中,以避免更多的主题讨论;)
David

3

您提供的最后一个选项是我会选择的方式。并返回两个分组表,一个用于“主行”,另一个用于收集的50列的“是否存在”行。假设您可以轻松地将选项映射到适当的列ID(看起来就可以轻松完成)。

假设像C#这样的语言,您可以使用LINQ等,对于迭代而言,这将足够容易。即使包含一些循环(这是UI代码,也必须在某个时候完成),这些操作也很容易做到。 )。或者您可以在返回之前在数据库中进行数据透视,这会更快。但是它仍然会保持复杂性。

但是您的设计对我来说确实听起来不错。


0

添加额外的表对我来说也相当不错。

当我处理类似的问题时,我尝试将树存储在order_lines表中。如果您考虑过类似的事情,我有:

  • 的额外parent_id字段order_lines和外键,以便(parent_id, product_id)参考(order_line_id, product_id)

  • 要使之具有选择权的检查约束将意味着父母(在我的情况下check((option_id is not null) = (parent_id is not null)))。

换句话说,我让用户界面说明了如何存储事物:

+---------------------------------+------------+----------+------------+
| assembly                        | unit cost  | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55                           | £10'000    | 2        |   £20'000  |
|   - Seal leak protection        | £ 5'000    | 1        |   £ 5'000  |
|   - Motor over temp protection  | £   500    | 1        |   £   500  |
+---------------------------------+------------+----------+------------+

从UI编码的角度来看,这似乎是正确的。但是从业务规则的角度来看,它很快就感觉到了错误,因为它引入了很多问题。(我不得不在触发器中处理各种特殊情况。)

因此不建议 ...就我所经历的类似情况而言,您当前的方法在将来不会出现问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.