nhibernate - पहचान कॉलम से हिरो कुंजी तक माइग्रेट करने का कोई व्यावहारिक तरीका है?




identity sequence (4)

यदि यह एक मौजूदा आवेदन को पलायन करने के बारे में एक सवाल है जो पहले ऑटो आईडी इस्तेमाल कर रहा था, और उसके पुराने डेटा में माइग्रेट होने की जरूरत है ... तो यह मेरी सबसे अच्छी शर्त होगी (हालांकि कोशिश नहीं की! - टिप्पणियाँ स्वागत है!) :

  • अपने कॉलम प्रकार आईडी को बड़े अक्षरों में बदलें
  • किसी भी तालिका में वर्तमान में सर्वोच्च आईडी मान खोजें
  • एचआईएलओ स्रोत तालिका में अपना 'अगला-उच्च' मान सेट करें, आईडी से मिलने वाले मूल्य से अधिक है

यदि पाठ्यक्रम केवल पहचान स्तंभ के साथ ही मुद्दों को संबोधित करता है, तो आपकी स्कीमा में कुछ और नहीं हो सकता है, जिसे बदलने के लिए आवश्यक हो सकता है यदि आप एप को NHibernate पर ले जा रहे हैं

मैं एक डेटाबेस के साथ काम करता हूं जो पहचान कॉलम पर भारी निर्भर करता है। हालांकि, जैसा कि हमने अब सभी आवेदन NHibernate पर ले जाया है, मैं NHLNNET के साथ अनुशंसा की जा रही है, जैसे HiLo का उपयोग करना चाहता था। क्या ऐसा करने के लिए कोई रणनीति है, या किसी भी सामान्य समस्याएं देखने के लिए?


मैंने एचआईएलओ मूल्यों (एसक्यूएल सर्वर पर) तय करने के लिए स्क्रिप्ट (स्टेपन्स के उत्तर के आधार पर) लिखा था - यह मानता है कि आपके पास एक हेलो सारणी है

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

और आपकी तालिका की पहचान कॉलम सभी को आईडी कहते हैं तालिका तालिका के साथ एंटिटी तालिका को इनिट करें जिसे आप के लिए हिलो मान उत्पन्न करना चाहते हैं। स्क्रिप्ट चलाना इस तरह एक तरह से अपडेट स्टेटमेंट की एक श्रृंखला उत्पन्न करेगा:

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

यहां एक स्क्रिप्ट (एमएस एसक्यूएल) है जो वर्तमान डाटाबेस में सभी तालिकाओं के लिए सभी अगले उच्च संख्या वाले हायलो (नाम, वैल्यू) तालिका को भर देगी:

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

यहां वृद्धिशील जनरेटर से हाल ही में माइग्रेशन से एक नमूना है जिसमें एकाधिकहिलीपरेटेबल जनरेटर (उदाहरण के लिए एक मेज को प्रत्येक इकाईयों के लिए उच्च मूल्यों को संग्रहीत करने के लिए उपयोग किया जाता है)।

मेरा आवेदन हाइबरनेट 3 + मानचित्रण फ़ाइलें (.hbm.xml) का उपयोग कर रहा है। मेरा डाटाबेस MySQL (इनओडीबी + ऑटो इंक्रीमेंट पीके) है।

चरण 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 : मौजूदा डेटा के अनुसार आरंभिक उच्च मानों को एसक्यूएल के निम्न भाग का उपयोग करके आबाद करें। मैं मानता हूँ कि प्रत्येक तालिका के लिए एक ही max_lo मान का उपयोग किया जाता है।

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