Ist das Hinzufügen von Indizes zu einer Drupal-Datenbank sicher?

12

Ich habe darüber gesucht und gelesen, aber ich habe nichts Bestimmtes zum Thema des Hinzufügens von Indizes zu Drupal-Tabellen gesehen (sowohl core als auch contrib).

Mein Hauptanliegen ist, was mit benutzerdefinierten Indizes passiert, wenn Sie Kern- oder Contrib-Code aktualisieren und Schemaänderungen auftreten. Was passiert in diesem Fall?

BEARBEITEN:

Ich denke, ein gewisser Kontext könnte helfen. Ich befasse mich hauptsächlich mit dem Hinzufügen von Indizes zu Tabellen, um die Leistung der Site zu optimieren (Abfragen, die im langsamen Abfrageprotokoll angezeigt werden, Seiten mit langsamen Ansichten usw.). Dies kann das Hinzufügen eines Index zu einer Tabelle in einem anderen Modul beinhalten. Beispielsweise

  1. Ich installiere Modul foo
  2. Modul foo erstellt Tabelle foo
  3. Ich füge der Tabelle einen Index hinzu foo
  4. Das Modul fooverfügt über ein Update, das das Schema ändert

Was geschieht?

mpdonadio
quelle

Antworten:

7

Ja, dies könnte zu Problemen führen.

Wenn ein Modul etwas mit der Spalte tun möchte, für die Sie einen Index hinzugefügt haben, entfernt es seine eigenen Indizes und führt dann die beabsichtigte Operation aus.

Was genau passiert, hängt von Ihrem Datenbanktyp und der tatsächlich ausgeführten Operation ab. Beispielsweise funktioniert eine Umbenennung der Spalte in MySQL einwandfrei, schlägt jedoch in PostgreSQL fehl. Wenn jedoch versucht wird, diese Spalte zu löschen (möglicherweise nach der Migration von Daten in eine andere Tabelle / Spalte), schlägt dies fehl.

Die Wahrscheinlichkeit, dass dies passiert, ist relativ gering, zumindest für kleinere Updates (hängt jedoch vom tatsächlichen Modul ab. Ich füge normalerweise keine Änderungen hinzu, die zu kleineren Releases führen könnten), aber es ist möglich.

Mein Vorschlag wäre, dass Sie versuchen, mit den Modulbetreuern zusammenzuarbeiten. Wenn die problematischen Abfragen vom Modul selbst stammen, werden die Betreuer die Indizes wahrscheinlich gerne hinzufügen, wenn Sie einen Patch bereitstellen. Stellen Sie die DESCRIBE-Ausgabe der problematischen Abfragen vor und nach dem Hinzufügen des Index bereit. Stellen Sie auch einen Patch zur Verfügung, der das Schema aktualisiert (einschließlich einer Aktualisierungsfunktion, um es für vorhandene Installationen festzulegen).

Jemand, der aktiv an leistungsbezogenen Dingen arbeitet und das oben Genannte wirklich gut macht, ist hier ein Beispiel: http://drupal.org/node/983950

Berdir
quelle
2

Wie in DatabaseSchema_pgsql :: changeField und in db_change_field () berichtet :

WICHTIGER HINWEIS: Um die Datenbankportabilität zu gewährleisten, müssen Sie alle Indizes und Primärschlüssel, die das geänderte Feld verwenden, explizit neu erstellen.

Das bedeutet, dass Sie alle betroffenen Schlüssel und Indizes mit db_drop_ {primary_key, unique_key, index} () löschen müssen, bevor Sie db_change_field () aufrufen. Übergeben Sie zum erneuten Erstellen der Schlüssel und Indizes die Schlüsseldefinitionen als optionales Argument $ new_keys direkt an db_change_field ().

Angenommen, Sie haben:

$schema['foo'] = array(
  'fields' => array(
    'bar' => array('type' => 'int', 'not null' => TRUE)
  ),
  'primary key' => array('bar')
);

und Sie möchten foo.bar so ändern, dass es seriell ist und als Primärschlüssel verbleibt. Die richtige Reihenfolge ist:

db_drop_primary_key($ret, 'foo');
db_change_field($ret, 'foo', 'bar', 'bar',
  array('type' => 'serial', 'not null' => TRUE),
  array('primary key' => array('bar'))
);

Ein ähnlicher Code wird für Drupal 7 gemeldet.

Denken Sie daran, dass Sie meiner Erfahrung nach keinen Primärschlüssel entfernen können, der ein serielles Feld verwendet. Auf Drupal 6 bekam ich jedes Mal einen Fehler, wenn ich das versuchte. Das habe ich auf Drupal 7 nicht ausprobiert.

Abgesehen davon kenne ich kein anderes Problem, das Sie mit Datenbankindizes haben könnten.

Das Hinzufügen eines Index zu einer Datenbanktabelle, die aus einem anderen Modul erstellt wurde, würde ich nicht empfehlen, weil:

  • Ein Modul löscht keinen Index für ein Feld, das geändert wird, wenn das Modul selbst diesen Index nicht erstellt hat. Dies ist für das Modul nicht möglich, da es den Namen des Index nicht kennt.
  • Das Ändern einer Datenbanktabelle, die von einem anderen Modul erstellt wurde, ist keine gute Idee, auch wenn das Modul ein Kernmodul ist. Wenn es ein anderes Modul gibt, das dieselbe Tabelle ändert, wie könnten die Module mit Konflikten umgehen, die sie miteinander haben, oder mit den Änderungen, die das Kernmodul auf seine eigene Datenbank anwenden würde?

Wenn die Datenbanktabelle aus einem anderen Modul (einem Kernmodul oder einem Modul eines Drittanbieters) erstellt wird, würde ich vorschlagen, eine Featureanforderung für das Modul zu öffnen und einen Anwendungsfall für die Verwendung eines neuen Index bereitzustellen. Wenn es Leistungsprobleme gibt, kann das Hinzufügen eines Index die gewünschte Maßnahme sein.

Wenn Sie einer aus einem anderen Modul erstellten Tabelle auf Ihrer eigenen Site einen Index hinzufügen möchten, müssen Sie sich auf alle Änderungen vorbereiten, die Sie bei jeder Aktualisierung des Moduls an Ihrem benutzerdefinierten Modul vornehmen müssen, bevor Sie es auf Ihrer eigenen Site installieren .
Sie können entscheiden, ob die Mehrarbeit die Leistung wert ist, die Sie erhalten. Persönlich halte ich es jedoch nicht für wert.

kiamlaluno
quelle
Vielen Dank. Wie würde das funktionieren, wenn ich einer Tabelle einen Index hinzufüge, um eine langsame Abfrage zu bekämpfen, und nicht nur eine Änderung an meinem eigenen Modul? Ich werde versuchen, meine Frage so zu bearbeiten, dass sie etwas klarer ist, wenn ich die Gelegenheit dazu bekomme.
mpdonadio
3
Sie können auch DB Tuner verwenden , um zu wissen, welche Indizes erstellt werden müssen.
Tostinni
@tostinni Ja, die Frage bezog sich fast direkt auf die Umsetzung der Empfehlungen von DB Tuner.
mpdonadio