Ecco uno scenario fittizio con alcuni dati popolati. Ai fini fiscali, la mia società fittizia deve conservare record di dati storici. Per questo motivo, ho incluso una colonna della versione sul tavolo.Versioning in tabelle SQL - come gestirlo?
TABLE EMPLOYEE: (with personal commentary)
|ID | VERSION | NAME | Position | PAY |
+---+---------+------------+----------+-----+
| 1 | 1 | John Doe | Owner | 100 | Started company
| 1 | 2 | John Doe | Owner | 80 | Pay cut to hire a coder
| 2 | 1 | Mark May | Coder | 20 | Hire said coder
| 2 | 2 | Mark May | Coder | 30 | Productive coder gets raise
| 3 | 1 | Jane Field | Admn Asst| 15 | Need office staff
| 2 | 3 | Mark May | Coder | 35 | Productive coder gets raise
| 1 | 3 | John Doe | Owner | 120 | Sales = profit for owner!
| 3 | 2 | Jane Field | Admn Asst| 20 | Raise for office staff
| 4 | 1 | Cody Munn | Coder | 20 | Hire another coder
| 4 | 2 | Cody Munn | Coder | 25 | Give that coder raise
| 3 | 3 | Jane Munn | Admn Asst| 20 | Jane marries Cody <3
| 2 | 4 | Mark May | Dev Lead | 40 | Promote mark to Dev Lead
| 4 | 3 | Cody Munn | Coder | 30 | Give Cody a raise
| 2 | 5 | Mark May | Retired | 0 | Mark retires
| 5 | 1 | Joey Trib | Dev Lead | 40 | Bring outside help for Dev Lead
| 6 | 1 | Hire Meplz | Coder | 10 | Hire a cheap coder
| 3 | 4 | Jane Munn | Retired | 0 | Jane quits
| 7 | 1 | Work Fofre | Admn Asst| 10 | Hire Janes replacement
| 8 | 1 | Fran Hesky | Coder | 10 | Hire another coder
| 9 | 1 | Deby Olav | Coder | 25 | Hire another coder
| 4 | 4 | Cody Munn | VP Ops | 80 | Promote Cody
| 9 | 2 | Deby Olav | VP Ops | 80 | Cody fails at VP Ops, promote Deby
| 4 | 5 | Cody Munn | Retired | 0 | Cody retires in shame
| 5 | 2 | Joey Trib | Dev Lead | 50 | Give Joey a raise
+---+---------+------------+----------+-----+
Ora, se volevo fare qualcosa di simile "Ottenere una lista dei programmatori correnti" non ho potuto fare solo SELECT * FROM EMPLOYEE WHERE Position = 'Coder'
perché sarebbe tornare un sacco di dati storici ... che è male.
Sto cercando buone idee per gestire questo scenario. Vedo alcune opzioni che mi saltano addosso, ma sono sicuro che qualcuno dirà "Wow, questo è un errore da principiante, splendore ... prova questo per le dimensioni:" di che cosa si tratta questo posto, giusto? :-)
Idea numero 1: Mantenere una tabella versione con la versione corrente come questo
TABLE EMPLOYEE_VERSION:
|ID |VERSION|
+---+-------+
| 1 | 3 |
| 2 | 5 |
| 3 | 4 |
| 4 | 6 |
| 5 | 2 |
| 6 | 1 |
| 7 | 1 |
| 8 | 1 |
| 9 | 2 |
+---+-------+
Anche se non sono sicuro di come lo farei con una singola query, io sono sicuro che potrebbe essere fatto, e scommetto che potrei capirlo con uno sforzo piuttosto piccolo.
Ovviamente, dovrei aggiornare questa tabella ogni volta che inserisco nella tabella EMPLOYEE per incrementare la versione per l'ID specificato (o inserirla nella tabella delle versioni quando viene creato un nuovo ID).
Il sovraccarico di ciò sembra indesiderabile.
Numero di idea 2: Mantiene una tabella di archivio e una tabella principale. Prima di aggiornare la tabella principale, inserisci la riga che sto per sovrascrivere nella tabella di archivio e usa la tabella principale come farebbe normalmente, come se non fossi interessato al controllo delle versioni.
Idea numero 3: Trova una query che aggiunge qualcosa sulla falsariga di SELECT * FROM EMPLOYEE WHERE Position = 'Coder' and version=MaxVersionForId(EMPLOYEE.ID)
... Non del tutto sicuro di come lo farei. Questa mi sembra la migliore idea, ma a questo punto non sono davvero sicuro.
Idea numero 4: Fai una colonna per "corrente" e aggiungere "in cui la corrente = TRUE e ..."
mi viene in mente che sicuramente le persone hanno fatto prima, incorrere in questi stessi problemi e avere informazioni su di esso da condividere, e così vengo a ritenerlo! :) Ho già cercato di trovare esempi del problema, ma sembrano specializzati in uno scenario particolare.
Grazie!
EDIT 1:
In primo luogo, apprezzo tutte le risposte, e hai tutto detto la stessa cosa - DATE
è meglio di VERSION NUMBER
. Una ragione stavo andando con VERSION NUMBER
è stato quello di semplificare il processo di aggiornamento nel server per impedire il seguente scenario
persona Un record carichi dipendente 3 nella sua sessione, ed ha la versione 4. record di persona B carichi dipendente 3 la sua sessione, e ha la versione 4. La persona A apporta modifiche e si impegna. Funziona perché la versione più recente nel database è 4. Ora è 5. La persona B apporta modifiche e commette. Questo fallisce perché la versione più recente è 5, mentre il suo è 4.
In che modo lo schema EFFECTIVE DATE
risolve questo problema?
EDIT 2:
credo che avrei potuto farlo facendo qualcosa di simile a questo: persona Un record carichi dipendente 3 nella sua sessione, ed è data effettiva è 1-1-2010, 01:00 pm, senza esperienza. La persona B carica il record 3 del dipendente nella sua sessione e la sua data effettiva è 1-1-2010, 13:00, senza alcuna esperienza. La persona A apporta modifiche e commette. La vecchia copia va alla tabella archivio (sostanzialmente idea 2) con una data di sperimentazione del 21/09/2010 alle 13:00. La versione aggiornata della tabella principale ha una data effettiva del 9/22/2010 alle 13:00. La persona B apporta modifiche e commette. Il commit non riesce perché le date effettive (nel database e nella sessione) non corrispondono.
Vorrei risolvere il problema delle versioni nella modifica con i blocchi e il comportamento della contesa, non con il sistema di controllo delle versioni (che sarà una sorta di modifica). – JNK