简体   繁体   English

从数据库中的预定义值列表中存储值的最佳方法是什么?

[英]What's the best way to store a value from a list of pre-defined values in a database?

Let's say I have a pre-defined list of values ( RW, FW, 4W ) representing drive type of a vehicle: 假设我有一个预定义的值列表( RW,FW,4W ),它们表示车辆的驾驶类型:

RW - Rear Wheel RW-后轮

FW - Front Wheet FW-前轮

4W - Four Wheel 4W-四轮

Now, I want to take a value from the above 3 values as an input from my user and then store it in a database. 现在,我想从上述3个值中取一个值作为用户的输入,然后将其存储在数据库中。

Upto my knowledge, I can perform this with the help of any of the following methods: 据我所知,我可以借助以下任何一种方法来执行此操作:

- Hard-code the values at the UI so that the UI shows a drop-down having only the above 3 values. -在用户界面上对值进行硬编码,以便用户界面显示仅包含上述3个值的下拉菜单。 Then store that value in the String vehicleType field of the Vehicle vehicle object and then store it in the DB as String . 然后将该值存储在Vehicle vehicle对象的String vehicleType字段中,然后将其作为String存储在DB中。

  • Cons: 缺点:

    i). 一世)。 No validation of the value at object level 没有在对象级别验证值

    ii). ii)。 No validation of the value at DB level. 没有在数据库级别验证该值。

    iii). iii)。 Though the need for adding a new value to the list is rare, but still user can't add a new value at runtime 尽管很少需要在列表中添加新值,但是用户仍然无法在运行时添加新值

    - Pros: -优点:

    i). 一世)。 No need of join at DB to retrieve the vehicle object 无需join DB即可检索vehicle对象

OR 要么

  • Make a separate table VEHICLE_TYPE in the DB having all the 3 values and link it with the VEHICLE table via. 在具有所有3个值的DB中创建一个单独的表VEHICLE_TYPE ,并通过将其与VEHICLE表链接。 foreign key. 外键。 And then populate the drop-down at UI from the VEHICLE_TYPE table. 然后在VEHICLE_TYPE表中的UI下拉列表中进行填充。 Store the value in the vehicle object as String 将值作为String存储在vehicle对象中

    - Cons: -缺点:

    i). 一世)。 No validation at object level 没有在对象级别进行验证

    ii). ii)。 Need a join at DB to retrieve a vehicle object 需要join在DB检索vehicle对象

    - Pros: -优点:

    i). 一世)。 validation of the value at DB level (by foreign key) 在数据库级别验证值(通过外键)

    ii). ii)。 User can add a new value to the list at runtime 用户可以在运行时将新值添加到列表中

OR 要么

  • Make a separate table VEHICLE_TYPE in the DB having all the 3 values but DON'T link it with the VEHICLE table via. 在DB中创建一个单独的表VEHICLE_TYPE ,该表具有所有3个值,但不要通过VEHICLE_TYPE将其链接到VEHICLE表。 foreign key. 外键。 And then populate the drop-down at UI from the VEHICLE_TYPE table. 然后在VEHICLE_TYPE表中的UI下拉列表中进行填充。 Store the value in the vehicle object and in the DB as String 将值存储为vehicle对象和DB中的String

    - Cons: -缺点:

    i). 一世)。 No validation at object level 没有在对象级别进行验证

    ii). ii)。 No validation at DB level 在数据库级别没有验证

    - Pros: -优点:

    i). 一世)。 No join required at DB level 在数据库级别无需join

    ii). ii)。 User can add new value to the list 用户可以将新值添加到列表中

OR 要么

  • Make a separate table VEHICLE_TYPE in the DB having all the 3 values and link it with the VEHICLE table via. 在具有所有3个值的DB中创建一个单独的表VEHICLE_TYPE ,并通过将其与VEHICLE表链接。 foreign key. 外键。 And then populate the drop-down at UI from the VEHICLE_TYPE table. 然后在VEHICLE_TYPE表中的UI下拉列表中进行填充。 Make an enum VehicleType in java and then add a field VehicleType vehicleType in the Vehicle class. 用Java enum VehicleType ,然后在Vehicle类中添加一个VehicleType vehicleType字段。 Store a value from the VehicleType enum in the vehicleType field based on the input of the user. 根据用户的输入,将VehicleType枚举中的值存储在vehicleType字段中。

    -Cons: -缺点:

    i). 一世)。 Will have to update the list at two places: VehicleType enum and the VEHICLE_TYPE table. 必须在两个位置更新列表: VehicleType枚举和VEHICLE_TYPE表。 May cause inconsistency. 可能导致不一致。

    ii). ii)。 User can't add a new value to the list (he can add a value in the table but can't change the enum) 用户无法向列表中添加新值(他可以在表中添加值,但不能更改枚举)

    - Pros: -优点:

    i). 一世)。 validation at UI level UI级别的验证

    ii). ii)。 validation at object level 在对象级别进行验证

    iii). iii)。 validation at DB level 在数据库级别进行验证

Question: Is there other way by which we can perform the above task which doesn't have any of the above disadvantages? 问题:我们是否可以通过其他方式执行上述任务,而没有上述缺点?

Sure. 当然。 Your second one with a modification: 您的第二个修改:

Make a separate table VEHICLE_TYPE in the DB having all the 3 values and link it with the VEHICLE table via. 在具有所有3个值的DB中创建一个单独的表VEHICLE_TYPE ,并通过将其与VEHICLE表链接。 foreign key. 外键。 And then populate the drop-down at UI from the VEHICLE_TYPE table. 然后在VEHICLE_TYPE表中的UI下拉列表中进行填充。 Store the value in the vehicle object as String . 将值作为String存储在车辆对象中。 When calling vehicle.setVehicleType() , verify that the value assigned is valid by checking the possible values from the DB. 调用vehicle.setVehicleType() ,通过检查数据库中可能的值来验证分配的值是否有效。 If it's invalid, throw an InvalidArgumentException or a subclass. 如果无效,则抛出InvalidArgumentException或子类。

Now you have validation in the object. 现在,您已经在对象中进行了验证。 And also, I don't consider having to do a join a con. 而且,我也不必考虑参加骗局。 You can't do much of anything without joining tables. 如果不加入表,您将无能为力。 That's why you have many tables. 这就是为什么您有很多表的原因。

I would chose also the second approach. 我也会选择第二种方法。 You have been already answered about the first con. 您已经获得有关第一个骗局的答复。

