2011-01-05 27 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

相關問題