Lavoro con un database che dipende molto dalle colonne di identità. Tuttavia, poiché ora abbiamo spostato tutte le applicazioni su NHibernate, volevo esaminare l'utilizzo di HiLo come sembra essere consigliato con NHibernate. Ci sono delle strategie per farlo o dei problemi comuni a cui prestare attenzione?Esiste un modo pratico per eseguire la migrazione dalle colonne Identity alle chiavi Hilo?
risposta
Se questa è una domanda sulla migrazione di un'applicazione esistente a hilos che in precedenza utilizzava id automatici e contiene vecchi dati che devono essere migrati ... questa sarebbe la mia migliore scommessa (non provatela però! Comments benvenuto!):
- cambiare il vostro tipi di colonna ID per bigints
- scoprire il valore più alto id attualmente in qualsiasi tavolo.
- impostare il proprio 'next-alto' valore nella tabella di origine Hilo a un valore superiore a quello che si trova nelle ID
Se Naturalmente questo unici problemi indirizzi con la colonna di identità, non è niente altro nello schema che potrebbe essere necessario cambiare se stai spostando un'app su NHibernate.
è necessario impostare la tabella utilizzata da NH per creare correttamente i valori di Hilo. Consenti a Schema Creator di creare la tabella in base alle definizioni di mapping, impostare i valori in base allo stato corrente degli ID nel database.
credo (è necessario verificare questo) che i valori generati da Hilo sono calcolate da:
hilo-id = high-value * max_lo + low-value
Mentre il-alto valore viene memorizzato nel database, max_low definito nel file di mappatura e di scarso valore calcolato in fase di esecuzione.
Anche NHibernate necessita di una propria connessione e transazione per determinare e incrementare il valore elevato. Pertanto non funziona se la connessione è fornita dall'applicazione.
È ancora possibile utilizzare seqhilo
, NH utilizza una sequenza di database per creare valori alti successivi e non ha bisogno di una connessione separata per farlo. Questo è disponibile solo su database che supportano sequenze, come Oracle.
Correzione:
Nel frattempo, ho dovuto implementare io stesso (prima, era solo teoria :-). Quindi torno a condividere i dettagli.
La formula è:
next_hi = (highest_id/(maxLow + 1)) + 1
next_hi
è il campo nel database è necessario aggiornare. highest_id
è l'ID più alto trovato nel tuo database. maxLow
è il valore specificato nel file di mapping. Nessuna idea perché è incrementata di uno. La divisione è una deviazione intera che tronca le cifre decimali.
Qualora vi siano tavolo Hilo per entità tavolo? – mcintyre321
Ho scritto uno script (basata su Stefano risposta) per stabilire i valori per Hilo (su un server di SQL) - si presuppone che si dispone di una tabella di Hilo come
CREATE TABLE [dbo].[HiloValues](
[next_hi] [int] NULL,
[Entity] [varchar](128) NOT NULL
)
E colonne di identità della vostra tabella sono tutti chiamati ID. Inizia la tabella Entità con i nomi tabella per i quali vuoi generare i valori hilo. Esecuzione dello script genera una serie di istruzioni di aggiornamento come questo:
UPDATE hv
SET next_hi = Transactions.ID/(10 + 1) + 1
FROM HiloValues hv
CROSS JOIN (SELECT ISNULL(Max(ID), 0) as id FROM Transactions) as Transactions
WHERE hv.entity = 'Transactions'
Qui è
DECLARE @scripts TABLE(Script VARCHAR(MAX))
DECLARE @max_lo VARCHAR(MAX) = '10';
INSERT INTO @scripts
SELECT '
UPDATE hv
SET next_hi = ' + Entity + '.ID/(' + @max_lo + ' + 1) + 1
FROM HiloValues hv
CROSS JOIN (SELECT ISNULL(Max(ID), 0) as id FROM ' + entity + ') as ' + entity + '
WHERE hv.entity = ''' + entity + '''' as script
FROM HiloValues WHERE Entity IN (SELECT name from sys.tables)
DECLARE curs CURSOR FOR SELECT * FROM @scripts
DECLARE @script VARCHAR(MAX)
OPEN curs
FETCH NEXT FROM curs INTO @script
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @script --OR EXEC(@script)
FETCH NEXT FROM curs INTO @script
END
CLOSE curs
DEALLOCATE curs
Ecco un esempio da una recente migrazione dal incremento generatore al MultipleHiLoPerTableGenerator (ad es. una singola tabella è usata per memorizzare valori alti per ogni Entità).
La mia applicazione utilizza i file di mappatura di Hibernate 3 + (.hbm.xml). Il mio database è MySQL (innoDB + auto increment pk).
Fase 1: sostituire le impostazioni del generatore nei file .hbm. Sostituire:
<generator class="increment" />
Con
<generator class="org.hibernate.id.MultipleHiLoPerTableGenerator">
<param name="table">hilo_values</param>
<param name="primary_key_column">sequence_name</param>
<param name="value_column">sequence_next_hi_value</param>
<param name="max_lo">1000</param>
</generator>
Fase 2: creare una nuova tabella per memorizzare i valori alti
CREATE TABLE IF NOT EXISTS `hilo_values` (
`sequence_name` varchar(255) NOT NULL,
`sequence_next_hi_value` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Fase 3: popolare i valori iniziali elevati secondo a dati esistenti utilizzando il seguente pezzo di SQL. Presumo qui che lo stesso valore max_lo
sia utilizzato per ogni tabella.
INSERT INTO hilo_values SELECT TABLE_NAME, ((AUTO_INCREMENT DIV (1000 + 1)) + 1) FROM information_schema.tables WHERE table_schema = 'yourdbname'
Ecco uno script (MS SQL) che riempirà tavolo per Hilo (nome, valore), con tutti i prossimi numeri alti per tutte le tabelle nel database corrente:
declare tables cursor for
select
Table_Schema,
Table_Name
from
information_schema.tables
where
Table_Schema = 'dbo'
and
Table_Type = 'BASE TABLE'
and
Table_Name <> 'HiLo'
and
right (Table_Name, 1) <> '_'
declare @table_schema varchar(255)
declare @table_name varchar(255)
truncate table HiLo
open tables
fetch next from tables into @table_schema, @table_name
while (@@fetch_status = 0)
begin
declare @sql as nvarchar(max)
declare @max_id as int
set @sql = 'select @max_id = max(Id) from [' + @table_schema + '].[' + @table_name + ']'
exec sp_executesql @sql, N'@max_id int output', @max_id output
declare @max_low as int
set @max_low = 1000
declare @next_high as int
set @next_high = isnull (@max_id/@max_low + 1, 0)
--select @table_name, @max_id, @next_high
insert into HiLo (Name, Value) values (@table_schema + '.' + @table_name, @next_high)
fetch next from tables into @table_schema, @table_name
end
close tables
deallocate tables
select * from HiLo
- 1. HiLO per Entity Framework
- 2. Esiste un modo per eseguire Trac offline?
- 3. C'è un modo pratico per comprimere NSData?
- 4. NHibernate Hilo - nuova colonna per entità e HiLo cattura
- 5. Dati tabella vuota e ripristino colonne IDENTITY
- 6. Migrazione di SimpleMembership a Identity 2.0
- 7. Esiste un uso pratico per un puntatore `volatile restrict`?
- 8. Esiste un modo per rinominare chiavi oggetto js utilizzando underscore.js
- 9. Esiste un modo per ottimizzare questa query LINQ alle entità?
- 10. Wordpress: esiste un modo per regolare la larghezza delle colonne per la tabella dei post?
- 11. SSL Identity Certificate per eseguire un server HTTPS su iOS
- 12. Esiste un modo pratico per utilizzare il tipo di dati hierarchyID nell'entità framework 4?
- 13. Eseguire un singolo file di migrazione
- 14. Esiste un modo per eseguire due animazioni jQuery (correttamente) contemporaneamente?
- 15. Come eseguire l'aggiornamento in migrazione per Ecto?
- 16. Esiste un modo per eseguire in modo trasparente la convalida sugli oggetti SQLAlchemy?
- 17. Sklearn: Esiste un modo per eseguire il debug di Pipelines?
- 18. Come eseguire la migrazione dei dati di Cassandra da uno spazio per chiavi a un altro spazio tasti?
- 19. Un modo semplice per riordinare le colonne?
- 20. Modo corretto per collegarsi alle librerie dalle librerie per l'iPhone/CocoaTouch
- 21. La strategia del generatore HiLo non funziona
- 22. Esiste un limite di lunghezza HTTP Header pratico?
- 23. Esiste un modo per personalizzare la pagina di accesso Thinktecture.IdentityServer.v2?
- 24. Esiste un modo per nascondere le chiavi API in un pacchetto R?
- 25. MySQL: come contare dalle colonne separatamente?
- 26. Modo Django per eseguire la formattazione condizionale
- 27. Esiste un modo per ordinare le colonne di una matrice in modo indipendente in R?
- 28. calcola la mediana dalle colonne data.table in R
- 29. Esiste un modo per accedere alle dipendenze dello stato risolto oltre a iniettarle nel controller?
- 30. Esiste un modo per utilizzare le chiavi variabili in un oggetto letterale JavaScript?
In realtà, non dovresti impostare il valore next-hi su un valore superiore a quello trovato negli ID, vedi la risposta di Stefan sotto per un buon approccio. – andreialecu
@legenden - cura di spiegare perché no? – UpTheCreek
@UpTheCreek: è troppo alto, perdi molti ID. Nel file di mappatura, si specifica quanti ID è possibile generare per un singolo valore in next-hi. next-hi è quindi sempre più piccolo di qualche fattore come gli id generati. –