难道有标识列迁移到希洛键的一条可行之路?(Is there a practical way of m

2019-08-04 04:38发布

我与在很大程度上取决于身份列的数据库。 然而,由于我们现在已经感动了所有的应用程序在NHibernate的,我想考虑使用高住低训作为似乎与NHibernate的推荐。 是否有任何策略要做到这一点,或任何共同的问题需要提防?

Answer 1:

如果这是一个有关迁移现有的应用程序到以前使用的汽车IDS hilos问题,并在它的旧数据需要被迁移......那么这将是我最好的选择(没有尝试过,但 - !欢迎评论!) :

  • 更改列类型ID来bigints
  • 找出价值最高的ID在当前的任何表。
  • 在希洛源表中的“下高”值设置为比你的ID发现高的值

当然,如果这只是解决了标识列,没有什么模式中的其他人,如果你是移动应用程序NHibernate的,可能需要改变的问题。



Answer 2:

你需要设置由NH使用的表正确地创建高住低训值。 让架构造物主根据你的映射定义创建表,根据数据库中的ID的当前状态设置的值。

我相信(你需要验证这一点),其值由希洛产生的计算:

hilo-id = high-value * max_lo + low-value

而高值被存储在数据库中,在映射文件并在运行时计算出的低值max_low定义。


NHibernate的也需要它自己的连接和交易,以确定并增加高价值。 因此,如果连接是由应用程序提供它不工作。

您仍然可以使用seqhilo ,NH使用数据库序列创建下一个高值,不需要单独的连接这样做。 这仅仅是在支持序列,如Oracle数据库可用。


更正:

同时,我必须实现它自己(之前,这只是理论:-)。 等我回来分享的细节。

的公式为:

next_hi = (highest_id / (maxLow + 1)) + 1

next_hi在您需要更新数据库中的字段。 highest_id是在你的数据库中找到的最高的ID。 maxLow是你在映射文件中指定的值。 不知道为什么它加一。 该部门是一个整数等分其截断小数。



Answer 3:

我写了一个脚本(基于Stephans答案)固定希洛值(SQL Server上) - 它假定你有一个希洛表像

CREATE TABLE [dbo].[HiloValues](
    [next_hi] [int] NULL,
    [Entity] [varchar](128) NOT NULL
)

而你的表的身份列都称为ID。 初始化实体表与表名要生成的希洛值。 运行该脚本将产生一系列像这样的更新语句:

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'

这里是

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


Answer 4:

这里有一个脚本(MS SQL),将填补希洛(名称,值)表的所有未来高号码在当前数据库中的所有表:

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


Answer 5:

这里是从增量发生器到MultipleHiLoPerTableGenerator(例如,单个表被用来存储高值每实体)最近的迁移的样品。

我的应用程序使用Hibernate 3 +映射文件(的.hbm.xml)。 我的数据库是MySQL的(InnoDB的+自动增量PK)。

第1步 :在您的.hbm文件替换您的发电机的设置。 更换:

<generator class="increment" />

通过

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

第2步 :创建一个新表来存储高值

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;

步骤3:根据使用以下SQL片的现有数据填充初始的高值。 我在这里假设相同max_lo值用于每个表。

INSERT INTO hilo_values SELECT TABLE_NAME,  ((AUTO_INCREMENT DIV (1000 + 1)) + 1) FROM information_schema.tables WHERE table_schema = 'yourdbname'


文章来源: Is there a practical way of migrating from identity columns to hilo keys?