2011-01-05 29 views
0

我真的很难知道将什么词语放入我的问题的标题中,因为我不确定是否存在与我的问题相关的数据库模式。我会尽量简化问题,直接解决问题的核心问题。我是否需要为这样一个简单的约束写一个触发器?

假设我有一些表格。 第一个是小部件类型的列表:

create table widget_types (
    widget_type_id number(7,0) primary key, 
    description varchar2(50) 
); 

下一个包含图标:

create table icons (
    icon_id number(7,0) primary key, 
    picture blob 
); 

即使得到了用户选择自己喜欢的小工具,有小部件的一个预定义子集他们可以从每个控件类型中进行选择。

create table icon_associations (
    widget_type_id number(7,0) references widget_types, 
    icon_id number(7,0) references icons, 
    primary key (widget_type_id, icon_id) 
); 

create table icon_prefs (
    user_id number(7,0) references users, 
    widget_type_id number(7,0), 
    icon_id number(7,0), 
    primary key (user_id, widget_type_id), 
    foreign key (widget_type_id, icon_id) references icon_associations 
); 

目前为止很简单。

现在让我们假设,如果我们正在向未设置其偏好设置的用户显示图标,则选择与当前窗口小部件关联的适当图像之一。我想指定首选的图标在这种情况下,显示了,这里就是我遇到我的问题:

alter table icon_associations 
    add (is_preferred char(1) check(is_preferred in ('y','n'))) 
; 

我不知道怎样才能强制执行,对于每个WIDGET_TYPE有一个且只有一行,is_preferred设置为'y'。

我知道在MySQL中,我能够在检查约束中编写子查询来快速解决此问题。这对于Oracle来说是不可能的。

是我的错误,这列没有任何业务在icon_associations表中?如果不是它应该去哪里?这是一种情况,在Oracle中,约束只能通过触发器来处理?

我只问,因为我想尽可能去约束路线。

非常感谢您的帮助, 保罗

回答

0

,我相信一个简单的方法来解决你的问题是有另一个表称为

icon_default_associations (widget_type_id, icon_id) 

,只是让(widget_type_id, icon_id)服从UNIQUE约束(或作它是主键)。

我想你会重载icon_associations的目的,如果你这样做你尝试的方式。

+0

但是,这只能防止创建多个首选图标(在指定图标的情况下)。我仍然可以指定图标而不将任何标记标记为首选。 – 2011-01-06 00:15:04

+0

就icon_associations的目的而言,我也有这种感觉。但是我也没有确信我已经过度扩张了。 – 2011-01-06 00:18:51

+0

如果你想确保所有图标都有1个且只有1个首选项,那么我认为最好在图标表中添加一个名为“default_widget_association”的列,并将其设置为NOT NULL。然后,您可以取消我建议的icon_default_associations表。您可能还想要重命名icon_associations表。 – kvista 2011-01-06 15:34:50

0

如果默认图标不更改,您可以确保默认图标首先进入icon_associations表吗?

这样,您总能保证只有一个默认图标,只要有图标,它就永远不会消失,而且您不需要使用is_preferred列或其约束和触发器。

这也将是很容易检索默认图标:

SELECT * from icon_associations WHERE ID=MIN(ID) 

的缺点是,更改默认图标将需要工作的一点点,但如果这不会发生,这能解决您的is_preferred列问题。

+0

这是一个聪明的解决方案。我没有足够的幸运有这样一个方便。 (我的问题比图标问题更复杂,但它们是相似的)。它确实让我觉得我可以有一个数字排名列,而不是二进制优先值。这意味着我不必推迟更新的限制。但它会使选择排名最好的图标更加困难。 – 2011-01-06 03:16:05

相关问题