有没有办法为数据库表的列强制执行一组值?

时间:2011-04-13 13:24:30

标签: sql sql-server database-design

我有一个表,在其中一个列中我将指定实体的类型。实体只能有三种类型 - 标题,图像或注释,因此我想确保表列只能接受这三个字符串中的一个。有没有办法将这个约束放在ms sql server 2008中?

编辑: - 添加了数据库图表以获得有关改进设计的提示。

设计: - 1)故事板有许多幻灯片,每张幻灯片可以有一个或多个标题或图像。

2)每个故事板可以有一个或多个作者,零个或多个评论者。

3)每个对象的图像,幻灯片和标题(可能更多的对象将在稍后出现,如音频等)可以对它们进行评论。这些评论可以由作者或评论者提供。 为了存储评论,我创建了一个评论表。

4)有必要记住幻灯片中幻灯片的顺序和图像的顺序,我正在使用幻灯片和图像编号字段。

5)由于可以对任何对象给出注释,我需要为每个对象都有一个全局ID,因为它们的引用将存储在注释表中。为了维护一个全局id,所有以name结尾的字段GID是使用Default:NEWID()生成的uniqueidentifier。

请建议对此数据库设计进行改进。

Database Diagram

4 个答案:

答案 0 :(得分:6)

这是检查约束的方法:

create table #tableWithConstrainedColumn (
    constrainThis varchar(20)
)

ALTER TABLE #tableWithConstrainedColumn ADD CONSTRAINT TempCheck
    CHECK (constrainThis in ('caption', 'image', 'comment'))

-- this statement will succeed
insert into #tableWithConstrainedColumn
select 'caption'
-- this statement will fail
insert into #tableWithConstrainedColumn
select 'captions'

drop table #tableWithConstrainedColumn

您也可以定义数据类型,但我不建议这样做:http://msdn.microsoft.com/en-us/library/aa933121(v=sql.80).aspx

正如@Widor刚推荐的那样,外键是最好的方法。

答案 1 :(得分:4)

听起来像Foreign Keys的工作?

答案 2 :(得分:1)

啊,啊哈,在这种情况下,问题的本质是不同的!因此我的第二个答案就在这里。

我承认我不能100%确定“最佳”解决方案是什么。我认为你打算如何查询这些数据将在一定程度上决定你存储它的方式。

根据您发布的额外信息,我建议您删除Comment表,以便存储有关评论的信息。丢失了ObjID, ObjType字段,可能还有usertype - 不应该在User表格中吗?

然后,我建议为您的架构添加三个新表:SlideCommentCaptionCommentImageComment,每个表只有两个字段:
一个用于存储CommentId(其中有一个FK到Comment表),另一个用于存储Slide-,Caption-或Image-GID。

因此,这些新表仅用于将Comment加入到他们所在的实体中。这应该使您能够以您想要的方式查询数据,而不必担心它引用的“实体”。

答案 3 :(得分:-1)

使用检查约束或触发BEFORE INSERT,UPDATE并将此验证编码到其中。