Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 超级类型表-是否可以进行多重继承?_Sql Server_Sql Server 2008_Supertype - Fatal编程技术网

Sql server 超级类型表-是否可以进行多重继承?

Sql server 超级类型表-是否可以进行多重继承?,sql-server,sql-server-2008,supertype,Sql Server,Sql Server 2008,Supertype,这个问题可能有一个简单的答案,这是一个标准的做法,或者没有答案,因为它不能做一个简单的原因,或者只是一个有趣的思维练习。我现在坐在最后一个选项上,但希望第一个 假设我想在数据模型中创建实体的“组”或“类”。通常,我会使用这样的超类型表: DrivableEntity ---------- ID (PK, auto-increment) Type (int or otherwise some kind of enum) Car ---------- ID (PK, FK to DrivableE

这个问题可能有一个简单的答案,这是一个标准的做法,或者没有答案,因为它不能做一个简单的原因,或者只是一个有趣的思维练习。我现在坐在最后一个选项上,但希望第一个

假设我想在数据模型中创建实体的“组”或“类”。通常,我会使用这样的超类型表:

DrivableEntity
----------
ID (PK, auto-increment)
Type (int or otherwise some kind of enum)

Car
----------
ID (PK, FK to DrivableEntity)
(car-specific fields)

Bike
----------
ID (PK, FK to DrivableEntity)
(bike-specific fields)
然后,对于每个子表,我的插入可能会经历外部看起来像普通CRUD过程的过程,但在内部插入到
DrivableEntity
中,然后使用范围标识插入到预期的表中

与其说是数据建模者,不如说是程序员,这让我想到了对象继承。对于直接继承来说,这很好。公共数据/任务可以抽象到一个级别,可以维护Liskov替换等。但是在数据模型中是否可以进行多重继承

我主要是一名C#开发人员,所以我开始考虑界面。如果我想公开“实现”了IDrivable和/或ITowable等的表,会怎么样?这样的事情可能吗?以前有人做过类似的事情吗?

大卫

实体框架能够使用继承。您可以使用POCO和EF来创建自己的接口,以提供对数据的访问

您所描述的情况并不是真正的多重继承,因为您只有一个基表/实体和一个派生表/实体。要在EF中对此进行建模,请创建一个基本实体,然后创建每个子实体。此时,您可以将每种类型的子实体属性映射到正确的表

话虽如此,插入/更新/删除逻辑将变得非常复杂。实体框架可能会遇到复杂模型的问题

我想问的问题是,你为什么要这样做?如果要在类型之间共享公共数据,我建议在服务器上创建视图,将父表与子表连接起来。它会快得多,并且您可以使用一个更简单的SQL来处理CUD(创建/更新/删除)操作,因为在数据访问和数据存储之间有一个明确的划分

这有意义吗


Erick

通常,数据模型的两种方法适用于您所描述的内容

您已经描述的模型是其中一种方法,其优点是非常“整洁”。如果表中有大量列,则该方法尤其有效,因此单个对象的大小不会变得太大或太宽

DrivableEntity
----------
ID (PK, auto-increment)
Type (int or otherwise some kind of enum)

Car
----------
ID (PK, FK to DrivableEntity)
(car-specific fields)

Bike
----------
ID (PK, FK to DrivableEntity)
(bike-specific fields)
另一种方法是使单个表中的所有列都可以为空,并用类型指示符标记每一行。这种方法可能会很快变得混乱,但对于简单的情况,开销要小得多

您可以在原始模型中建模继承或接口,只需将另一个外键列添加到“派生”实体之一。例如:

FlyableEntity
-------------
ID (PK)
... flyable attributes

FlyingCar (implements/inherits IDrivable and IFlyable)
-------------
DrivableEntityID (PK, FK)
FlyableEntityID (PK, FK)
... add flying car attributes

or:

FlyingCar (inherits from Car)
-------------
CarID (PK, FK)
FlyableEntityID (FK)
... add flying car attributes

您可以创建视图来解决此问题

可视可驾驶汽车
VIEWDRIVABLEBIKE
可视可视汽车

然后,使用并集将视图合并为超级视图,将可驾驶图元和可拖曳图元组合在一起。您只能包含这两个列中常见的列。类似但不同的名称需要规范化:

CREATE VIEW vrDiveTow
AS

SELECT
viewDriveableCar.CarId as ID,
... other attributes

UNION

SELECT
viewTowableCar.TowableId as ID,
... other attributes
UNION

一个大问题。SQL使用可以缓存的查询计划来生成结果。如果SQL的查询计划是围绕查询“七喜”而构建的,并且您正在筛选“可口可乐”,那么该查询计划将无效,并且实际会使用完整的表扫描。

可以使用子类型,但也不鼓励使用子类型。数据库是它们自己的世界,您不应该试图将OOP原则带入这个世界。许多人尝试过,许多人失败了。如果您试图用OOP术语来考虑数据库“对象”,那么您的数据库将受到影响

绝对不是我所希望的那种优雅的方法,但从逻辑上讲,它确实适合。我认为我真正想要做的只是在像SQLServer这样的关系模型中不可行。不过,这种方法可能对该项目仍然有用。谢谢我也有这种感觉。这背后的主要驱动力是,本项目对DAL的第一个要求是“它不能是ORM”。因此,试图在代码中驱动适当的OO原则将是一场艰苦的战斗。这一要求是完全正确的。无意冒犯,但从您的问题/评论中,我感觉到您对数据库不是很熟悉,而且您是被迫开发此解决方案的。您真的应该找一些数据库开发人员来为您设计数据库。