2016-12-12 5 views
0

Wir verwenden Liquibase-Changesets, um die Verwendung von MySQL und PostgreSQL zu unterstützen. Jetzt bin ich über die Tatsache gestolpert, dass MySQL Indizes für Fremdschlüssel automatisch erstellt, wo Postgre nicht.liquibase - Index für Postgresql-Fremdschlüssel erstellen

Frage: Wie stelle ich sicher, dass das DB-Schema Indizes für alle Fremdschlüssel unabhängig davon hat, welche DB tatsächlich verwendet wird?

aktualisieren 2017.02.28 Hier ist der Link auf eine Frage im Forum liquibase: http://forum.liquibase.org/#Topic/49382000001637005

Antwort

1

Werfen Sie einen Blick auf 'dbms' Voraussetzung hier: http://www.liquibase.org/documentation/preconditions.html. Sie können alle Postgesql-spezifischen Code dort setzen.

+0

Danke für das Aufzeigen von Vorbedingungen. Dies scheint jedoch eine gewundene Lösung zu sein, da ich dort alle fehlenden Indizes für Postgres manuell erstellen müsste. Für jeden neuen Fremdschlüssel, der eingeführt wird, sollte man auch daran denken, auch einen solchen postgresspezifischen Änderungssatz zu erstellen. – SebastianRiemer

+0

Noch ein weiterer Nachteil in der Illusion der RDBMS-Portabilität. –

+0

@SebastianRiemer ja, ich stimme zu. Habe gerade gesehen, dass es ein benutzerdefiniertes Änderungs-Tag gibt: http://www.liquibase.org/documentation/changes/custom_change.html. Wenn Sie also mit Java vertraut sind, können Sie versuchen, myForeignKey-Tags zu erstellen, die den Datenbankanbieter überprüfen und bei Bedarf eine Abfrage erstellen, um den Index zu erstellen. – dbf

0

Ich werde dies mit einem CustomChange-Command beheben:

public class AddForeignKeyConstraintWithIndex extends 
liquibase.change.core.AddForeignKeyConstraintChange implements 
liquibase.change.custom.CustomSqlChange { 

@SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"}) 
private ResourceAccessor resourceAccessor; 

@Override 
public void setUp() throws SetupException { 
} 

@Override 
public void setFileOpener(ResourceAccessor resourceAccessor) { 
    this.resourceAccessor = resourceAccessor; 
} 

@Override 
public SqlStatement[] generateStatements(Database database) { 
    SqlStatement[] result = super.generateStatements(database); 
    // Für Postgres zusätzlich Index anlegen 
    if (database instanceof PostgresDatabase) { 
     AddColumnConfig columnConfig = new AddColumnConfig(); 
     columnConfig.setName(getBaseColumnNames()); 
     columnConfig.setComputed(Boolean.FALSE); 

     SqlStatement createIndexStatement = new CreateIndexStatement(
       "ix_" + getConstraintName(), 
       getBaseTableCatalogName(), 
       getBaseTableSchemaName(), 
       getBaseTableName(), 
       Boolean.FALSE, 
       null, 
       columnConfig 
     ); 
     List<SqlStatement> list = new ArrayList<>(Arrays.asList(result)); 
     list.add(createIndexStatement); 

     return list.toArray(new SqlStatement[list.size()]); 

    } 
    return result; 
} 

Sie dann diese CustomChange wie dies nennen kann (mit genau den gleichen params wie für die AddForeignKeyConstraint-Anweisung):

<customChange 
class="eu.***.***.AddForeignKeyConstraintWithIndex" 
     baseTableName="tbl_interest_reference" 
     baseColumnNames="customer_id" 
     constraintName="finterest_ref_customer_fk" 
     referencedTableName="tbl_customer" 
     referencedColumnNames="customer_id" 
    />