Ich arbeite mit einer Datenbank, die stark von Identitätsspalten abhängt. Da wir nun alle Anwendungen auf NHibernate umgestellt haben, wollte ich mit HiLo nachsehen, wie es mit NHibernate zu empfehlen ist. Gibt es irgendwelche Strategien, um dies zu tun, oder irgendwelche gemeinsamen Probleme, auf die man achten sollte?Gibt es eine praktische Möglichkeit, von Identitätsspalten zu Hiloschlüsseln zu migrieren?
Antwort
Wenn es sich um eine Frage über die Migration einer bestehenden Anwendung auf Hilos handelt, die zuvor Auto-IDs verwendet hat und alte Daten darin enthalten sind, die migriert werden müssen, dann wäre dies meine beste Wette (nicht ausprobiert!) willkommen Kommentare):
- Ihre Spaltentypen IDs bigints ändern
- derzeit höchsten ID-Wert in einer Tabelle herausfinden.
- Stellen Sie Ihren ‚nächste hohen‘ Wert in der Tabelle hilo Quelle auf einen höheren Wert, als Sie in dem IDs gefunden
Wenn Dies ist natürlich nur Adressen Probleme mit der Identitätsspalte, nicht irgendetwas anderes in Ihrem Schema, das muss möglicherweise geändert werden, wenn Sie eine App in NHibernate verschieben.
Sie müssen die Tabelle einrichten, die von NH verwendet wird, um HiLo-Werte korrekt zu erstellen. Lassen Sie Schema Creator die Tabelle gemäß Ihren Zuordnungsdefinitionen erstellen, legen Sie die Werte entsprechend dem aktuellen Status der IDs in Ihrer Datenbank fest.
Ich glaube, (Sie müssen dies überprüfen), die von hilo erzeugten Werten werden berechnet durch:
hilo-id = high-value * max_lo + low-value
Während der High-Wert in der Datenbank gespeichert ist, max_low in der Mapping-Datei definiert und von geringen Wert zur Laufzeit berechnet.
NHibernate benötigt auch eine eigene Verbindung und Transaktion, um den hohen Wert zu ermitteln und zu erhöhen. Daher funktioniert es nicht, wenn die Verbindung von der Anwendung bereitgestellt wird.
Sie können weiterhin seqhilo
verwenden, NH verwendet eine Datenbanksequenz, um die nächsten hohen Werte zu erstellen, und benötigt dazu keine separate Verbindung. Dies ist nur für Datenbanken verfügbar, die Sequenzen wie Oracle unterstützen.
Korrektur:
Inzwischen habe ich es selbst zu implementieren hatte (vor, es war nur Theorie :-). Also komme ich zurück, um die Details zu teilen.
Die Formel lautet:
next_hi = (highest_id/(maxLow + 1)) + 1
next_hi
das Feld in der Datenbank Sie aktualisieren müssen. highest_id
ist die höchste ID in Ihrer Datenbank. maxLow
ist der Wert, den Sie in der Zuordnungsdatei angegeben haben. Keine Idee, warum es um eins erhöht wird. Die Division ist eine Integer-Division, die die Dezimalstellen abschneidet.
Sollten Sie eine hilo Tabelle pro Einheit haben Tabelle? – mcintyre321
schrieb ich ein Drehbuch (basierend Antwort Stephans) für hilo Werte Festsetzung (auf SQL Server) - es wird davon ausgegangen, dass Sie eine hilo Tisch haben wie
CREATE TABLE [dbo].[HiloValues](
[next_hi] [int] NULL,
[Entity] [varchar](128) NOT NULL
)
Und Ihre Tabelle Identität Spalten werden alle ID genannt. Initiieren Sie die Entitätstabelle mit den Tabellennamen, für die Sie die Hilo-Werte generieren möchten.
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'
es hier
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
Hier ist ein Beispiel aus einer aktuellen Migration vom Generator zum MultipleHiLoPerTableGenerator Zuwachs ist: das Skript ausführen, wird eine Reihe von Update-Anweisungen wie diese erzeugt (ZB eine einzelne Tabelle wird verwendet, um hohe Werte für jede Entitäten zu speichern).
Meine Anwendung verwendet Hibernate 3 + Mapping-Dateien (.hbm.xml). Meine Datenbank ist MySQL (innoDB + auto increment pk).
Schritt 1: Ersetzen Sie Ihre Generatoreinstellungen in Ihren .hbm-Dateien. Ersetzen :
<generator class="increment" />
von
<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>
Schritt 2: Erstellen einer neuen Tabelle, die die hohen Werte speichern
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;
Schritt 3: die anfängliche hohe Werte bevöl nach zu bestehenden Daten mit dem folgenden Stück SQL. Ich gehe hier davon aus, dass für jede Tabelle der gleiche max_lo
Wert verwendet wird.
INSERT INTO hilo_values SELECT TABLE_NAME, ((AUTO_INCREMENT DIV (1000 + 1)) + 1) FROM information_schema.tables WHERE table_schema = 'yourdbname'
Hier ist ein Skript (MS SQL), die HiLo (Name, Wert) Tabelle in der aktuellen Datenbank für alle Tabellen mit allen nächsten hohen Zahlen füllt:
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. Gibt es eine Möglichkeit, South zu konfigurieren, um zu migrieren, ohne irgendwelche Fragen zu stellen?
- 2. Gibt es eine einfache Möglichkeit, Alembic zu einer bestimmten Revision zu migrieren?
- 3. Eine praktische Möglichkeit, eine große Ansicht für UIScrollView zu erstellen?
- 4. Gibt es eine Möglichkeit, Kovarianz zu deklarieren?
- 5. Gibt es eine Möglichkeit, "träge" zu lesen?
- 6. Gibt es eine Möglichkeit, Datenbanktransaktionen zu beschleunigen?
- 7. Gibt es eine Möglichkeit, Mehrfacheinspritzung zu propagieren?
- 8. Gibt es eine Möglichkeit, django.db.connection.queries zu löschen?
- 9. Gibt es eine Möglichkeit, ConfigurationManager.AppSettings zu überschreiben?
- 10. Gibt es eine Möglichkeit, Typdeklarationen zu erweitern?
- 11. Gibt es eine praktische Möglichkeit, das größte Element im Container mit STL zu finden?
- 12. Gibt es eine Möglichkeit, AMDPlugin zu deaktivieren?
- 13. Gibt es eine Möglichkeit, Fenstereigenschaften zu verbergen?
- 14. Gibt es eine Möglichkeit, onPanResponderMove zu verwalten?
- 15. Gibt es eine Möglichkeit, PreparedStatement zu aktualisieren?
- 16. Gibt es eine Möglichkeit, Unterabfragen zu vermeiden?
- 17. Gibt es eine Möglichkeit, Webkonsolenfehler zu erkennen?
- 18. Gibt es eine Möglichkeit, dies zu loopen?
- 19. Gibt es eine Möglichkeit, Formularantwort zu ignorieren?
- 20. Gibt es eine Möglichkeit, Duplikate zu vermeiden?
- 21. Gibt es eine Möglichkeit, Creeps zu löschen?
- 22. Gibt es eine Möglichkeit, Selektoren zu gruppieren?
- 23. Gibt es die beste Möglichkeit, vorhandene Tabellen ohne Fremdschlüssel zu Laravel 5 mit Eloquent zu migrieren?
- 24. Gibt es eine Möglichkeit, IEnumerable zu speichern oder zu speichern?
- 25. Gibt es eine Möglichkeit, zu teilweise hochgeladenen Dateien zu gelangen?
- 26. Gibt es eine bessere Möglichkeit, diesen LINQ-Anweisungsblock zu erstellen?
- 27. Gibt es eine Möglichkeit, Bilder von Webcam zu erfassen?
- 28. Gibt es eine Möglichkeit, die textAlignment von UILabel zu animieren?
- 29. Gibt es eine Möglichkeit, die Anforderung von RenderBody() zu umgehen?
- 30. Gibt es eine Möglichkeit, unbekannte Ereignislistener von Objekten zu entfernen?
Eigentlich sollte der Wert next-hi nicht höher als der Wert in den IDs gesetzt werden, siehe Stefan's Antwort unten für einen guten Ansatz. – andreialecu
@legenden - warum nicht erklären? – UpTheCreek
@UpTheCreek: Es ist zu hoch, Sie verlieren viele IDs. In der Mapping-Datei geben Sie an, wie viele IDs Sie für einen einzelnen Wert in next-hi generieren können. next-hi ist daher immer etwas kleiner als die generierten ids. –