简体   繁体   中英

Java web application & database design

I have developed a work flow web application in Java with an Oracle backend. The workflow requires the user to complete a series of checklists.
I started the project using 2 tables per checklist - one table to store the questions and another to store the answers.

But management keeps asking for more checklists so I changed my db approach (below). I'd like to know if this approach is good or I am setting myself up for trouble down the road. I am in the process of refactoring the whole application because it did not follow an MVC approach. Now is the time to correct any database deign issues.

Here is my new approach:

tables:

CHECKLIST_CLASS - store a type of checklist ie Quality Audit Checklist, Process Audit Checklist
CHECKLIST_INSTANCE - the users checklist being worked. store FK of the checklist_class_id, work_flow_id
CHECKLIST_ANSWER - stores the check_list_instance_id, FK of the question_id, multiple choice answer
CHECKLIST_QUESTION - stores the question_id, FK of the checklist_class_id

I like this approach because I can dynamically add a new check list without adding another db table.
but it makes queries a little complicated looking for determining the status of each checklist in the workflow.

 SELECT TO_CHAR(CALCDATEREQUIRED, 'MM/DD/YYYY') as CALCDATEREQUIRED, 
        TO_CHAR(CALCAPPROVEIPRDATE, 'MM/DD/YYYY') as CALCAPPROVEIPRDATE, 
        (SELECT SECTION_I_STATE FROM TPQOT_CALC_MODEL WHERE CHECKLIST_INSTANCE_ID = 
            SELECT MAX(TPQOT_CHECKLIST_INSTANCE.CHECKLIST_INSTANCE_ID) FROM TPQOT_CHECKLIST_INSTANCE 
            WHERE TPQOT_CHECKLIST_INSTANCE.CHECKLIST_CLASS_ID='1257877690209' AND 
            TPQOT_CHECKLIST_INSTANCE.CALC_ID=CALCID AND 
            TPQOT_CHECKLIST_INSTANCE.CALC_REV=CALCREV)  ) AS SECTION_I_STATE, 
        (SELECT CHECKLIST_STATE AS FINALIZE_CHECKLIST_STATUS FROM TPQOT_CHECKLIST_INSTANCE WHERE CHECKLIST_INSTANCE_ID = 
            (SELECT MAX(TPQOT_CHECKLIST_INSTANCE.CHECKLIST_INSTANCE_ID) FROM TPQOT_CHECKLIST_INSTANCE 
            WHERE TPQOT_CHECKLIST_INSTANCE.CHECKLIST_CLASS_ID='1257877690209' AND 
            TPQOT_CHECKLIST_INSTANCE.CALC_ID=CALCID AND 
            TPQOT_CHECKLIST_INSTANCE.CALC_REV=CALCREV)  ) AS DI4630901_STATE, 
        (SELECT CHECKLIST_STATE AS FINALIZE_CHECKLIST_STATUS FROM TPQOT_CHECKLIST_INSTANCE WHERE CHECKLIST_INSTANCE_ID = 
            (SELECT MAX(TPQOT_CHECKLIST_INSTANCE.CHECKLIST_INSTANCE_ID) FROM TPQOT_CHECKLIST_INSTANCE 
            WHERE TPQOT_CHECKLIST_INSTANCE.CHECKLIST_CLASS_ID='1257877670188' AND 
            TPQOT_CHECKLIST_INSTANCE.CALC_ID=CALCID AND 
            TPQOT_CHECKLIST_INSTANCE.CALC_REV=CALCREV)  ) AS OPC_STATE, 
        (SELECT phonebook.lname FROM phonebook WHERE phonebook.badge = xtbl463Calc.CalcOriginator) AS OrigName, 
        (SELECT phonebook.lname FROM phonebook WHERE phonebook.badge = xtbl463Calc.CalcChecker) AS CheckName, 
        (SELECT phonebook.lname FROM phonebook WHERE phonebook.badge = xtbl463Calc.CalcReviewer) AS ReviewName, 
        (SELECT phonebook.lname FROM phonebook WHERE phonebook.badge = xtbl463Calc.CalcApprover) AS ApproveName 
        FROM xtbl463Calc ORDER BY CALCID;

The result set for this query goes into an array list of hashmaps and sent to my view. Should I continue with this 4 table approach? Do I need to refactor my query? I think once I code all my javabean models representing the various checklists I can clean things up. I just want to feel like I am on the right path during this refactoring job.

I can't see much wrong with the table structure, if I understood your description correctly, it stores the structure it is supposed to store.

The query on the other hand does look way too complicated.

There are a lot of queries iwthin queries within queries which just can't be right. I can see three options open here:

  1. Check whether you need this query at all. Do you really have to display the detailed status of everything at the same time?
  2. Check whether you can simplify your query in some way, eliminate or merge parts of it, replace inner selects with joins, anything. There is considerable repetition in the query, so it can definitely be simplified.
  3. Break the query down into several smaller queries that are executed one after the other. For example, the phonebook part of the query can almost certainly be run separately from the main query.

With options 2 and 3 a sub-option is to consider the use of views.

And finally, there's the question of putting the result in a list of hashmaps. I obviously don't know the time constraints within which you're working but if you can afford the time, I'd strongly recommend creating POJOs for storing the results instead of putting them in a hashmap.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM