我正在寻找有关设计数据库的建议,该数据库具有希望与几种不同的其他实体类型相关的通用实体。可怕的介绍句,我知道......所以请让我通过例子解释。
考虑到我有两个不同的实体Employees和Customers with table defs:
Employees
----------
EmployeeID int PK
FirstName varchar
LastName varchar
... other Employee specific fields
Customers
----------
CustomerID int PK
FirstName varchar
LastName varchar
... other Customer specific fields
更好的设计可能在相关的基表中有公共字段FirstName和LastName,但这并不是我挣扎的部分。
现在,请考虑我希望能够为员工和客户存储无限数量的地址和电话号码,并定义表格:
Addresses
----------
AddressID int PK
AddressLine varchar
City varchar
State varchar
PostalCode varchar
PhoneNumbers
-------------
PhoneNumberID int PK
PhoneNumber varchar
PhoneExtension varchar
然后另外两个表将地址和PhoneNumbers与员工联系起来:
EmployeeAddresses
------------------
EmployeeAddressID int PK
EmployeeID int FK Employees.EmployeeID
AddressID int FK Addresses.AddressID
EmployeeAddressType enum
EmployeePhoneNumbers
---------------------
EmployeePhoneNumberID int PK
EmployeeID int FK Employees.EmployeeID
PhoneNumberID int FK PhoneNumbers.PhoneNumberID
EmployeePhoneNumberType enum
两个类似的表CustomerAddresses和CustomerPhoneNumbers,用于将地址和PhoneNumbers与Customers表相关联。地址和PhoneNumbers的任何特定于员工或客户的方面,如上面的EmployeeAddressType,也都在最后四个表中。
根据我发现的研究互联网的情况,这种设计称为每个类型的表(TPT)或每个子类的表(TPS)。多态优势似乎很吸引人,例如,我可以将AddLine2添加到Addresses表中,我的Employess和Customers都会自动获得额外地址行的好处。
TPT上的这些来源所指出的缺点是查询速度较慢且难以实施。而现在我的请求是开放式的... ...
我还没有考虑其他哪些缺点?您可以尝试基于此设计维护和发展应用程序吗?最后,上述设计是最有经验的数据库设计师会使用的吗?
感谢。
答案 0 :(得分:1)
使用单表继承来启动。它是最简单,最简单,最快速的。
使用派对模型。个人和组织都是缔约方,可以扮演客户或员工的角色。
将电子邮件地址,电话号码,网站和邮寄地址视为“联系方式”或地址的子类型。
如果您使用JBoss Hibernate(java)或NHibernate(.net)之类的工具,那么这将为您完成大部分工作。
答案 1 :(得分:0)
您最好先使用People表,然后使用customers表,员工表等。电子邮件地址,地址和电话号码将与人员表或客户或其他专业表相关。
与多个父表相关的一个地址表的问题在于,您无法设置正确的外键约束,并且无法使用不良数据。
您可以使用单独的表正确创建外键,但随后查询变得更难(假设您需要了解CA中的每个人),您会获得最终位于多个类别中的人员的重复记录(员工也可能是客户)当需要更改表结构时,更难确保表全部更新。
答案 2 :(得分:0)
您当前数据库设计的一个缺点是您的数据库不会阻止员工拥有2个或更多家庭地址。它也不会阻止客户在这个问题上没有地址。
您可以通过更改为EmployeeAddresses表上的复合主键(PK = EmployeeID,EmployeeAddressType)来防止创建多个家庭地址。但是,如果您使用的是ORM,那么当PK为一列时,其中许多只能玩得很好。
答案 3 :(得分:0)
员工和客户都是People类的子类,如前面的回复中所述。这两个子类可能不是互斥的。
有一种称为类表继承的技术。在这种技术中,将有三个表,People,Employees和Customers。所有人共有的属性(如Address)将位于People表中。
您可以通过访问此标记来获取详细信息 class-table-inheritance并查看“信息”标签。