您将如何为“默认子项”建模? 带有 ORM 的标志?
我正在使用 ORM(SQLAlchemy,但我的问题与实现无关)来建模父类与其子类之间的多对多关系。我想知道,表达这个概念的简单方法是什么“其中一个孩子是默认/主要孩子”?
例如,我需要坚持以下内容:
这个 Person 实例有地址 X 和 Y,主要的是 Y。
我看到这是使用“中间”类实现的,例如“PersonAddressRelation”,其中包含“Person”,“Address”和“main”标志,但我认为它看起来有点麻烦。。有更好的方法吗?
I'm using an ORM (SQLAlchemy, but my question is quite implementation-agnostic) to model a many-to-many relationship between a parent class and its children.. I was wondering, what would be a simple way to express the concept "one of the children is the default/main one"?
For example, I'd need to persist the following:
This Person instance has Address X and Y, the main one is Y.
I saw this implemented using a "middle" class like "PersonAddressRelation" that would contain "Person", "Address" and the "main" flag, but I think it looks a bit cumbersome.. Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最简单的方法是在 Person 表上有一个连接表、PersonAddressRelation,以及一个作为 Address 表的键的 DefaultAddress 列。
The simplest way would be to have a join table, PersonAddressRelation, and also a DefaultAddress column on the Person table that keys to the Address table.
几句话。
M:N 关系不指定“父级”和“子级”,因为没有父级也没有子级:只有两个实体通过第三个实体(中间实体)具有 m:n 关系。
“地址”通常不是有效的实体类型,因为从语义上讲,它没有标识,类似于“名称”没有标识(名字、姓氏)。 当您考虑重用 Address 类型的实体实例时,您会看到这一点:一般情况下您不会这样做。 (尽管您将重复使用客户实体实例,例如,当客户有多个订单时)
您希望在 M:N 关系(默认)上指定一个属性,因为它属于那里。 这意味着关系本身形成一个实体(这是中间实体,通常它只有两个形成 PK 的 FK 字段)。 这称为“客观化关系”,因为关系本身被视为一个实体。 其他示例是“员工 m:n 部门”,并且您想要指定员工开始工作的部门的“开始日期”。
所以一般来说:创建中间实体,因为它通常应该在那里,并在那里添加属性。 在这种特殊的 Address 情况下,请务必确保您在相关实体(Person)之间重复使用 Address 实例。 如果没有,请将地址与人员合并,或者如果一个人可以有多个地址,请在人员 - 地址之间创建一个简单的 1:n 关系,以将其规范化,但不要害怕将地址数据合并到与其相关的实体中,因为地址数据通常不会被重复使用(因此您的 m:n 关系实际上不存在:没有与多个人员实例相关的 Address 实例。
A couple of remarks.
M:N relationships don't specify 'parent' and 'child', as there's no parent nor a child: there are simply two entities having an m:n relationship via a 3rd entity (the intermediate entity).
'Address' is in general not a valid entity type, as semantically it has no identity, similar to a 'name' has no identity (first name, last name). You'll see this when you look at re-using an entity instance of type Address: you won't do that in general. (though you will re-use a Customer entity instance for example, when the customer has multiple orders)
You want to specify an attribute on the M:N relationship (default), as it belongs there. This means that the relationship itself forms an entity (which is the intermediate entity, often it has just two FK fields forming the PK). This is called an 'objectified relationship', as the relationship itself is seen as an entity. Other examples of this are Employee m:n Department and you want to specify the StartDate an employee started for a department the employee works for.
So in general: create the intermediate entity, as it in general should be there, and add the attribute there. In this particular case with Address, be really sure you are re-using Address instances among related entities (Person). If not, merge Address with Person OR if a person can have multiple addresses, create a simple 1:n relationship between Person - Address, to normalize it out, though don't be afraid to merge address data into the entity it is related to, as often address data is really not re-used (so your m:n relationship is really not there: there's no Address instance which is related to multiple person instances.