I am developing an application where a user submits a mission and other users accept the mission.
Pretty simple.
I want to keep a track of the mission progress status and store it into a database.
Which would be more appropriately:
1.having the following enums in a database column:
PRICE_NEGOTIATION,
DEPOSIT_NEGOTIATION,
MISSION_STARTED,
DEMO_RECEIVED,
DEMO_APPROVED,
DEMO_UNAPPROVED,
PAYMENT_DONE,
PAYMENT_PENDING,
PRICE_NEGOTIATION_UNAPPROVED_BY_CREATOR,
PRICE_NEGOTIATION_UNAPPROVED_BY_ACCEPTOR,
DEPOSIT_NEGOTIATION_UNAPPROVED_BY_CREATOR,
DEPOSIT_NEGOTIATION_UNAPPROVED_BY_ACCEPTOR,
MISSION_CANCELED_AFTER_START_BY_CREATOR,
MISSION_CANCELED_AFTER_START_BY_ACCEPTOR,
MISSION_CANCELED_AFTER_DEMO_UNAPPROVEMENT,
and so on..
- having more than one column in the database where one of them gives a cancel reason, another one that holds who canceled the mission and another one about the payment status.
any better suggestions?
10x in advance and sorry if the question is too much opinion based.
-
What are you trying to accomplish?ControlAltDel– ControlAltDel2015年06月03日 15:51:49 +00:00Commented Jun 3, 2015 at 15:51
-
3It would be option #26ton– 6ton2015年06月03日 15:52:03 +00:00Commented Jun 3, 2015 at 15:52
-
As i said i am trying to accomplish having a track about the progress of the missionJoro Seksa– Joro Seksa2015年06月03日 15:53:12 +00:00Commented Jun 3, 2015 at 15:53
-
Personally, I prefer the first one. In the second one, you will have NULL and business logic may be more complicated whether app grows.Héctor Valls– Héctor Valls2015年06月03日 15:53:54 +00:00Commented Jun 3, 2015 at 15:53
-
1I'm not entirely sure, but it looks like you might be combining two ideas into one enum. Can you separate the 2nd list into 2 or more smaller lists? ("UNAPPROVED_BY_CREATOR" is being repeated)Dan Pichelman– Dan Pichelman2015年06月03日 16:19:08 +00:00Commented Jun 3, 2015 at 16:19
2 Answers 2
I can see the redundancy in your enum, this should be two separate columns, each of which can be an enum:
enum for col1:
PRICE_NEGOTIATION,
DEPOSIT_NEGOTIATION,
MISSION_CANCELED
enum for col2:
UNAPPROVED_BY_CREATOR,
UNAPPROVED_BY_ACCEPTOR,
UNAPPROVED_BY_ACCEPTOR,
AFTER_START_BY_CREATOR,
AFTER_START_BY_ACCEPTOR,
AFTER_DEMO_UNAPPROVEMENT
You can even add a check constraint to ensure sane values between the two enum columns (assuming you're using a RDBMS that supports check constraints - hello MySQL... you listening?)
alter table ... add constraint enum_sanity_chk check (
case
when col1='PRICE_NEGOTIATION' then
col2 in (
'UNAPPROVED_BY_CREATOR',
'UNAPPROVED_BY_ACCEPTOR'
)
when col1='DEPOSIT_NEGOTIATION' then
col2 in (
'UNAPPROVED_BY_CREATOR',
'UNAPPROVED_BY_ACCEPTOR'
)
when col1='MISSION_CANCELED' then
col2 in (
'AFTER_START_BY_CREATOR',
'AFTER_START_BY_ACCEPTOR',
'AFTER_DEMO_UNAPPROVEMENT'
)
...
else
false -- col1 not matched to any expected enum
end
);
Let the database enforce all the rules between data. With the rules well defined at the lowest level, the rest of the system gains this assurance.
-
5You can further disambiguate CREATOR and ACCEPTOR.Robert Harvey– Robert Harvey2015年06月03日 16:45:12 +00:00Commented Jun 3, 2015 at 16:45
I think the way you want to split it into multiple enums is not bad, but it requires changes in DB.
It will also enable you to create a successful payment with cancel reason etc. When you have a single (huge) enum, it covers this logic by enumerating all allowed combinations. Without it, you either need some application logic or you allow the full carthesian multiplication of the enums.
Anyway, as enums can have fields and methods, you can just upgrade the existing enum. Add some private fields and getters in it and you can do something like this:
if (missionProgress.getPaymentStatus() == PaymentStatus.CANCEL) {...}
Anyway, if you don't have the application running on any customer's server yet (with tons of data already), I would advise not to use a huge enum like that.
-
i am currently developing it and have no data yet. So i need to take a decision :)Joro Seksa– Joro Seksa2015年06月03日 16:11:35 +00:00Commented Jun 3, 2015 at 16:11
-
It looks like you have some workflow with phases, their statuses and the reason or author of those statuses ... I think option #2 is way better in case you are creating a new app.Vlasec– Vlasec2015年06月04日 14:43:11 +00:00Commented Jun 4, 2015 at 14:43