开发者

Handling custom user fields with possibility of grow and shrink

This question is much about how to do, idea etc.

I have a situation where a user can create as man开发者_运维百科y custom fields as he can of type Number, Text, or Date, and use this to make a form. I have to make/design some table model which can handle and store the value so that query can be done on these values once saved.

Previously I have hard coded the format for 25 user defined fields (UDF). I make a table with 25 column with 10 Number, 10 Text, and 5 Date type and store the label in it if a user makes use of any field. Then map it to other table which has same format and store the value. Mapping is done to know which field is having what label but this is not an efficient way, I hope.

Any suggestion would be appreciated.

Users have permissions for creating any number of UDF of the above types. then it can be used to make forms again this is also N numbers and have to save the data for each form types.

e.g. let's say a user created 10 number 10 date and 10 text fields used first 5 of each to make form1 and all 10 to make form2 now saved the data.

My thoughts on it:

Make a table1 with [id,name(as UDF_xxx where xxx is data type),UserLabel ]

table2 to map form and table1 [id(f_key table1_id), F_id(form id)]

and make 1 table of each data type as [ id(f_key of table1),F_id(form number),R_id(row id for data, would be same for all data type),value]

Thanks to all I'm going to implement, it both DataSet entry and json approach looks good as it gives wider extension-ability. Still I've to figure out which will best fit with the existing format.


There are two approaches I have used.

  1. XML: To create a dynamic user attribute, you may use XML. This XML will be stores in a clob column - say, user_attributes. Store the entire user-data in XML key-value pair, with type as an attribute or another field. This will give you maximum freedom.

    You can use XOM or any other XML object Model API to display or operate on the data. A typical Node will look like

    <userdata>
      ...
      ...
      <datanode>
        <key type="Date">User Birth</key>
        <value>1994-02-25</value>
      </datanode>
      ...
    </userdata>
    
  2. Attribute-AttributeValue This is same thing as above but using tables. What you do is you create a table -- attributes with FK as user_id, another table attribute_values with FK as attribute_id.

    attributes contains multiple field-names and types for each user and attribute_values contains values of those attributes. so basically,

    users
      user_id
    
    attributes
      attr_id
      user_id (FK)
      attr_type
      attr_name
    
    attribute_values
      attr_val_id
      attr_id (FK)
      attr_val
    

If you see in both the approached you are not limited by how-many or what type of data you have. But there is a down-side of this is parsing. In either of the case, you will have to to do a small amount of processing to display or analyze the data.

The best of both worlds (having rigid column structure vs having completely dynamic data) approach is to have a users table with must-have columns (like user_name, age, sex, address etc) and have user-created data (like favorite pet house etc.) in either XML or attribute-attribute_value.


What do you want to achieve? A table per form permutation or might each dataset consist of different sets?

Two possibilities pop into my mind:

  1. Create a table that describes one field of a dataset, i.e. the key might be dataset id + field id and additional columns could contain the value stored as a string and the type of that value (i.e. number, string, boolean, etc.).

    That way each dataset might be different but upon reading a dataset and storing it into an object you could create the appropriate value types (Integer, Double, String, Boolean etc.)

  2. Create a table per form, using some naimg convention. When the form layout is changed, execute ALTER TABLE statements to add, remove, rename columns or change their type. When the user changes the type of a column or deletes it, you might need to either deny that if the values are not null or at least ask the user if she's willing to drop values that don't match the new requirements.


Edit: Example for approach 1

Table UDF //describes the available fields
--------
id (PK)
user_id (FK)
type
name

Table FORM //describes a form's general attributes
--------
id (PK)
user_id (FK)
name
description

Table FORM_LAYOUT //describes a form's field layout
--------
form_id (FK)
udf_id (FK)
mapping //mapping info like column index, form field name etc.

Table DATASET_ENTRY //describes one entry of a dataset, i.e. the value of one UDF in
--------
id (PK)
row_id
form_id (FK)
udf_id (FK)
value



Selecting the content for a specific form might then be done like this:
SELECT e.value, f.type, l.mapping from DATASET_ENTRY e
JOIN UDF f ON e.udf_id = f.id
JOIN FORM_LAYOUT l ON e.form_id = l.form_id AND e.udf_id = l.udf_id
WHERE e.row_id = ? AND e.form_id = ?


Create a table which manages which fields exist. Then create tables for each data type you want to support, where the user will their values into.

create table Fields(
  fieldid int not null,
  fieldname text not null,
  fieldtype int not null
);

create table FieldDate
(
   ValueId int not null,
   fieldid int not null,
   value date
);

create table FieldNumber
(
   ValueId int not null,
   fieldid int not null,
   value number
);

..

Another possibility would be to use ALTER TABLE to create custom fields. If your application has the rights to perform this command and the custom fields are changing very rarely this would be the option I chose.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