![]() |
1
39
通常有三种方法可以将对象继承映射到数据库表。 您可以创建一个大表,其中包含所有对象的所有字段,并为该类型提供一个特殊字段。虽然现代数据库不存储空字段而节省了空间,但这很快但浪费了空间。如果您只在表中查找所有用户,那么对于其中的每种类型的人,事情都会变得缓慢。并非所有的或映射器都支持这一点。 您可以使用包含基类字段的所有表为所有不同的子类创建不同的表。从性能角度来看,这是可以的。但不是从维护的角度。每次基类更改时,所有表都会更改。 你也可以按照你的建议为每个班级做一张桌子。通过这种方式,您需要连接来获取所有数据。所以它的性能较差。我认为这是最干净的解决方案。 你想用什么当然取决于你的情况。没有一个解决方案是完美的,所以你必须权衡利弊。 |
![]() |
2
44
看看马丁·福勒的 Patterns of Enterprise Application Architecture :
|
![]() |
3
5
如果用户、人员和特殊人员都具有相同的外键,那么我将拥有一个表。添加一个名为type的列,该列被约束为用户、人员或特殊人员。然后根据类型的值对其他可选列进行约束。 对于对象代码来说,如果您有单独的表或多个表来表示多态性,就没有多大区别。但是,如果必须对数据库执行SQL,那么在单个表中捕获多态性就容易多了……前提是子类型的外键相同。 |
![]() |
4
5
我在这里要说的是将数据库架构师置于纵容之下,但这里是: 考虑数据库 看法 作为接口定义的等价物。 表是类的等价物。 因此在您的示例中,所有3个人类都将实现IPerson接口。 所以你有三张表,分别是“用户”、“个人”和“特殊人”。 然后有一个视图“personview”或任何选择公共属性(由“interface”定义)的视图,从所有3个表中选择到单个视图中。 使用此视图中的“PersonType”列存储所存储人员的实际类型。 因此,当您运行的查询可以对任何类型的人进行操作时,只需查询PersonView视图。 |
![]() |
5
5
这可能不是OP想要问的,但我想我可以把它扔到这里。 我最近在一个项目中遇到了一个数据库多态性的独特案例。我们有60到120个可能的类,每个类都有自己的一组30到40个独特的属性,所有类上大约有10到12个共同的属性。我们决定采用SQL-XML路由,结果得到了一个表。比如:
将所有公共属性作为列,然后是一个大的XML属性包。ORM层随后负责从xmlotherproperties读取/写入各自的属性。有点像:
(我们最终将XML列映射为一个仓促的而不是一个XML文档,但是您可以使用最适合您的DAL的任何内容) 它不会赢得任何设计奖项,但如果你有大量(或未知)可能的课程,它将起作用。在sql2005中,您仍然可以在SQL查询中使用xpath根据存储为xml的某些属性选择行。这只是一个小小的表演惩罚。 |
![]() |
6
4
在关系数据库中,有三种处理继承的基本策略,以及一些更复杂/定制的替代方案,具体取决于您的具体需求。
这些应用程序中的每一个都提出了自己关于规范化、数据访问代码和数据存储的问题,尽管我个人倾向于使用 每个子类一张表 除非有一个特定的性能或结构上的原因去选择其中一个。 |
![]() |
7
4
在这里冒着成为一名“建筑宇航员”的风险,我更倾向于为子类使用单独的表格。使子类表的主键也成为链接回父类型的外键。 这样做的主要原因是它变得更加逻辑一致,并且您最终不会得到许多字段,这些字段对于特定的记录来说是空的和无意义的。当您迭代设计过程时,这个方法还使得向子类型添加额外的字段更加容易。 这确实增加了向查询中添加联接的缺点,这可能会影响性能,但我几乎总是先使用理想的设计,然后在有必要时,稍后再进行优化。几次我都是先走“最优”的路,但后来我几乎总是后悔。 所以我的设计应该是 人员(个人ID、姓名、地址、电话等) 特殊人员(个人ID引用个人(个人ID),额外字段…) 用户(personid引用person(personid)、用户名、加密密码、额外字段…) 如果需要的话,您还可以在后面创建聚合父类型和子类型的视图。 这种方法的一个缺陷是,如果您发现自己在大量搜索与特定父类型相关联的子类型。在我的头脑中没有一个简单的答案,您可以根据需要通过编程方式跟踪它,或者运行SOEM全局查询并缓存结果。它将真正取决于应用程序。 |
![]() |
8
3
我会说,根据区分人和特殊人的不同,您可能不希望此任务使用多态性。
我将创建一个用户表,一个对用户具有可以为空的外键字段的个人表(也就是说,这个人可以是一个用户,但不必是)。
|
![]() |
9
2
在我们的公司中,我们通过将所有字段组合在一个表中来处理多态性及其最糟的情况,并且不能强制执行引用完整性,而且很难理解模型。我肯定会反对这种做法。 我将使用每个子类的表,并避免性能受到影响,但是使用ORM,我们可以通过基于类型动态地构建查询来避免与所有子类表连接。上述策略适用于单记录级别的拉取,但对于批量更新或选择,您无法避免。 |
![]() |
10
1
是的,如果可能会有更多的类型,我也会考虑一个typeid和一个persontype表。但是,如果只有3个不应该是NEC。 |
![]() |
11
1
这是一篇老文章,但我想我会从概念、程序和性能的角度来考虑。
我要问的第一个问题是人、特殊人和用户之间的关系,以及某人是否可能成为
二者都
一个特殊的人和一个用户同时。或者,4种可能的组合中的任意一种(A+B、B+C、A+C或A+B+C)。如果该类作为值存储在
另一个使我倾向于单一表的因素是您对场景的描述。
而且,如果您关心安全问题,那么有一个名为
多年来,我主要考虑的仍然是在数据库外部和现实世界中考虑对象的重要性(以及可能的进化)。在这种情况下,所有类型的人都有跳动的心(我希望),而且可能彼此之间也有等级关系;因此,在我的脑海里,即使不是现在,我们可能需要用另一种方法来存储这种关系。这与这里的问题没有明确的关联,但它是对象关系表达式的另一个例子。到目前为止(7年后),你应该能够很好地了解你的决定是如何运作的。 |
![]() |
12
0
在过去,我完全按照您的建议做了这件事——为常见的东西准备一个Person表,然后为派生类链接SpecialPerson。但是,我认为,因为linq2sql希望在同一个表中有一个字段来指示差异。不过,我并没有太多地关注实体模型——这肯定允许使用其他方法。 |
![]() |
13
-1
就个人而言,我将把所有这些不同的用户类存储在一个表中。然后,您可以拥有一个存储“类型”值的字段,或者您可以通过填写哪些字段来暗示您要处理的是哪种类型的人。例如,如果userid为空,则此记录不是用户。 您可以使用一对一或无联接类型链接到其他表,但是在每个查询中,您都将添加额外的联接。 如果您决定沿着该路径走下去(它们称之为“每个层次结构的表”或“tph”),那么linq-to-sql也支持第一个方法。 |
![]() |
Schadre · C-plus编码错误 2 年前 |
![]() |
Nithin K · 即使类属性的类型正确,也会获取异常 2 年前 |
![]() |
amirreza870 · Python OOP-更改类文本 2 年前 |
![]() |
A_K · 使用cat或打印方法打印部分内容的子集闭包 2 年前 |
![]() |
Mo Fatah · 如何使用Python类打印数独板? 3 年前 |