【问题标题】:SQL Best practices: Using a column to store two different kinds of data?SQL 最佳实践:使用列存储两种不同类型的数据?
【发布时间】:2016-02-04 20:49:30
【问题描述】:

假设我有一个包含idusernamepasswordtypelinked_id 的登录表

type 列指定该登录名是属于员工还是客户。

如果他们是员工,linked_id 是他们在员工表中的 ID。

如果他们是客户,linked_id 是他们在客户表中的 ID。

直觉上,这似乎是个坏主意,但除了处理外键约束之外,我想不出也没有理由不这样做。

这也带来了另一个问题:在这种情况下拥有 FK 约束总是很重要吗?

想法?

【问题讨论】:

  • 我会使用多列。如果看起来更乱(因为你有一堆空值),但有更好的数据库完整性和空值占用很少的磁盘空间。
  • 是的,在这种类型的链接数据中具有 FK 约束总是好的。否则,很容易删除登录记录,留下孤立的客户或员工;或者在您的设计案例中,删除员工或客户记录并留下孤立的登录记录。

标签: mysql sql sql-server database foreign-keys


【解决方案1】:

我认为您正在错误地考虑您的表格设计。我会将登录信息放在一个表中,然后从相应的表中指向登录记录。换句话说,从员工和客户表中指向您的登录记录,而不是从登录记录中指向客户或员工记录。这使您可以拥有外键约束并消除对“类型”的额外字段的需要

举个例子:

  • 登录:ID(PK)、用户名、密码
  • 员工:Id(PK)、姓名、员工编号、Login_Id(FK_LoginId)
  • 客户端:Id(PK)、姓名、地址、Login_Id(FK_LoginId)

然后,您可以通过数据存储在哪个表中固有地知道每个登录是什么“类型”。

【讨论】:

  • 出色的洞察力。既然你已经指出了这一点,它似乎很明显。谢谢你的耳光!
  • 当然,现在的问题是弄清楚登录代表什么样的用户:客户或员工,这可能需要扫描两个表(客户和员工)以获得答案。
  • 是的,但我假设您的用户名字段将被索引,因此即使您必须查看两个表,它也会非常快。由于您谈论的是企业对企业类型的场景,因此您的用户表将始终相对较小。
【解决方案2】:

最简单的解决方案是在您的数据库中简单地添加一个额外的列并使用EmployeeIdClientId 使表结构更易于理解。

您也可以争辩说您在数据库设计中缺少实体。例如,如果员工也是客户怎么办?在这种情况下,当前的系统将如何处理?

你可以有一个中间表来管理这个并确定那个人的状态。

即有表Login

字段:ID, username, password, type, PersonId

然后是另一个表PersonEmployeeIdClientId,虽然我确实认为这会导致很多NULL 值它会支持我所描述的上述情况。

作为补充说明,我不想查看现有的Login 表,确定linked_id 字段,然后必须决定该列与哪个表相关,EmployeeClient

您也可以像 @randyh22 所建议的那样将其拆分,并完全删除 linked_id 字段,并在子表中包含 Login 标识符(EmployeesClients)。

重组:

Login 表:LoginId、用户名、密码(确保已散列)

员工表:EmployeeId、Forename、Surname、LoginId

客户表:ClientId、Forename、Surname、LoginId

【讨论】:

  • 我使用过数据库设计,其中一列可以指向任意数量的表。这是一场噩梦。
  • @MikeChristensen - 我目前在工作中处于这种情况。完全同意!
  • 这是糟糕的数据库设计。通常这种情况意味着您的 ID 指向错误的方向。在 OP 的情况下,没有什么复杂到他们需要在多个表中有一个列点。
  • 感谢您的回答。在我们的情况下,员工兼客户是不道德的,因此该用例不适用于此处。
猜你喜欢
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-28
  • 2014-02-06
相关资源
最近更新 更多