Trabajo con una base de datos que depende en gran medida de las columnas de identidad. Sin embargo, como ahora hemos trasladado todas las aplicaciones a NHibernate, quería estudiar el uso de HiLo, ya que parece ser recomendado con NHibernate. ¿Hay alguna estrategia para hacer esto, o algún problema común a tener en cuenta?¿Existe alguna forma práctica de migrar de las columnas de identidad a las claves de la unidad?
Respuesta
Si se trata de migrar una aplicación existente a hilos que usaba previamente identificadores automáticos, y tiene datos antiguos que deben migrarse ... entonces esta sería mi mejor opción (aunque no lo intenté). los comentarios de bienvenida):
- cambiar sus identificadores de tipos de columna a bigints
- enteran de más alto valor id actualmente en cualquier mesa.
- fijar el valor de 'próxima alto' en la tabla de origen hilo a un valor más alto que se encuentran en las identificaciones
Si supuesto, esto sólo soluciona problemas con la columna de identidad, no nada más en su esquema que podría necesitar cambiar si está moviendo una aplicación a NHibernate.
Necesita configurar la tabla utilizada por NH para crear valores HiLo correctamente. Deje que Schema Creator cree la tabla de acuerdo con sus definiciones de mapeo, establezca los valores de acuerdo con el estado actual de los identificadores en su base de datos.
creo (que necesita para verificar esto) que valores generados por hilo se calculan por:
hilo-id = high-value * max_lo + low-value
Mientras que el alto valor se almacena en la base de datos, max_low definido en el archivo de asignación y de bajo valor calculado en tiempo de ejecución.
NHibernate también necesita su propia conexión y transacción para determinar e incrementar el valor alto. Por lo tanto, no funciona si la conexión proporciona la conexión.
Puede seguir usando seqhilo
, NH usa una secuencia de base de datos para crear los siguientes valores altos y no necesita una conexión separada para hacerlo. Esto solo está disponible en bases de datos que admiten secuencias, como Oracle.
Corrección:
Mientras tanto, he tenido que aplicar yo mismo (antes, era sólo teoría :-). Entonces vuelvo a compartir los detalles.
La fórmula es:
next_hi = (highest_id/(maxLow + 1)) + 1
next_hi
es el campo en la base de datos tiene que actualizar. highest_id
es la ID más alta que se encuentra en su base de datos. maxLow
es el valor que especificó en el archivo de asignación. No idea por qué se incrementa en uno. La división es una definición entera que trunca los decimales.
En caso de tener una mesa de hilo por entidad ¿mesa? – mcintyre321
Escribí un guión (basado de respuesta Esteban) para la fijación de los valores de Hilo (en el servidor SQL) - que se supone que tiene una tabla de hilo como
CREATE TABLE [dbo].[HiloValues](
[next_hi] [int] NULL,
[Entity] [varchar](128) NOT NULL
)
Y las columnas de identidad de su mesa están llamados ID. Inicie la tabla Entidad con los nombres de tabla para los que desea generar los valores del hilo. Al ejecutar el script generará una serie de instrucciones de actualización como éste:
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'
Aquí es
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
Este es un ejemplo de una reciente migración del generador incremento para el MultipleHiLoPerTableGenerator (por ejemplo, una sola tabla se usa para almacenar valores altos para cada Entidad).
Mi aplicación utiliza archivos de mapeo Hibernate 3+ (.hbm.xml). Mi base de datos es MySQL (innoDB + auto incremento pk).
Paso 1: reemplace las configuraciones de su generador en sus archivos .hbm. Reemplazar:
<generator class="increment" />
Por
<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>
Paso 2: crear una nueva tabla para almacenar los valores altos
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;
Paso 3: rellenar los valores altos iniciales de acuerdo a los datos existentes usando la siguiente pieza de SQL. Supongo que aquí se usa el mismo valor max_lo
para cada tabla.
INSERT INTO hilo_values SELECT TABLE_NAME, ((AUTO_INCREMENT DIV (1000 + 1)) + 1) FROM information_schema.tables WHERE table_schema = 'yourdbname'
Aquí es una secuencia de comandos (MS SQL) que llenará la tabla Hilo (Nombre, Valor) con todos los números altos próximos para todas las tablas de base de datos actual:
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. ¿Existe alguna forma práctica de usar números naturales en Haskell?
- 2. Datos de la tabla vacía y restablecer las columnas de IDENTIDAD
- 3. ¿Existe alguna convención de formato en las cadenas de consulta?
- 4. Cómo InnoDB ordena las claves primarias de varias columnas
- 5. Fingiendo actualizaciones de claves foráneas usando las claves de entidad
- 6. ¿Existe alguna manera de extender las primeras migraciones de código?
- 7. ¿Hay alguna forma de ignorar las columnas que no existen en INSERTAR?
- 8. ¿Hay alguna forma de agregar columnas adicionales a un jstree?
- 9. ¿Es una mala práctica usar DiscriminatorFormula para migrar las bases de datos de Hibernate?
- 10. Probando si un hash tiene alguna de las claves
- 11. ¿Hay alguna forma de automatizar las pruebas de Windows Forms?
- 12. ADO.NET Entity Framework y columnas de identidad
- 13. ¿Existe alguna forma mejor de convertir de UTCTime a EpochTime?
- 14. ¿MySQL indexa las columnas de clave externa de forma automática?
- 15. Cómo probar las subclases de la unidad
- 16. ¿Existe alguna forma de serializar las invocaciones de una señal boost :: signals2?
- 17. ¿Existe alguna forma declarativa de analizar objetos XML a Java?
- 18. ¿Cómo puedo encontrar fácilmente las columnas de IDENTIDAD en peligro de desbordamiento?
- 19. ¿Hay alguna forma de obtener las claves generadas cuando se utiliza Spring JDBC batchUpdate?
- 20. Obtener todas las columnas de todas las tablas MySQL
- 21. Cómo cambiar las columnas de DataTop orden
- 22. ¿Alguna forma de manipular las columnas en GridView con AutoGenerateColumns = true?
- 23. ¿Existe alguna forma mejor de actualizar WebView?
- 24. columnas de identidad RESEED en la base de datos
- 25. PHP, La fusión de las matrices con las claves comunes
- 26. ¿Existe alguna forma mejor de agregar un diccionario utilizando LINQ?
- 27. Java: ¿forma simple de poner las claves/valores de LinkedHashMap en las listas respectivas?
- 28. Diccionario de clasificación basado en las claves
- 29. Ordenar columnas en las tablas de la base de datos
- 30. ¿Existe alguna forma preferida de formatear las cadenas jQuery para que sean más legibles?
En realidad, no debe establecer el siguiente valor de hi a un valor superior al que se encuentra en los ID, consulte la respuesta de Stefan a continuación para obtener un buen enfoque. – andreialecu
@legenden: cuidado para explicar por qué no? – UpTheCreek
@UpTheCreek: es demasiado alto, pierdes muchos identificadores. En el archivo de mapeo, usted especifica cuántos identificadores puede generar para un solo valor en next-hi. next-hi es, por lo tanto, siempre más pequeño por algún factor que los identificadores generados. –