Heim >Datenbank >MySQL-Tutorial >Detaillierte Beispiele für das Upgrade der IOS-Datenbank und die Datenmigration

Detaillierte Beispiele für das Upgrade der IOS-Datenbank und die Datenmigration

小云云
小云云Original
2017-12-25 14:09:071982Durchsuche

In diesem Artikel werden hauptsächlich relevante Informationen zu detaillierten Beispielen für die Aktualisierung von iOS-Datenbanken und die Datenmigration vorgestellt. Hier finden Sie Beispiele, die Ihnen bei der Lösung der Probleme bei der Aktualisierung der Datenbank und der Datenmigration helfen können .

Detailliertes Beispiel der Datenmigration für ein IOS-Datenbank-Upgrade

Zusammenfassung:

Ich bin vor langer Zeit auf ein Datenbankversions-Upgrade gestoßen Um das Szenario zu zitieren: Der damalige Ansatz bestand darin, einfach die alten Datenbankdateien zu löschen und die Datenbank- und Tabellenstruktur neu aufzubauen. Diese gewaltsame Aktualisierungsmethode würde zum Verlust alter Daten führen. Nun scheint dies keine elegante Lösung zu sein. Jetzt wird die Datenbank im neuen Projekt erneut verwendet. Ich hoffe, dass wir dieses Problem in Zukunft auf elegantere Weise lösen können, oder? ?

Die ideale Situation ist: Die Datenbank wird aktualisiert und die Tabellenstruktur, Primärschlüssel und Einschränkungen werden geändert. Nachdem die neue Tabellenstruktur erstellt wurde, werden die Daten automatisch aus der alten Tabelle abgerufen Dieselben Felder werden zugeordnet und migriert. Bei Datenbankversions-Upgrades werden nur Felder hinzugefügt oder entfernt und Primärschlüsseleinschränkungen geändert. Daher basiert die unten zu implementierende Lösung auch auf den grundlegendsten und am häufigsten verwendeten Geschäftsszenarien. Was die komplizierteren betrifft, können die Szenarien auf dieser Basis erweitert werden, um den eigenen Erwartungen gerecht zu werden.

Auswahl und Fertigstellung

Nach der Online-Suche gibt es keine einfache und vollständige Lösung für die Datenbankaktualisierung und Datenmigration, und ich habe einige Ideen gefunden

1. Löschen Sie alte Daten und Tabelle neu erstellen

Vorteile: Einfach
Nachteile: Datenverlust

2. Ändern Sie die Tabellenstruktur basierend auf der vorhandenen Tabelle

Vorteile: Kann Daten behalten
Nachteile: Die Regeln sind relativ umständlich. Sie müssen eine Datenbankfeldkonfigurationsdatei erstellen, dann die Konfigurationsdatei lesen und SQL ausführen, um die Tabellenstruktur, Einschränkungen, Primärschlüssel usw. zu ändern Das Aktualisieren mehrerer Datenbanken ist umständlich und mühsam.

3. Erstellen Sie eine temporäre Tabelle, kopieren Sie die alten Daten in die temporäre Tabelle, löschen Sie dann die alte Datentabelle und legen Sie die temporäre Tabelle als Datentabelle fest Tisch.

Vorteile: Es kann Daten speichern, unterstützt die Änderung der Tabellenstruktur, Änderungen von Einschränkungen und Primärschlüsseln und ist relativ einfach zu implementieren
Nachteile: Es sind viele Schritte zur Implementierung erforderlich

Alles in allem ist die dritte Methode eine zuverlässigere Lösung.

Hauptschritte

Gemäß dieser Idee werden die Hauptschritte des Datenbank-Upgrades wie folgt analysiert:

  • Get the Datenbank Alte Tabelle

  • Ändern Sie den Tabellennamen, fügen Sie das Suffix „_bak“ hinzu und verwenden Sie die alte Tabelle als Sicherungstabelle

  • Erstellen Sie eine neue Tabelle

  • Holen Sie sich die neu erstellte Tabelle

  • Durchlaufen Sie die alte Tabelle und die neue Tabelle, vergleichen Sie und extrahieren Sie die benötigten Felder der Tabelle migriert werden

  • Datenmigrationsverarbeitung

  • Sicherungstabelle löschen

Analyse von Verwendete SQL-Anweisungen

Diese Vorgänge beziehen sich auf Datenbankoperationen, daher ist der Schlüssel zum Problem die SQL-Anweisung, die dem Schritt entspricht. Die wichtigsten verwendeten SQL-Anweisungen werden unten analysiert:

Holen Sie sich die alten Tabelle in der Datenbank


Sie können sehen, dass es Datenbankfelder wie Typ | gibt . Wir müssen nur den Namen verwenden, der das Datenbanknamenfeld ist.

SELECT * from sqlite_master WHERE type='table'


Ändern Sie den Tabellennamen, fügen Sie das Suffix „_bak“ hinzu und verwenden Sie das alte Tabelle als Backup-Tabelle

sqlite> SELECT * from sqlite_master WHERE type='table'
 ...> ;
+-------+---------------+---------------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| type | name   | tbl_name  | rootpage | sql                                                     |
+-------+---------------+---------------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| table | t_message_bak | t_message_bak | 2  | CREATE TABLE "t_message_bak" (messageID TEXT, messageType INTEGER, messageJsonContent TEXT, retriveTimeString INTEGER, postTimeString INTEGER, readState INTEGER, PRIMARY KEY(messageID))        |
| table | t_message  | t_message  | 4  | CREATE TABLE t_message (
 messageID TEXT, 
 messageType INTEGER,
 messageJsonContent TEXT, 
 retriveTimeString INTEGER, 
 postTimeString INTEGER, 
 readState INTEGER, 
 addColumn INTEGER,
 PRIMARY KEY(messageID)
) |
+-------+---------------+---------------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 行于数据集 (0.03 秒)



Tabellenfeldinformationen abrufen

-- 把t_message表修改为t_message_bak表 
ALTER TABLE t_message RENAME TO t_message_bak



Die erhaltenen Tabellenfeldinformationen sind wie folgt: |. Für diese Datenbankfelder müssen wir nur den Feldnamen verwenden.

-- 获取t_message_bak表的字段信息
PRAGMA table_info('t_message_bak')


Verwenden Sie Unterabfragen für die Datenmigrationsverarbeitung

sqlite> PRAGMA table_info('t_message_bak');
+------+--------------------+---------+---------+------------+------+
| cid | name    | type | notnull | dflt_value | pk |
+------+--------------------+---------+---------+------------+------+
| 0 | messageID   | TEXT | 0  | NULL  | 1 |
| 1 | messageType  | INTEGER | 0  | NULL  | 0 |
| 2 | messageJsonContent | TEXT | 0  | NULL  | 0 |
| 3 | retriveTimeString | INTEGER | 0  | NULL  | 0 |
| 4 | postTimeString  | INTEGER | 0  | NULL  | 0 |
| 5 | readState   | INTEGER | 0  | NULL  | 0 |
+------+--------------------+---------+---------+------------+------+
6 行于数据集 (0.01 秒)



Kopieren Sie die Werte von messageID und messageType , messageJsonContent, retriveTimeString, postTimeString, readState-Felder in der t_message_bak-Tabelle zur t_message-Tabelle

INSERT INTO t_message(messageID, messageType, messageJsonContent, retriveTimeString,
 postTimeString, readState) SELECT messageID, messageType, messageJsonContent, retriveTimeString,
 postTimeString, readState FROM t_message_bak

Code-Implementierung

Der nächste Schritt besteht darin, den Code zu implementieren


Verwandte Empfehlungen:

// 创建新的临时表,把数据导入临时表,然后用临时表替换原表
- (void)baseDBVersionControl {
 NSString * version_old = ValueOrEmpty(MMUserDefault.dbVersion);
 NSString * version_new = [NSString stringWithFormat:@"%@", DB_Version];
 NSLog(@"dbVersionControl before: %@ after: %@",version_old,version_new);

 // 数据库版本升级
 if (version_old != nil && ![version_new isEqualToString:version_old]) {

  // 获取数据库中旧的表
  NSArray* existsTables = [self sqliteExistsTables];
  NSMutableArray* tmpExistsTables = [NSMutableArray array];

  // 修改表名,添加后缀“_bak”,把旧的表当做备份表
  for (NSString* tablename in existsTables) {
   [tmpExistsTables addObject:[NSString stringWithFormat:@"%@_bak", tablename]];
   [self.databaseQueue inDatabase:^(FMDatabase *db) {
    NSString* sql = [NSString stringWithFormat:@"ALTER TABLE %@ RENAME TO %@_bak", tablename, tablename];
    [db executeUpdate:sql];
   }];
  }
  existsTables = tmpExistsTables;

  // 创建新的表
  [self initTables];

  // 获取新创建的表
  NSArray* newAddedTables = [self sqliteNewAddedTables];

  // 遍历旧的表和新表,对比取出需要迁移的表的字段
  NSDictionary* migrationInfos = [self generateMigrationInfosWithOldTables:existsTables newTables:newAddedTables];

  // 数据迁移处理
  [migrationInfos enumerateKeysAndObjectsUsingBlock:^(NSString* newTableName, NSArray* publicColumns, BOOL * _Nonnull stop) {
   NSMutableString* colunmsString = [NSMutableString new];
   for (int i = 0; i* migrationInfos = [NSMutableDictionary dictionary];
 for (NSString* newTableName in newTables) {
  NSString* oldTableName = [NSString stringWithFormat:@"%@_bak", newTableName];
  if ([oldTables containsObject:oldTableName]) {
   // 获取表数据库字段信息
   NSArray* oldTableColumns = [self sqliteTableColumnsWithTableName:oldTableName];
   NSArray* newTableColumns = [self sqliteTableColumnsWithTableName:newTableName];
   NSArray* publicColumns = [self publicColumnsWithOldTableColumns:oldTableColumns newTableColumns:newTableColumns];

   if (publicColumns.count > 0) {
    [migrationInfos setObject:publicColumns forKey:newTableName];
   }
  }
 }
 return migrationInfos;
}

- (NSArray*)publicColumnsWithOldTableColumns:(NSArray*)oldTableColumns newTableColumns:(NSArray*)newTableColumns {
 NSMutableArray* publicColumns = [NSMutableArray array];
 for (NSString* oldTableColumn in oldTableColumns) {
  if ([newTableColumns containsObject:oldTableColumn]) {
   [publicColumns addObject:oldTableColumn];
  }
 }
 return publicColumns;
}

- (NSArray*)sqliteTableColumnsWithTableName:(NSString*)tableName {
 __block NSMutableArray* tableColumes = [NSMutableArray array];
 [self.databaseQueue inDatabase:^(FMDatabase *db) {
  NSString* sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')", tableName];
  FMResultSet *rs = [db executeQuery:sql];
  while ([rs next]) {
   NSString* columnName = [rs stringForColumn:@"name"];
   [tableColumes addObject:columnName];
  }
 }];
 return tableColumes;
}

- (NSArray*)sqliteExistsTables {
 __block NSMutableArray* existsTables = [NSMutableArray array];
 [self.databaseQueue inDatabase:^(FMDatabase *db) {
  NSString* sql = @"SELECT * from sqlite_master WHERE type='table'";
  FMResultSet *rs = [db executeQuery:sql];
  while ([rs next]) {
   NSString* tablename = [rs stringForColumn:@"name"];
   [existsTables addObject:tablename];
  }
 }];
 return existsTables;
}

- (NSArray*)sqliteNewAddedTables {
 __block NSMutableArray* newAddedTables = [NSMutableArray array];
 [self.databaseQueue inDatabase:^(FMDatabase *db) {
  NSString* sql = @"SELECT * from sqlite_master WHERE type='table' AND name NOT LIKE '%_bak'";
  FMResultSet *rs = [db executeQuery:sql];
  while ([rs next]) {
   NSString* tablename = [rs stringForColumn:@"name"];
   [newAddedTables addObject:tablename];
  }
 }];
 return newAddedTables;
}

SQL 2005-Datenbank-Upgrade 2008-Datenbank und 2005-Datenanhang 2008-Datensicherungsdokument

Problemlösung beim Upgrade der SQL-Server-Datenbankversion

Ausführliche Erklärung Zusammenfassung der Methoden zur Migration der Oracle-Datenbank zu MySQL (Bilder und Text)

Das obige ist der detaillierte Inhalt vonDetaillierte Beispiele für das Upgrade der IOS-Datenbank und die Datenmigration. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn