相同的两个表上的多对一和一对一关系?
我正在设计一个数据库,其中两个字段具有多对一关系,但我还需要它们之间存在一对一关系,并且我想了解是否有更好的方法来做到这一点的一些建议我现在就有了
我的表是 accounts
和 users
。一个帐户可以有多个用户,但每个帐户只能且必须有一个所有者。一名用户只能与一个帐户相关。
我在 users
表中有一个 account
字段,它存储与用户相关的帐户的 ID。在 accounts
表中,我有一个 owner
字段,它存储拥有该帐户的用户(即管理员管理员)的 ID。
我正在使用 InnoDB,因此我可以使用外键。问题是,如果没有先创建帐户或用户(由于外键的限制),我就无法创建帐户或用户,因此我将 owner
设置为可为空。现在,我可以创建一个 owner
为空的帐户,然后创建用户,最后将帐户的 owner
设置为该用户。
这是可以接受的吗?有更好的方法吗?
以下是我提出的一些可能的其他方法,以及我对每种方法的想法:
在
users
表中拥有一个布尔型owner
字段。由于每个帐户只能有一个所有者,因此这种方式似乎不太理想,因为我必须确保每个帐户只有一个用户将该属性设置为true
。有第三个表,名为
owners
。这看起来像是没有充分理由的更多开销和更多工作,因为它实际上与在users
表中拥有owner
字段相同。
我现在拥有它的方式对我来说最有意义,但是在创建用户之前必须设置一个空所有者,然后在事后返回设置它,这有点尴尬。
如果您能给我任何意见,我将不胜感激。谢谢!
这个问题类似,但没有提到外键:设计表:同时一对多和一对一?
I'm designing a database where two fields have a many-to-one relationship, but I also need a one-to-one relationship between them, and I would like some advice on whether there is a better way to do it than what I've got right now.
My tables are accounts
and users
. An account can have multiple users, but each account can only and must have one owner. A user can be related to only one account.
I have an account
field in the users
table, which stores the ID of the account the user is related to. In the accounts
table, I have an owner
field, which stores the ID of the user who owns the account (i.e. the head admin).
I'm using InnoDB so I can make use of foreign keys. The problem is that I can't create an account or a user without the other being created first (due to the restraints of the foreign keys), so I made owner
nullable. Now I can create an account with a null owner
, then create the user, and finally set the owner
on the account to the user.
Is this acceptable, and is there a better way?
Here are some possible other ways I've come up with, and my thoughts on each:
Have a boolean
owner
field in theusers
table. Since every account can only have one owner, this way seems less than ideal because I'd have to ensure only one user per account has the attribute set totrue
.Have a third table called
owners
. This seems like more overhead and more work for no good reason since it's effectively the same as having anowner
field in theusers
table.
How I have it now makes the most sense to me, but it's a little awkward having to set a null owner until I create the user, and then coming back to set it after the fact.
I'd appreciate any input you can give me. Thanks!
This question is similar, but there's no mention of foreign keys: Designing Tables: One to many and one to one at same time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,如果您的模式无法按拓扑排序,即如果您无法建立一个表仅引用排序中位于其前面的表的排序,那么这是一个坏主意。这种“分层”依赖关系对于软件模块来说也是一个非常好的属性(如果两个模块相互依赖,就会出现问题)。
在您的情况下,您有引用帐户的用户和引用用户的帐户,因此显然无法找到拓扑顺序。
在这种情况下,一个标准解决方案是引入一个单独的表,例如“角色”,其中包含三列:用户、帐户和角色。列角色可以是“所有者”或“访客”。
事实上,您知道(鉴于当前的请求)一个帐户必须有一个且仅有一个所有者,或者一个用户必须列在一个且仅有一个帐户中,这并不是真正与“用户”域相关的 IMO 规则和“账户”。
您可以轻松实施这些规则,但在我看来,构建数据以使您没有其他可能性是一个错误。您的目标应该是对领域进行建模,而不是对具体规则进行建模……因为人们会改变对这些规则的看法。
您能设想一个用户拥有两个帐户吗?您可以设想一个拥有多个所有者/管理员的帐户吗?我可以……这意味着很可能很快就会提出这个请求。结构化数据使您无法表示这一点是在自找麻烦。
此外,当模型中存在循环依赖性时,您的查询将更难编写。
例如,一种非常常见的情况是尝试仅使用一个带有指向表本身的“父”字段的表来表示分层零件列表数据库...更好最好是使用两个表,零件和组件,其中组件有两个对零件和数量的引用。
In general is a bad idea if your schema cannot be sorted topologically, i.e. if you cannot establish an ordering where a table only refers to tables preceding it in the ordering. This sort of "layered" dependency is also a very nice property to have for example for software modules (you have a problem if two modules depends on each other).
In your case you have user that refers to account and account that refers to user so clearly there's no way to find a topological ordering.
One standard solution in this case is to introduce a separate table e.g. "role" where you have three columns: user, account and role. The column role can be either "owner" or "guest".
The fact that you know that (given the current requests) an account must have one and only one owner, or that a user must be listed in one and only one account are not IMO rules that are really pertinent to the domain of "users" and "accounts".
You can implement those rules easily, but structuring your data so that you have no other possibility is IMO a mistake. You should aim to model the domain, not the specific rules... because people will change their mind about what those rules are.
Can you conceive a user with two accounts? Can you conceive an account with multiple owners/admins? I can... and this means that most probably quite soon this will be a request. Structuring the data so that you cannot represent this is looking for troubles.
Also when you have cyclical dependencies in the model your queries will be harder to write.
A very common case is for example to try to represent a hierarchical part list database using just one table with a "parent" field that points to the table itself... much better is having two tables instead, part and component, where component has two references to part and and a quantity.
你的解决方案很好。
如果您对所有者列可为空感到不舒服,您可以依赖一些神奇的用户记录(可能 id 为零),这将是“系统用户”。因此,新创建的帐户将由零号用户拥有,直到其所有权被适当地重新定义。无论如何,对我来说,这似乎比允许帐户拥有空所有者更臭。
Your solution is fine.
If you're uncomfortable with the owner column being nullable, you could rely on some magic user record (perhaps with an id of zero) which would be the "system user". So newly created accounts would be owned by user-zero, until their ownership was suitably redefined. That seems smellier than allowing accounts to have a null owner, to me, anyway.
对于当前每个用户只有一个帐户的要求
以及当要求更改为多对多时,删除约束
仅对于一个所有者,只需在应用程序级别强制执行即可。
For the current requirement to have only one account per user
and when the requirement changes to many-to-many, drop the constraint
For the one owner only, simply enforce that on the application level.