【问题标题】:Foreign Key to One of Many Tables (MySQL)许多表之一的外键(MySQL)
【发布时间】:2011-11-02 02:43:15
【问题描述】:

我正在为一个家庭成员拥有的小型企业(景观美化、树木移除等)设计一个网站。这是一个宠物项目。

该网站将允许用户创建一个帐户然后请求服务,并将创建必要的发票,但它也将允许我的家人输入未通过该网站收到的订单的发票。

我正在研究数据库(MySQL),这就是我目前所拥有的。凡是包含“User”的都是指在线客户,凡是包含 Cust 的都是指非在线客户。

基本上我在这里要做的是:

一张发票有一个客户、企业或用户(在线客户)。一张发票也有一个或多个 InvoiceLine,每个 InvoiceLine 都有一个服务或产品。

我将用户(在线客户)放在单独的表中,因为用户拥有密码哈希和密码盐(以及可能的其他东西)是有意义的,但仅为记录保存而添加的客户不应该有密码和与网站相关的事情。

   ServicesAndProducts 
--------------------------
| ID INT (PK)            | 
| Name VARCHAR(50)       |  
| BasePrice DECIMAL(7,2) |
| ...                    |
--------------------------

   CustServicesProvided               UserServicesProvided
---------------------------       ---------------------------
| ID INT (PK)             |       | ID INT (PK)             |
| ServiceID INT (FK)      |       | ServiceID INT (FK)      |
| CustInvoiceID INT (FK)  |       | UserInvoiceID INT (FK)  |
| ...                     |       | ...                     |
---------------------------       ---------------------------

       CustInvoices                     UserInvoices
--------------------------        --------------------------
| ID INT (PK)            |        | ID INT (PK)            |
| CustomerID INT (FK)    |        | UserId INT (FK)        |
| ....                   |        | ....                   |
--------------------------        --------------------------

        Customers                           Users
--------------------------        ---------------------------
| ID INT (PK)            |        | ID INT (PK)             |
| Name VARCHAR(50))      |        | Name VARCHAR(50)        |
| BasePrice DECIMAL(7,2) |        | PasswordHash VARCHAR(50)|
| ...                    |        | PasswordSalt VARCHAR(50)|
--------------------------        | ...                     |
                                  ---------------------------

我还有另一个类似的 BusinessServicesProvided、BusinessInvoices 和 Business,因为我想要外键,而且 Businesses 的字段与其他两个字段不同。

我的问题是有一种方法可以将发票表组合在一起,并将提供的服务表组合在一起,同时仍然保持发票表与客户和用户(和企业)之间的三种外键?

我想过可能会添加一个 InvoiceType 表,然后在 Invoice Table 中有一个 TypeID (FK) 来表示,但我不知道如何维护实体(客户、业务或用户)之间的外键和发票。例如:

   ServicesAndProducts 
--------------------------
| ID INT (PK)            | 
| Name VARCHAR(50)       |  
| BasePrice DECIMAL(7,2) |
| ...                    |
--------------------------

      ServicesProvided    
---------------------------
| ID INT (PK)             |
| ServiceID INT (FK)      |
| CustInvoiceID INT (FK)  |
| ...                     |
---------------------------

       Invoices                            InvoiceType
--------------------------        ---------------------------
| ID INT (PK)            |        | ID INT (PK)             |
| ForeignID INT (FK)     |        | Name VARCHAR(50)        |
| Invoice Type INT (FK)  |        |                         |
| ....                   |        |                         |
--------------------------        ---------------------------

        Customers                           Users
--------------------------        ---------------------------
| ID INT (PK)            |        | ID INT (PK)             |
| Name VARCHAR(50))      |        | Name VARCHAR(50)        |
| BasePrice DECIMAL(7,2) |        | PasswordHash VARCHAR(50)|
| ...                    |        | PasswordSalt VARCHAR(50)|
--------------------------        | ...                     |
                                  ---------------------------

我还考虑过在创建用户时使用触发器来创建新客户,但我也希望客户能够查看他们过去请求的发票/服务。

这是我第一次设计数据库,因此欢迎任何想法。

【问题讨论】:

    标签: mysql database database-design


    【解决方案1】:

    不可以,你不能将外键指向不同表的主键,告诉数据库在其中一个表中找到匹配的记录(此外,假设不同表中的主键值范围可能重叠,然后您可能会匹配两个或多个主键表)。

    您的错误是创建一个全新的表来说明客户和用户之间的差异。相反,使用公共列(可能称为客户)创建一个表,然后将具有外键的表分离回主表。每个表都包含其中一种客户子类型(在线或有血有肉)的列。

    不同种类的发票也是如此。一个表保存常见的发票信息(尤其是主键),一个或多个辅助表保存特定于种类发票的信息。

    这种设计类似于面向对象编程中的类继承。

    【讨论】:

      猜你喜欢
      • 2011-03-23
      • 2011-06-28
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 2016-02-05
      相关资源
      最近更新 更多