我有两种相同类型的对象具有不同类型的父对象的情况。 以下伪代码最好地解释了这种情况:
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,其中:
但是,当我根据sql_variant定义用户数据类型时,它将字段大小指定为固定的8016字节,这似乎很多。
必须有更好的方法。任何人? 感谢。
答案 0 :(得分:12)
一个字:不要
这是非常糟糕的做法 - 列有 ONE SINGLE DATATYPE 是有原因的。不要滥用这个并将一切变成变种.......
马克
答案 1 :(得分:1)
如果NEITHER列将参与任何数学运算,请将它们设为CHAR()或VARCHAR(),因为您将处理一系列字符,而不是数字。在这种情况下,'1'与'A'一样有效。
答案 2 :(得分:1)
我不确定我是否完全理解你的情况,但在类似的情况下我在TableA上创建了两列,一列用于存储字符串键,另一列用于存储int键;最终它们可能都是NULLable(但不在同一记录中)。
答案 3 :(得分:0)
通过使用一列,您可以消除设置外键关系的能力,从而引入不良数据的可能性。您需要将每个表的密钥存储在不同的字段中,因为它们是不同的数据,意味着不同的东西。将它们存储在一列中是一个非常糟糕的主意。
答案 4 :(得分:0)
嗯,有两个问题。首先是OO设计,在你的模型中,TypeA可以有不同类型的父类,这些类型(TypeB和TypeC)没有共同的父类。显然,我不相信它可以是真实的。但我不知道这些类型的含义......如果从某些TypeX继承TypeB和TypeC,这个问题就可以解决了,在这种情况下,我将引用TypeA中的TypeX。
第二个是数据库设计。由于OO设计中的错误,您在DB端遇到问题。解决方案是相同的 - 为TypeX创建单独的表,并在TypeA和TypeB之间放置所有公共属性,为TypeA和TypeB创建单独的表。 TypeX将TypeA与1:1和TypeB相关。 在这种情况下,TypeA创建以这种方式查找 - 在TypeX中插入新行,获取ID,在TypeA中插入行。在此解决方案中,您将在TypeX和TypeA或TypeX和TypeB中匹配行。
TypeX(TypexID int not null主键标识(1,1),SomeCommonColumn int) TypeA(TypexID int非null主键,TypeASpecific int) TypeB(TypexID int非null主键,TypeBSpecific varchar)
这是以关系理论 - 明确和非冗余的方式实现这种情况的唯一方法。它看起来不是很简单,但通常这些表由视图和存储过程覆盖,因此应用程序可以将这些表用作单个(虚拟)表。
谢谢你, 亚历山大