我正在为家庭成员拥有的小型企业(景观美化,树木移除等)设计网站。这是一个宠物项目。
该网站将允许用户创建一个帐户,然后请求服务,并将创建必要的发票,但它也将允许我的家庭成员输入未通过网站收到的订单的发票。
我正在研究数据库(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)|
-------------------------- | ... |
---------------------------
我还考虑在创建用户时触发创建新客户,但我也希望客户能够查看他们过去请求的发票/服务。
这是我第一次设计数据库,所以任何想法都值得赞赏。
答案 0 :(得分:1)
不,你不能将外键指向不同表中的主键,告诉数据库在其中一个表中找到匹配的记录(此外,可能是不同表中主键值的范围可能重叠,然后您可以匹配两个或多个主键表。)
您的错误是创建一个全新的表来解释客户和用户之间的差异。相反,创建一个包含公共列(可能称为customer)的表,然后将具有外键的表分隔回主表。每个表都包含一个客户子类型的列(在线或血肉)。
不同种类的发票相同。一个表包含常见的发票信息(最常见的是主键),一个或多个辅助表包含特定于发票的种类的信息。
这种设计类似于面向对象编程中的类继承。