2013-06-29 21 views
3

我想限制字段中的輸入錯誤。我正在建設的網站包含汽車數據。如何避免在一個字段中輸入互斥數據mysql

汽車可以有一個列表中的多個設備(空調,ABS,真皮座椅等),並且我想以某種方式防止數據輸入出錯,或者至少使其最小化。

錯誤的第一種情況是當數據輸入2個或更多互斥設備時。例如,汽車不能具有手動空調和自動空調以及自動空調雙區域。汽車中只有一種可以存在。

錯誤的第二種情況是當沒有先決條件的設備輸入數據時。例如,進入緊急制動輔助(BA)而沒有所需的ABS。一輛汽車可以沒有BA的ABS ,但BA只會存在於ABS汽車中。

輸入數據的表格很簡單。每輛車(version_id)都有多個設備(修剪)或trim_ids。 Version_id和trim_id分別是表格版本和修剪的FK。所以在table versiontrim中已經處理了不存在的trim_id或version_id的錯誤。

表versiontrim(在這裏我希望儘量減少數據錯誤)

version_id trim_id 

表修剪:

trim_id trim trimtype 

表版本

version_id model_id version active bodytype places motor_id etc... 

我明白任何幫助。

+1

與數據混合業務需求......這種事情應該由GUI應用程序或應用服務器,數據庫不是你 – Hawili

+1

可以使用存儲過程來插入數據,而不是直接訪問表,在這種情況下,你可以做任何處理在實際插入之前檢查或插入任何先決條件 – Hawili

+0

謝謝Hawili。我只是想着你的第一條評論。在某種程度上,數據庫中的所有內容都是由業務需求驅動的,在特定情況下,它與數據的一致性有關。按照存儲過程,我仍然需要介紹它。將檢查出來。 – BernardA

回答

1
For each selected trim, 
    Retrieve the set of mutually exclusive trims. 
    Check if any of those are also selected. 
    Retrieve the set of prerequisite trims. 
    Check that each of those are also selected. 
create table prerequisites (
    trim_id1 int not null references trims (trim_id), 
    trim_id2 int not null references trims (trim_id), 
    primary key (trim_id1, trim_id2) 
); 

create table exclusives (
    exclusive_group int not null, 
    trim_id int not null references trims (trim_id), 
    primary key (exclusive_group, trim_id), 
    index (trim_id, exclusive_group) 
); 

-- Retrieve all prerequisites of selected trims 
select p.trim_id1, p.trim_id2 
from versions v 
inner join versiontrim vt on vt.version_id = v.version_id 
inner join prerequisites p on p.trim_id1 = vt.trim_id 
where v.version_id = ?; 

-- Retrieve all mutually exclusive trims of selected trims 
select vt.trim_id as trim_id1, e2.trim_id as trim_id2 
from versions v 
inner join versiontrim vt on vt.version_id = v.version_id 
inner join exclusives e1 on e1.trim_id = vt.trim_id 
inner join exclusives e2 on e2.exclusive_group = e1.exclusive_group 
where e1.trim_id <> e2.trim_id 
and v.version_id = ?; 

你可能會進一步採取這一步驟,直接返回衝突:

-- Retrieve any missing prerequisites of the selected trims 
select p.trim_id1, p.trim_id2 
from versions v 
inner join versiontrim vt1 on vt1.version_id = v.version_id 
inner join prerequisites p on p.trim_id1 = vt1.trim_id 
left join versiontrim vt2 
    on vt2.version_id = v.version_id 
    and vt2.trim_id = p.trim_id2 
where vt2.version_id is null 
and v.version_id = ?; 

-- Retrieve any selected mutually exclusive trims 
select vt.trim_id as trim_id1, e2.trim_id as trim_id2 
from versions v 
inner join versiontrim vt on vt.version_id = v.version_id 
inner join exclusives e1 on e1.trim_id = vt.trim_id 
inner join exclusives e2 on e2.exclusive_group = e1.exclusive_group 
inner join versiontrim vt2 on vt2.version_id = v.version_id 
where e1.trim_id <> e2.trim_id 
and vt2.trim_id = e2.trim_id 
and v.version_id = ?; 
+0

感謝Markus。這解決了我的問題。我做在查詢一些小的調整,作爲[版本]表是不相關的,我之後的信息(我需要知道哪些VERSION_ID有不一致和由表中給出[versiontrim]。另外,在VERSION_ID加場查詢字段(同樣,這就是我期待的)和結尾。最後的WHERE子句中刪除它,它重要領域的表先決條件的順序取決於再次/ prerequisite.Thanks能想出解決方案,不是哲學的東西 – BernardA

0

如果你想這些依賴於數據庫級別車型,你應該把這些選項中的每一個都是獨特的實體。

由於您當前的結構建模了N-N關係,因此它還允許將相同的選項多次連接到給定的version。對於所有選項,您應該採取與以下相同的方法。

相互排斥的選項構成了選項的「類型」。例如,您描述的空調選項是「空調類型」。

爲此,創建一個新的實體(如aircond_type):

 

aircond_type: 
    +----+-----------+ 
    | id | label  | 
    +----+-----------+ 
    | 1 |  none | 
    +----+-----------+ 
    | 2 | manual | 
    +----+-----------+ 
    | 3 | automatic | 
    +----+-----------+ 
    | 4 | bi-zone | 
    +----+-----------+ 

然後在versions這個新表中添加外鍵。

至於相互依賴的選項,表達依賴關係的關係方式是外鍵約束。這意味着謂詞版「X有選擇BA」依賴「版本X有選擇ABS」,這意味着模擬在自己的表中的每個謂詞,這兩個之間的外鍵約束:

CREATE TABLE version_has_abs (
    version_id INT NOT NULL PRIMARY KEY, 
    CONSTRAINT version_fk FOREIGN KEY version_fk_idx(version_id) 
     REFERENCES version(version_id) 
); 

CREATE TABLE version_has_ba (
    version_id INT NOT NULL PRIMARY KEY, 
    CONSTRAINT version_fk FOREIGN KEY version_fk_idx(version_id) 
     REFERENCES version_has_abs(version_id) 
); 

這顯然是不切實際,或者至少不靈活。一個簡單的驗證觸發器可以進行檢查,並在沒有「ABS」選項的情況下阻止「BA」選項的歸屬。

另外,對於這個簡單的1-1的依賴,你可以治療「BA」選項爲「ABS」選項的變化。這樣你就可以有三種「制動」選項:「標準」,「ABS」,「帶BA的ABS」。

+0

感謝RandomSeed只是爲了對同一個選項附加同一個選項的同一個選項的評論,我沒有提到表version version的主鍵是字段version_id和trim_id,所以重複不會發生。其餘的我需要睡一會兒。 – BernardA

相關問題