我应该有1个或2个用户个人地址和用户组地址表吗?

k5hmc34c  于 2022-10-22  发布在  PHP
关注(0)|答案(4)|浏览(311)

如果我有用户,也有用户组(如本地天文学组/俱乐部),并且我希望两者都与街道地址有一对多的关系,那么我可以只拥有一个地址表和两个fk,这样我就不必复制表模式了吗?还是只有两个单独的表,useraddresses和usergroupaddresses更好?谢谢你的投入和时间,谢谢!

68bkxrlz

68bkxrlz1#

如果用户和组的地址实际上是相同类型的地址,那么可以根据需要使用一个地址表进行引用。

pdkcd3nj

pdkcd3nj2#

您描述的带有两个外键的设计称为“独占弧”。只能填充两个外键中的一个。执行和使用起来相当尴尬。
例如,一个地址必须引用一个实体,因此从概念上来说,该列是必需的,并且不应为NULL。但不能将两列都设置为NOT NULL,因为其中一列与给定地址不相关。所以它们必须为空。然后你必须有其他方法来防止两者都为NULL,同时也防止两者都不为NULL。MySQL不支持CHECK约束,因此您可以编写触发器或编写自定义应用程序代码来执行此规则。
创建一个地址表,但颠倒关系怎么样?也就是说,Users和Groups表包含对Addresses表的外键引用,而不是相反。
另一种解决方案是,用户和组都依赖于一个公共的超级表,称之为“可寻址表”或其他东西。就像OO设计中的接口或抽象类。然后,您的地址也可以具有Addressables的外键。参见other questions I have answered on this subject中的示例。
在我的书SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming的“多态关联”一章中,我也更详细地讨论了这个问题。

vyswwuz2

vyswwuz23#

最好有一个地址表,除非一种地址类型对另一种地址有特殊需求。这更容易维护,也允许您添加功能。例如,如果您当地的天文学小组决定在某个地方举办“活动”,那么您只需创建事件表并引用地址表,就可以开始了。如果你把它们分开,那么每次你有一个新的“实体”,它有一个地址,你就必须创建一个新表。
希望这有帮助。
至于你的评论:我将把参考放在一个单独的参考表中。

6ss1mwsb

6ss1mwsb4#

数据库设计的首要任务是有效性。当使用一个表策略来持久化所有地址时,将有一个地址属于用户还是组的隐式定义。
因为您不必识别哪些地址是所需的集合(用户或组),所以双表策略是一种更简单的编程方法,可以防止某人编写错误的代码(SQL)。
例如,我们需要来自用户地址的一些数据:

SELECT * FROM user_address WHERE <other conditions>; // The two-table strategy

/**
 * The one-table strategy
 */
SELECT * FROM all_addresses
WHERE user_id IS NOT NULL
    AND <other conditions>;

此外,如果我们使用两个表来持久化地址,无论需要什么地址,性能都会更好。
在一种表策略中,即使列中有索引(取决于数据库系统),“ISNOTNULL”条件也可能不会得到优化。Join是在一种表策略中识别用户地址的另一种方法,但它仍然比另一种策略更费力。
然而,单表策略有其性能优势。如果我们需要收集所有地址(无论用户或组),并且这种操作是系统的性能瓶颈,您可以考虑使用一个表策略。

相关问题