2010-06-22 14 views
4

比方說,我有值(RW,FW,4W)表示車輛的驅動方式的一個預先定義的列表:從數據庫中的預定義值列表中存儲值的最佳方式是什麼?

RW - 後輪

FW - 前Wheet

4W - 四輪

現在,我想借此從上面的3個值的值從我的用戶,然後將一個輸入存儲它在一個數據庫中。

高達我的知識,我可以用下列任何一種方法的幫助下進行的:

- 硬編碼在UI中的值,使得UI僅顯示有一個下拉以上3個值。然後將該值存儲在Vehicle vehicle對象的String vehicleType字段中,然後將其作爲String存儲在數據庫中。

  • 缺點:

    i)中。 ii)沒有驗證物體水平的值

    ii)。沒有驗證數據庫級別的值。 iii)。雖然需要增加一個新的值到列表中是罕見的,但還是用戶不能在運行時

    添加一個新值 - 優點:

    我)。在DB不需要的join檢索vehicle對象

OR

  • 製作一個單獨的表VEHICLE_TYPE在具備全部3個值的數據塊,並通過VEHICLE錶鏈接。外鍵。然後從VEHICLE_TYPE表中填充UI的下拉列表。存儲在vehicle對象的值作爲String

    - 缺點:

    我)。在目標層面沒有驗證

    ii)。需要join在DB檢索vehicle對象

    - 優點:

    我)。數據庫級別的值驗證(通過外鍵)

    ii)。用戶可以在運行時一個新值添加到列表中

OR

  • 製作一個單獨的表VEHICLE_TYPE在具備全部3個值的DB但請勿鏈接它與VEHICLE表格通過。外鍵。然後從VEHICLE_TYPE表中填充UI的下拉列表。存儲在vehicle對象,並在DB值作爲String

    - 缺點:

    我)。在目標層面沒有驗證

    ii)。沒有驗證在DB級別

    - 優點:

    我)。在數據庫層面需要join

    ii)。用戶可以添加新的值列表

OR

  • 製作一個單獨的表VEHICLE_TYPE在具備全部3個值的數據塊,並通過VEHICLE錶鏈接。外鍵。然後從VEHICLE_TYPE表中填充UI的下拉列表。在java中創建一個enum VehicleType,然後在Vehicle類中添加一個字段VehicleType vehicleType。根據用戶的輸入,將VehicleType enum中的值存儲在vehicleType字段中。

    -Cons:

    我)。將不得不在兩個地方更新列表:VehicleType enum和VEHICLE_TYPE表。可能會導致不一致。 ㈡)。用戶不能將新值添加到列表(他可以在表中添加值,但不能改變枚舉)

    - 優點:

    我)。在UI層面驗證

    ii)。對象層面的驗證

    iii)。在DB級驗證

問: 是否有其他途徑,使我們可以執行不具有任何上述缺點的上述任務?

+1

你爲什麼擔心加入?除非您的應用程序使用量很大,否則不太可能成爲真正的性能問題。在特殊情況下,當您的應用程序出現加載問題時(這是一個很好的問題!),您需要擔心這種類型的問題。 – 2010-06-22 14:33:38

回答

2

當然。您的第二個修改:

在DB中創建一個單獨的表VEHICLE_TYPE具有所有3個值並通過VEHICLE表將其鏈接到表。外鍵。然後從VEHICLE_TYPE表中填充UI的下拉列表。將車輛對象中的值存儲爲String。當致電vehicle.setVehicleType()時,通過檢查數據庫中的可能值來驗證分配的值是否有效。如果它無效,則拋出一個InvalidArgumentException或一個子類。

現在您已驗證對象。而且,我不認爲必須加入一個騙局。如果不加入表格,你無法做任何事情。這就是爲什麼你有很多表。

+0

是的,'join'不是一個con,除非我們需要檢索大量的數據,而性能是我們主要關心的。在我的情況下,我需要檢索大量的數據,並且在DB中已經有了各種需要加入的表,所以我儘量避免「加入」。 – 2010-06-22 15:30:34

1

我會選擇第二種方法。你已經回答了第一個問題。

關於第二個騙子,如果性能是非常重要的,你可以使用這些方法之一:

  1. 如果應用程序,延遲加載車輛的類型車輛的類型,不使用太多。

  2. 如果您沒有使用數據庫ID,因爲您使用的車輛類型的代碼作爲主鍵,您可以添加codeType屬性到您的車輛類,並加載此屬性,而不是類型(也可以可以根據需要慢慢裝載),直接從車輛表中取出。那麼你將不會有任何加入。

1

我不認爲加入應該是你引起人們的關注 - 你可能會發現,影響設計,以減少的連接是最有可能會是無用功的開銷。您的網絡延遲到數據庫可能會高於JOIN開銷。

你如何處理用戶輸入的附加價值取決於你如何希望他們來處理:

  1. 把他們當作真正的附加價值。它們被添加到數據庫中的VEHICLE_TYPE中,並且一旦添加,所有用戶都可以選擇。

  2. 將它們視爲該特定字段的自定義值。即VEHICLE_TYPE包含「其他」類型,用戶可以在單獨的字段中輸入其他詳細信息。這些不會與其他用戶共享,也不會顯示在下拉列表中。

要獲得對象級驗證,請針對VEHICLE_TYPE進行驗證。這可以通過現代的OIM和ORM框架自動完成。這些允許您在模型上定義驗證規則,然後將這些驗證規則傳播到UI,以便儘早捕獲驗證錯誤,並向後傳遞到數據庫以確保數據存儲的一致性。

您可以將車輛ID存儲爲常規鑰匙或類型字符串本身(RW,FW等)。如果使用類型字符串本身,則不必連接到VEHICLE_TYPE表。您可以直接顯示字符串,或者如果需要本地化,則可以從資源包中獲取演示文稿字符串。

編輯:要查看ORM和OIM如何將模型驗證元數據帶回到數據庫並轉到UI,請參閱DZone:Hibernate 4 ValidationMetawidget。藉助JSR 303,您可以驗證UI,業務層和後端中的對象。

+0

首先,您能否詳細說明我們如何使用ORM進行對象級驗證?其次,我想你想在第1點而不是'VEHICLE_TABLE'說'VEHICLE_TYPE'。對? – 2010-06-23 04:52:21

1

製作一個單獨的表Vehicle_type(Vehicle_type_id int,description varchar(您需要確定appropraite大小))用作下拉菜單的查找。如果你希望當查詢改變時(例如adimin將seden改爲sedan)在主表中改變值,則將typeid存儲在車輛表中。如果您希望這是歷史數據(也許不再是一款轎車,但較舊的車輛仍應標記爲轎車),然後將類型的描述存儲在車輛表中。在第二種情況下,您無法強制使用FK關係,因此您需要確保插入(僅限於該值的更新)不能選擇當前不在表中的值。應用程序可能會這樣做,但如果值可能會在應用程序之外更改,則可以編寫觸發器來執行此操作。

相關問題