1

我有一个包含三个字段的表UserCityCountry,其中一个字段必须始终为非NULL。我可以为此使用 SQL 约束还是应该重新考虑我在做什么?

场景是我的数据库应该包含可以附加到用户、城市或国家的文档。因此,此表中的一行恰好包含一个用户、城市或国家/地区的文档。但是,人们也应该能够搜索所有文档,而不管它已“附加”到哪个实体。

我不使用三个不同的表的原因是我想避免JOIN在所有三个地方搜索文档时都使用三个表。我想我在这里尝试使用的那种非规范化会提高性能,但我不确定。

想法?

4

5 回答 5

1

如果我理解正确,以下 SQL 应该添加您正在寻找的约束:

ALTER TABLE YourTableName
ADD CONSTRAINT CK_TestNullCount 
    CHECK (Case When [user] is NULL Then 0 Else 1 End 
           + Case When City Is NULL Then 0 Else 1 End 
           + Case When Country Is NULL Then 0 Else 1 End = 1)
于 2010-03-09T17:32:12.350 回答
0

将它们放在具有 LocationID、LocationName 和(如果需要)LocationType(用户、城市、国家)列的单个表 Locations 中。您只需要一个连接即可发现文档的“位置”,并且您不必担心选择哪个字段来获取位置的名称。

使用此技术,您可以使用简单的非空外键约束来强制执行“唯一一个”位置要求。

于 2010-03-09T17:07:04.193 回答
0

不确定您是否可以使用 CHECK CONSTRAINT 来做到这一点 - 我一直在玩,但最终似乎没有任何效果:-(

但是您始终可以在表上创建一个INSTEAD OF INSERT(可能还有一个INSTEAD OF UPDATE)触发器来检查这些条件,如果不满足,则使用 RAISERROR 引发异常,并且不会插入(或更新)该行。

于 2010-03-09T17:20:59.957 回答
0

我建议坚持使用 FK 方案。以下是我如何确保一个文档绑定到一个,并且只有一个DocumentType(你称之为附加到)。

这是一个非常简化的关系。我意识到您已经在 Document 表上获得了 3 列,但请考虑将其设为 FK。 替代文字

然后使用有效的值范围加载您的文档类型。

替代文字

插入数据时,您将写入类型为 varchar,而不是 int。这不应该导致性能问题,并将帮助您使用非规范化架构进行报告等。

替代文字

于 2010-03-09T17:23:45.347 回答
-1

为什么没有两列,一列称为 LocationId,一列称为 LocationTypeId。然后,您可以左连接到所有三个表:

SELECT COALESCE(User.Name, City.Name, Country.Name) 
FROM Location
INNER JOIN LocationType ON Location.LocationTypeId = LocationType.LocationTypeId
LEFT JOIN User ON Location.LocationId = User.Id AND Location.LocationTypeId = 1
LEFT JOIN City ON Location.LocationId = City.Id AND Location.LocationTypeId = 2
LEFT JOIN Country ON Location.LocationId = Country.Id AND Location.LocationTypeId = 3
于 2010-03-09T17:13:17.297 回答