[英]Many-to-One and One-to-One Relationships on Same Two Tables?
我正在设计一个数据库,其中两个字段具有多对一关系,但我也需要它们之间的一对一关系,并且我想就是否有比什么更好的方法提出一些建议我现在有。
我的表是accounts
和users
。 一个帐户可以有多个用户,但每个帐户只能且必须有一个所有者。 一个用户只能与一个帐户相关联。
我在users
表中有一个account
字段,其中存储了与用户相关的帐户的 ID。 在accounts
表中,我有一个owner
字段,它存储拥有该帐户的用户(即主管管理员)的 ID。
我正在使用 InnoDB,所以我可以使用外键。 问题是我不能在没有先创建另一个帐户或用户的情况下创建一个帐户或用户(由于外键的限制),所以我将owner
设为可为空。 现在我可以创建一个拥有 null owner
的帐户,然后创建用户,最后将帐户的owner
设置为用户。
这是可以接受的,有没有更好的方法?
以下是我想出的其他一些可能的方法,以及我对每种方法的想法:
在users
表中有一个 boolean owner
字段。 由于每个帐户只能有一个所有者,因此这种方式似乎不太理想,因为我必须确保每个帐户只有一个用户的属性设置为true
。
有第三个表称为owners
。 这似乎更多的开销和更多的工作没有充分的理由,因为它实际上与在users
表中拥有一个owner
字段相同。
我现在如何拥有它对我来说最有意义,但是在我创建用户之前必须设置 null 所有者,然后在事后回来设置它有点尴尬。
我很感激你能给我的任何意见。 谢谢!
这个问题类似,但没有提到外键: 设计表:一对多和一对一?
一般来说,如果您的模式无法按拓扑排序,即如果您无法建立排序,其中表仅引用排序中它之前的表,则通常是一个坏主意。 这种“分层”依赖也是一个非常好的属性,例如对于软件模块(如果两个模块相互依赖,就会出现问题)。
在您的情况下,您有引用帐户的用户和引用用户的帐户,因此无法找到拓扑排序。
在这种情况下,一个标准解决方案是引入一个单独的表,例如“角色”,其中有三列:用户、帐户和角色。 列角色可以是“所有者”或“访客”。
您知道(给定当前请求)一个帐户必须有一个且只有一个所有者,或者用户必须列在一个且只有一个帐户中的事实并不是真正与“用户”域相关的 IMO 规则和“账户”。
您可以轻松地实施这些规则,但是将数据结构化以使您没有其他可能性是 IMO 的错误。 您应该针对 model 域,而不是特定规则......因为人们会改变他们对这些规则的看法。
你能设想一个有两个帐户的用户吗? 您可以设想一个拥有多个所有者/管理员的帐户吗? 我可以……这意味着很可能很快就会提出请求。 将数据结构化以使您无法表示这一点正在寻找麻烦。
此外,当您在 model 中存在循环依赖关系时,您的查询将更难编写。
例如,一个非常常见的情况是尝试仅使用一个表来表示分层零件列表数据库,该表具有指向表本身的“父”字段......更好的是有两个表,零件和组件,其中组件有两个引用部分和一个数量。
你的解决方案很好。
如果您对所有者列可以为空感到不舒服,您可以依赖一些神奇的用户记录(可能 id 为零),这将是“系统用户”。 因此,新创建的帐户将归用户零所有,直到它们的所有权被适当地重新定义。 无论如何,这似乎比允许帐户拥有 null 所有者更臭。
当前要求每个用户只有一个帐户
alter table UserAccount add constraint un_user_account unique(UserID);
当需求变为多对多时,放弃约束
alter table UserAccount drop constraint un_user_account;
仅对于一个所有者,只需在应用程序级别强制执行即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.