简体   繁体   English

同一两张表上的多对一和一对一关系?

[英]Many-to-One and One-to-One Relationships on Same Two Tables?

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 .我的表是accountsusers 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.我在users表中有一个account字段,其中存储了与用户相关的帐户的 ID。 In the accounts table, I have an owner field, which stores the ID of the user who owns the account (ie the head admin).accounts表中,我有一个owner字段,它存储拥有该帐户的用户(即主管管理员)的 ID。

I'm using InnoDB so I can make use of foreign keys.我正在使用 InnoDB,所以我可以使用外键。 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.问题是我不能在没有先创建另一个帐户或用户的情况下创建一个帐户或用户(由于外键的限制),所以我将owner设为可为空。 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.现在我可以创建一个拥有 null owner的帐户,然后创建用户,最后将帐户的owner设置为用户。

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:以下是我想出的其他一些可能的方法,以及我对每种方法的想法:

  1. Have a boolean owner field in the users table.users表中有一个 boolean owner字段。 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 to true .由于每个帐户只能有一个所有者,因此这种方式似乎不太理想,因为我必须确保每个帐户只有一个用户的属性设置为true

  2. Have a third table called owners .有第三个表称为owners This seems like more overhead and more work for no good reason since it's effectively the same as having an owner field in the users table.这似乎更多的开销和更多的工作没有充分的理由,因为它实际上与在users表中拥有一个owner字段相同。

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.我现在如何拥有它对我来说最有意义,但是在我创建用户之前必须设置 null 所有者,然后在事后回来设置它有点尴尬。

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?这个问题类似,但没有提到外键: 设计表:一对多和一对一?

In general is a bad idea if your schema cannot be sorted topologically, ie 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 eg "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".您知道(给定当前请求)一个帐户必须有一个且只有一个所有者,或者用户必须列在一个且只有一个帐户中的事实并不是真正与“用户”域相关的 IMO 规则和“账户”。

You can implement those rules easily, but structuring your data so that you have no other possibility is IMO a mistake.您可以轻松地实施这些规则,但是将数据结构化以使您没有其他可能性是 IMO 的错误。 You should aim to model the domain, not the specific rules... because people will change their mind about what those rules are.您应该针对 model 域,而不是特定规则......因为人们会改变他们对这些规则的看法。

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.此外,当您在 model 中存在循环依赖关系时,您的查询将更难编写。

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.例如,一个非常常见的情况是尝试仅使用一个表来表示分层零件列表数据库,该表具有指向表本身的“父”字段......更好的是有两个表,零件和组件,其中组件有两个引用部分和一个数量。

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".如果您对所有者列可以为空感到不舒服,您可以依赖一些神奇的用户记录(可能 id 为零),这将是“系统用户”。 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.无论如何,这似乎比允许帐户拥有 null 所有者更臭。

在此处输入图像描述

For the current requirement to have only one account per user当前要求每个用户只有一个帐户

alter table UserAccount add constraint un_user_account unique(UserID);

and when the requirement changes to many-to-many, drop the constraint当需求变为多对多时,放弃约束

alter table UserAccount drop constraint un_user_account;

For the one owner only, simply enforce that on the application level.仅对于一个所有者,只需在应用程序级别强制执行即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM