sql-server - 可选列中的空值

标签 sql-server database-design

假设我有一个 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/

相关文章:

database-design - 电子邮件滴灌应用程序的数据库模式?

sql - 比较 SQL 中的 int 和 varchar 列

sql-server - 找不到证书

sql-server - Weka如何连接到MSSQL服务器

mysql - 每个项目的附加查询?

database-design - 是否需要有一个序列生成的主键,即使我可能不会将它用于数据库操作

mysql - 我应该将整个站点放在一个数据库中还是拆分为两个数据库?

sql-server - 在 SQL Server 中使用开始/结束 block 和 Go 关键字?

sql-server - 如何创建一个始终返回传递给其 WHERE 子句的值的表(或其他对象),如镜像

php - 错误 (150) - 设计基本关系数据库时遇到问题