许多表之一的外键(MySQL)

时间:2011-11-02 02:43:16

标签: mysql database database-design

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

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

我正在研究数据库(MySQL),这就是我现在所拥有的。任何包含“用户”的内容都指的是在线客户,而任何包含Cust的内容都指的是非在线客户。

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

发票包含客户,业务或用户(在线客户)。发票也是一个或多个InvoiceLines,每个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,因为我想要外键,而且商家的字段与其他两个字段不同。

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

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

   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)|
--------------------------        | ...                     |
                                  ---------------------------

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

这是我第一次设计数据库,所以任何想法都值得赞赏。

1 个答案:

答案 0 :(得分:1)

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

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

不同种类的发票相同。一个表包含常见的发票信息(最常见的是主键),一个或多个辅助表包含特定于发票的种类的信息。

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