假设我有一个 Table1,包含三列:ID(主键、身份)、A 和 B
现在,假设我有 3 种方法,假设它们在列方面没有任何共同之处:
方法一:C、D、E
方法2:F、G、H、I
方法三:J
我可以制作一张 table : ID、A、B、C、D、E、F、G、H、I、J、M
其中 M 是方法的名称(或方法 ID)。
但是,如果 90% 的时间都使用方法 3,则会出现很多空值。
这是一个问题吗?如果是这样,有没有更好的方法来设置?
如果我将每个方法设为自己的表实体,如何确保每个 ID 都有一个与之匹配的方法?
如果我将其保留为一张表,如何确保仅填写 C、D、E,并且如果 M 为 1,则 F 到 J 均为 NULL?
好吧,似乎有些人很难进行抽象思考,所以我将创建一个应用上述内容的随机具体示例:
假设我有人们进行锻炼的记录。
每条记录始终都有一个 ID(用于唯一标识事件)、TIME_STARTED 和 TIME_ENDED。
但是,根据他们进行的练习,需要不同的属性。假设只有三个练习:
椭圆机:坡度、水平、速度
仰卧起坐:User_Weight、次数、延迟、Extra_Weight
硬拉:Weight_Lifted
对于每个 ID 只能有一种“方法”。应用此,请参阅上面的问题。
最佳答案
听起来你有一个 supertype/subtype这里的情况。在本例中,Table1 保存您的父类(super class)型,并且您需要创建一个不同的表来保存每个子类型。这些子类型表上的 PK 也将是父类(super class)型表的 FK。所以你会得到这样的东西:
Supertype_table
| ID(PK) | A | B |
Subtype1_table
| ID(PK&FK) | C | D | E |
Subtype2_table
| ID(PK&FK) | F | G | H | I |
Subtype3_table
| ID(PK&FK) | J |
此架构的要点是确保您没有一堆大部分为空的行。对于每种方法,您必须编写一个单独的查询来插入/更新相应的表。使用 SQL Server,您可以创建一个组合所有这些表并抽象出任何联接的 View :
CREATE VIEW MyView
SELECT Super.ID, Super.A, Super.B,
Sub1.C, Sub1.D, Sub1.E,
Sub2.F, Sub2.G, Sub2.H, Sub2.I,
Sub3.J
FROM Supertype_table as Super
LEFT OUTER JOIN Subtype1_table as Sub1 on Super.ID = Sub1.ID
LEFT OUTER JOIN Subtype2_table as Sub2 on Super.ID = Sub2.ID
LEFT OUTER JOIN Subtype3_table as Sub3 on Super.ID = Sub3.ID
那么你可以这样写:
SELECT ID, A, B, J
FROM MyView
WHERE J is not null
编辑:OP的评论
为了确保每个 ID 都在一个且唯一的一个表中,您需要在父类(super class)型表上使用某种标识符。因此,如果您有一个名为 TypeID 的列,您将创建以下函数:
CREATE FUNCTION [dbo].[SubtypeofSuperID](@ID int)
RETURNS int
AS
BEGIN
DECLARE @TypeID int;
SELECT @TypeID = TypeID
FROM Supertype_table
WHERE ID = @ID
RETURN @TypeID
END
然后,使用它,您可以对每个子类型表创建检查:
ALTER TABLE Subtype1_table CONSTRAINT [CK_CorrectSubtype1]
CHECK ( [dbo].[SubtypeofSuperID]([ID]) = 1 )
ALTER TABLE Subtype2_table CONSTRAINT [CK_CorrectSubtype2]
CHECK ( [dbo].[SubtypeofSuperID]([ID]) = 2 )
ALTER TABLE Subtype3_table CONSTRAINT [CK_CorrectSubtype3]
CHECK ( [dbo].[SubtypeofSuperID]([ID]) = 3 )
关于sql-server - 可选列中的空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11056494/