1

我有一种情况,相同类型的两个对象具有不同类型的父对象。下面的伪代码最好地解释了这种情况:

TypeA a1, a2;
TypeB b;
TypeC c;
a1.Parent = b;
a2.Parent = c;

更复杂的是,TypeB 和 TypeC 可能具有不同类型的主键,例如,以下断言可能为真:

Assert(b.Id is string && c.Id is int);

我的问题是在 SQL Server 中定义这种父子关系的最佳方法是什么?我能想到的唯一解决方案是定义 TypeA 表有两列 - ParentId 和 ParentType,其中:

  • ParentId 是 sql_variant - 能够同时保存数字和字符串
  • ParentType 是字符串 - 保留父类型的程序集限定名称。

但是,当我基于 sql_variant 定义用户数据类型时,它将字段大小指定为固定的 8016 字节,这似乎是太多了。

必须有更好的方法。任何人?谢谢。

4

5 回答 5

12

一个字:不要

这是非常糟糕的做法 - 列有一个单一的数据类型是有原因的。不要滥用这个,把所有东西都变成变种......

马克

于 2009-05-13T14:36:09.390 回答
1

如果 NEITHER 列永远不会参与任何数学运算,请将它们设为 CHAR() 或 VARCHAR(),因为您将处理一系列字符,而不是数字。在这种情况下,“1”与“A”一样有效。

于 2009-05-13T14:39:51.520 回答
1

我不确定我是否完全理解您的情况,但在类似的情况下,我在 TableA 上创建了两列,一列存储字符串键,一列存储 int 键;最终它们都可以为 NULLable(但不在同一记录中)。

于 2009-05-13T14:43:27.770 回答
0

通过使用一列,您消除了设置外键关系的能力,从而引入了不良数据的可能性。您需要将每个表的键存储在不同的字段中,因为它们是表示不同事物的不同数据。将它们存储在一个列中将是一个非常糟糕的主意。

于 2009-05-13T14:53:56.193 回答
0

嗯,有两个问题。首先是 OO 设计,在您的模型中,TypeA 可以有不同类型的父级,而这些类型(TypeB 和 TypeC)没有共同的父级。显然,我不相信它会是真实的。但是我不知道这些类型的含义...如果从一些TypeX继承TypeB和TypeC就可以解决这个问题,这种情况下我将在TypeA中引用TypeX。

第二个是数据库设计。由于 OO 设计中的错误,您在 DB 端遇到问题。解决方案是一样的 - 为 TypeX 创建单独的表,并将 TypeA 和 TypeB 之间的所有公共属性放在那里,为 TypeA 和 TypeB 创建单独的表。TypeX 与 TypeA 以及 TypeB 的关系为 1:1。在这种情况下,TypeA 创建看起来是这样的——在 TypeX 中插入新行,获取 ID,在 TypeA 中插入行。在此解决方案中,您将在 TypeX 和 TypeA 或 TypeX 和 TypeB 中找到匹配的行。

TypeX(TypexID int not null primary key identity (1,1), SomeCommonColumn int) TypeA(TypexID int not null primary key, TypeASpecific int) TypeB(TypexID int not null primary key, TypeBSpecific varchar)

只有用关系理论来实现这种情况——清晰且非冗余的方式。它看起来不是很简单,但通常这些表由视图和存储过程覆盖,因此这些表可以被应用程序用作单个(虚拟)表。

谢谢你,亚历山大

于 2009-05-13T15:42:39.420 回答