Regarding the second con, if performance is so important, you could use one of those approaches: 关于第二个缺点,如果性能是如此重要,则可以使用以下方法之一:

  1. If the type vehicle is not used much in the application, lazy loading the type of the vehicle. 如果在应用程序中不使用类型车辆,请延迟加载车辆类型。

  2. If you are not using database ids, because you are using the code of the type vehicle as primary key, you could add a codeType property to your vehicle class, and load this property instead of the type (which could also be loaded lazyly, depending on needs), directly from the vehicle table. 如果您没有使用数据库ID,因为您使用的是vehicle类型的代码作为主键,则可以向您的vehicle类添加一个codeType属性,然后加载该属性而不是type(也可以延迟加载,具体取决于(根据需要),直接从车辆表上获取。 Then you won't have any join. 这样,您将没有任何加入。

I don't feel that joins should be your cause for concern - you might well find that compromising the design to reduce the overhead of a JOIN is most likely going to be wasted effort. 我不认为联接应该引起您的关注,您很可能会发现,为了减少JOIN的开销而折衷设计可能很浪费时间。 Your network latency to the db could be higher than the JOIN overhead. 您到db的网络延迟可能高于JOIN开销。

How you deal with additional values entered by the user depends upon how you want them to be handled: 您如何处理用户输入的其他值取决于您希望如何处理它们:

  1. Treat them as true additional values. 将它们视为真正的附加值。 They are added to the VEHICLE_TYPE in the database, and once added, are available for all users to select. 它们将被添加到数据库中的VEHICLE_TYPE,并且一旦添加,便可供所有用户选择。

  2. Treat them as custom values for that particular field. 将它们视为该特定字段的自定义值。 Ie the VEHICLE_TYPE includes a type "Other" and the user can enter additional details in a separate field. 即VEHICLE_TYPE包含类型“其他”,用户可以在单独的字段中输入其他详细信息。 These are not shared with other users and do not appear in the dropdown list. 这些不会与其他用户共享,也不会出现在下拉列表中。

To get object-level validation, validate against the VEHICLE_TYPE. 要获得对象级验证,请针对VEHICLE_TYPE进行验证。 This can be done automatically with modern OIM and ORM frameworks. 这可以通过现代OIM和ORM框架自动完成。 These allow you to define validation rules on the model which are then propagated forward to the UI for early catching of validation errors, and backwards to the database to ensure data store consistency. 这些允许您在模型上定义验证规则,然后将其传播到UI以便尽早捕获验证错误,然后传播到数据库以确保数据存储的一致性。

You can store Vehicle ID as regular key, or the type string itself (RW,FW etc.). 您可以将“车辆ID”存储为常规键,也可以存储类型字符串本身(RW,FW等)。 If using the type string itself, you don't have to join to the VEHICLE_TYPE table. 如果使用类型字符串本身,则不必加入VEHICLE_TYPE表。 You could present the string directly, or you can fetch the presentation strings from resource bundles if localization is needed. 您可以直接显示字符串,或者如果需要本地化,则可以从资源包中获取显示字符串。

EDIT: To see how ORM and OIM can take model validation metadata back to the db and out to the UI, see DZone: Hibernate 4 Validation , and Metawidget . 编辑:要查看ORM和OIM如何将模型验证元数据带回db并返回到UI,请参见DZone: Hibernate 4 ValidationMetawidget With JSR 303 you can validate your objects in the UI, business layer and back end. 使用JSR 303,您可以在UI,业务层和后端中验证对象。

Make a separate table Vehicle_type (Vehicle_type_id int, description varchar (you need to determine the appropraite size))to use as the lookup for the drop down menu. 制作一个单独的表Vehicle_type(Vehicle_type_id int,描述varchar(您需要确定适当的大小)),以用作下拉菜单的查找。 If you want the value to change in the main table when the look up changes (say an adimin changes seden to sedan), then store the typeid in the vehicle table. 如果您希望在查找更改时在主表中更改该值(例如将adimin从seden更改为sedan),则将typeid存储在车辆表中。 If you want this to be historical data (maybe there is no longer a type sedan but older vehicles should still be marked as sedan) then store the decription of the type in the vehicle table. 如果您希望将其用作历史数据(也许不再有类型的轿车,但仍应将较旧的车辆标记为轿车),则将类型的描述存储在车辆表中。 In the second case you can't enforce with an FK relationship, so you will need to ensure that inserts (and updates of that value only) cannot choose values not currently in the table. 在第二种情况下,您不能使用FK关系强制实施,因此您需要确保插入(和仅更新该值)不能选择表中当前不存在的值。 The application will likely do this although you could write a trigger to do so if values are likely to change outside the application. 应用程序可能会执行此操作,但是如果值可能会在应用程序外部更改,则可以编写触发器来执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有没有办法使用Spring Data的CrudRepository#save()方法保存带有预定义@EmbeddedId值的@Entity? - Is there a way to save an @Entity with pre-defined @EmbeddedId value using Spring Data's CrudRepository#save() method? 如果不在预定义目录中,如何防止(以编程方式)启动Java应用程序? - how to prevent (programmatically) a java application from starting if it's not in a pre-defined directory? 将通用列表存储在 Map 值中的最佳方法是什么? - What is the best way to store a generic List in a Map value? 用户可以更新预定义的数据库吗? Android Studio - Can Pre-Defined Database be Updated by User? Android Studio 如何在Java中将预定义值添加到Pair Hashmap - How to add pre-defined values to Pair Hashmap in Java 什么是从数据库存储和检索数据的最佳方法 - What is the best way to store and retrieve data from database 使用预定义方法将负整数转换为十六进制值 - Converting negative integer to hex value using pre-defined methods 从主要包含空值的可比较数据列表中获取最小值和最大值的最佳方法是什么? - What is the best way to get min and max value from a list of Comparables that main contain null values? 在数据库中存储堆栈跟踪的最佳方法是什么 - What is the best way to store stacktrace in database 使用Java从数据库读取UDT的最佳方法是什么? - What's the best way to read a UDT from a database with Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM