One Enum vs Enum multipli

1

Sto sviluppando un'applicazione in cui un utente invia una missione e altri utenti accettano la missione.

Molto semplice.

Voglio tenere traccia dello stato di avanzamento della missione e memorizzarlo in un database.

Quale sarebbe più appropriatamente:

1.avere le seguenti enumerazioni in una colonna del database:

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,

e così via ..

  1. avere più di una colonna nel database in cui una di esse fornisce un motivo di annullamento, un'altra che contiene chi ha annullato la missione e un'altra sullo stato del pagamento.

suggerimenti migliori?

10 volte in anticipo e scusa se la domanda è troppo basata sull'opinione.

    
posta Papa-rapa-beo 03.06.2015 - 18:15
fonte

2 risposte

3

Riesco a vedere la ridondanza nel tuo enum, questo dovrebbe essere due colonne separate, ognuna delle quali può essere un enum:

enum per col1:

PRICE_NEGOTIATION,
DEPOSIT_NEGOTIATION,
MISSION_CANCELED

enum per col2:

UNAPPROVED_BY_CREATOR,
UNAPPROVED_BY_ACCEPTOR, 
UNAPPROVED_BY_ACCEPTOR, 
AFTER_START_BY_CREATOR,
AFTER_START_BY_ACCEPTOR,
AFTER_DEMO_UNAPPROVEMENT

Puoi persino aggiungere un vincolo di controllo per garantire valori sane tra le due colonne enum (supponendo che tu stia utilizzando un RDBMS che supporta i vincoli di controllo - ciao MySQL ... stai ascoltando?)

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
);

Lascia che il database applichi tutte le regole tra i dati. Con le regole ben definite al livello più basso, il resto del sistema ottiene questa garanzia.

    
risposta data 03.06.2015 - 18:37
fonte
0

Penso che il modo in cui vuoi dividerlo in enumerazioni multiple non sia male, ma richiede modifiche nel DB.

Ti consentirà anche di creare un pagamento di successo con il motivo di cancellazione ecc. Quando hai un enum singolo (enorme), copre questa logica enumerando tutte le combinazioni consentite. Senza di esso, o hai bisogno di qualche logica applicativa o permetti la piena moltiplicazione cartesiana delle enumerazioni.

Ad ogni modo, dato che le enumerazioni possono avere campi e metodi, puoi semplicemente aggiornare l'enum esistente. Aggiungi alcuni campi e getter privati e puoi fare qualcosa di simile:

if (missionProgress.getPaymentStatus() == PaymentStatus.CANCEL) {...}

Ad ogni modo, se non hai ancora l'applicazione in esecuzione sul server di qualsiasi cliente (con già tonnellate di dati), ti consiglio di non usare un enumer enorme come quello.

    
risposta data 03.06.2015 - 18:04
fonte

Leggi altre domande sui tag