Tabele de baze de date personalizate Menținerea bazei de date

Pe parcursul vieții tabelului dvs. personalizat, probabil veți găsi că trebuie să faceți modificări la ceea ce stochează sau cum îl stochează. Aceasta poate fi ca răspuns la necesitatea de a stoca mai multe (sau mai puține) date. Este posibil ca proiectarea inițială a bazei dvs. de date să nu aibă ca scop să se ocupe (eficient) de ceea ce cere acum baza dvs. de utilizator. În orice caz, trebuie să știm cum să ne adaptăm tabelul pentru a satisface noile noastre nevoi. Aceasta este ceea ce vom analiza în acest tutorial, și ne vom concentra în primul rând pe această funcție dbDelta () pe care am întâlnit-o în prima parte.


dbDeta

Din fericire, cea mai mare parte a lucrărilor legat de manipularea modificărilor bazei de date se face prin funcția WordPress dbDelta (). Am folosit această funcție în prima parte pentru a crea masa noastră, dar de fapt face mult mai mult decât atât: înainte de a efectua interogarea pe care am dat-o, verifică dacă tabela există deja. Dacă nu, creează tabelul, dar dacă există - compară diferența (de aici numele) și face niste schimbări. De aceea, în prima parte nu am verificat manual dacă tabela există deja.

Dacă tabela există deja, dar este diferită de tabela dată de SQL (de exemplu, tabela existentă are o coloană lipsă sau o coloană diferită de coloană), atunci dbDelta () aplică automat aceste actualizări. În acest fel, putem lansa o nouă versiune a plug-in-ului nostru, care modifică tabelul nostru prin aplicarea "dbDelta ()" cu SQL modificat. Aproape.

din pacate, dbDelta () nu se aplică toate schimbări. Să presupunem că în ultima noastră versiune de plug-in nu avem nevoie de o coloană și dorim să o eliminăm. Deci, o eliminăm din interogarea SQL în prima parte și în apelul de rutină de actualizare wptuts_create_tables (). După actualizare vom constata că coloana este încă acolo. Mai rău: actualizarea utilizatorilor de la vechea versiune la noua versiune va avea apoi o tabelă structural diferită de cea a celor care încep cu noua versiune.

Notă: dbDelta () este nu distructivă: adică va adăuga coloane lipsă sau va schimba coloanele modificate, dar nu va elimina coloanele sau indexurile.

Deci ce face? dbDelta () de fapt?

Să ne amintim de interogarea SQL la care trecem dbDelta () la crearea mesei:

 $ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log "(log_id bigint (20) nesemnate NOT NULL auto_increment, user_id bigint (20) nesemnificat NOT NULL implicit '0', activitate varchar (20) NOT NULL implicit 'actualizat', object_id bigint NULL implicit '0', object_type varchar (20) NOT NULL implicit 'post', data_activitate datetime NOT NULL default '0000-00-00 00:00:00', KEY PRIMARY (log_id), KEY user_id (user_id) ; "; dbDelta ($ sql_create_table);

Mai întâi extrage toate CREATE TABLE interogări (dvs. poate sa transmiteți mai multe interogări către dbDelta () o dată, separându-le de un ";", dar pentru a îmbunătăți lizibilitatea prefer să nu). Din aceasta este nevoie de numele tabelului, masă de $, și se execută

 $ wpdb-> get_results ("DESCRIBE $ table;");

Aceasta returnează o serie de coloane existente - fiecare coloană este de fapt un obiect care conține informații referitoare la respectiva coloană (numele, tipul, valoarea implicită etc.). De exemplu, nostru log_id coloana arata ca:

 Obiectul stdClass ([Field] => log_id [Type] => bigint (20) nesemnat [Null] => NO [Key] => PRI [Default] => [Extra] => auto_increment)

Dacă tabela nu există, atunci o matrice goală este returnată și tabela este creată. In caz contrar dbDelta () apoi trece prin fiecare linie a interogării date, extrage coloanele și le stochează într-o matrice $ cfields. Se procedează la fel cu fiecare dintre chei (inclusiv primar).

Apoi trece prin fiecare existent coloane. Dacă sunt prezente în matricea de mai sus, $ cfields, acestea sunt eliminate. Apoi, compară tipul lor, dacă nu se potrivesc, generează automat o valoare corespunzătoare ALTER TABLE interogare care trebuie efectuată mai târziu. După ce a făcut acest lucru, singurele coloane rămase în $ cfields sunt cele care nu există deja. Din aceasta generează și mai mult ALTER TABLE interogări pentru a crea aceste coloane.

Se execută apoi o procedură aproape identică pentru chei.


Ai grija

Capacitatea dbDelta () pentru a face toate aceste analize vine la un cost: fussiness de ceea ce va accepta (sau interpreta corect). De exemplu:

  • Fiecare parte a interogării (de exemplu, fiecare coloană și declarația cheie) trebuie să aibă o linie proprie. De exemplu
     user_id bigint (20) nesemnificat NOT NULL implicit '0', activitate varchar (20) NOT NULL default 'actualizat',

    va acționa ca și cum activitate coloana nu este prezentă. Formatul corect este:

     user_id bigint (20) nesemnificat NOT NULL implicit '0', activitate varchar (20) NOT NULL default 'actualizat',
  • Trebuie să utilizați CHEIE mai degrabă decât INDEX-ul său sinonim.
  • Orice cheie KEY trebuie să primească un nume. De exemplu, nu scrieți
    KEY (user_id)]

    ar trebui să fie

    KEY utilizator_id (user_id)

    (deși numele nu trebuie să fie același cu coloana).

  • Cheia PRIMARĂ nu ar trebui să primească un nume, ci mai degrabă trebuie să existe Două spații între CHEIA PRINCIPALA și declarația coloanei: (Log_id). De exemplu,
     TASTĂ PRIMARĂ (log_id),

    va provoca o eroare. Formatul corect este:

     TASTĂ PRIMARĂ (log_id),

Aceasta nu este o listă completă, ca regulă generală ar trebui să evitați spații suplimentare în jurul și între cuvinte cheie, cum ar fi CREA și MASA și nu ar trebui să existe spații suplimentare în jurul coloanelor. Intervalele din dbDelta () se bazează pe utilizarea preg_match () pentru a extrage informații din instrucțiunea SQL trecut - și ca atare, lucrurile pot merge prost destul de ușor dacă acea instrucțiune nu este formatată corespunzător.

Unele dintre aceste erori vor apărea în tăcere (de exemplu, dacă nu dați CHEIE un nume, dbDelta () o va păstra duplicat). Din acest motiv, este important să vă examinați manual tabelul (utilizând phpMyAdmin sau similar) pentru a verifica dacă codul dvs. funcționează corect.


Adăugarea sau modificarea coloanelor

Cu dbDelta (), acest lucru este foarte simplu - să presupunem că vrem să facem object_id un index, adăugați o coloană suplimentară user_ip pentru a stoca adresa IP a utilizatorului și a schimba tipul coloanei de activitate la varchar (30), pur și simplu înlocuim SQL Query original cu:

 $ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log "(log_id bigint (20) nesemnificat NOT NULL auto_increment, user_id bigint (20) nesemnificat NOT NULL implicit '0', user_ip varchar (15), activitate varchar bigint (20) nesemnate NOT NULL implicit '0', object_type varchar (20) NOT NULL implicit 'post', activity_date datetime NOT NULL implicit '0000-00-00 00:00:00', KEY PRIMARY (log_id), KEY user_id (utilizator_id), KEY object_id (object_id),) $ charset_collate; ";

Atunci ne asigurăm că sunăm wptuts_create_tables () în rutina de actualizare, iar modificările vor intra în vigoare.


Eliminarea coloanelor

De cand dbDelta () nu va elimina coloanele, pur și simplu eliminarea liniei corespunzătoare din interogare nu va fi suficientă (este totuși necesar totuși). În schimb, trebuie să facem lucrurile manual.

Mai întâi, extrageți o gamă de columuri existente:

 $ existent_columns = $ wpdb-> get_col ("DESC $ wpdb-> wptuts_activity_log", 0);

Apoi, dacă coloanele pe care dorim să le îndepărtăm sunt prezente, le putem elimina cu un ALTER TABLE interogare:

 $ remove_columns = matrice ('object_id'); // Array de coloane pentru a elimina $ remove_columns = array_intersect ($ remove_columns, $ existing_columns); dacă (! empty ($ remove_columns)) $ wpdb-> interogare ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP COLUMN" .implode ('DROP COLUMN', $ remove_columns).

Eliminarea cheilor

La fel cum am făcut și cu coloanele, obțineți mai întâi o serie de indici:

 $ existent_keys = $ wpdb-> get_col ("SHOW INDEX FROM $ wpdb-> wptuts_activity_log WHERE Key_name! = 'PRIMARY';

Apoi, dacă cheile pe care dorim să le ștergem, le putem elimina la fel ca mai sus, dar acum le folosim DROP INDEX

 $ remove_keys = array ('user_id'); // Array de chei pentru a elimina $ remove_keys = array_intersect ($ remove_keys, $ existing_keys); dacă (! empty ($ remove_keys)) $ wpdb-> interogare ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP INDEX" .implode ('DROP INDEX', $ remove_keys).

Actualizare rutină

Acum că știm cum să facem upgrade la baza noastră de date - să vedem cum ar trebui să ne ocupăm de acest lucru în plug-in-ul nostru. Vom stoca toată manipularea actualizării în interiorul funcției: wptuts_activity_log_upgradecheck (). Rețineți că va fi activat cârligul de activare a pluginului nu să fie declanșat atunci când actualizați un plug-in: pentru a ne asigura că rutina noastră de actualizare își face treaba, admin_init.

Pentru a verifica ce rutine de actualizare trebuie să efectuăm, vom stoca versiunea plug-in în baza de date. Vom compara această versiune (versiunea instalată) cu versiunea curentă (activată) a plug-in-ului:

  • Dacă nu există o versiune în baza de date, este o instalare proaspătă și vom adăuga versiunea curentă
  • În cazul în care există este o versiune în baza de date, și este versiunea curentă, nu facem nimic
  • În caz contrar, este o versiune mai veche, așa că vom trece prin toate rutinele de actualizare necesare.
 add_action ('admin_init', 'wptuts_activity_log_upgradecheck'); funcția wptuts_activity_log_upgradecheck () // Versiunea pluginului curent activat $ current_version = '1.3'; // Versiunea de bază de date - poate fi necesară actualizarea. $ instal_version = get_option ('wptuts_activity_log_version'); dacă (! $ installed_version) // Nu există o versiune instalată - vom presupune că tocmai a fost instalată proaspăt add_option ('wptuts_activity_log_version', $ current_version);  elseif ($ installed_version! = $ current_version) / * * Dacă aceasta este o versiune veche, efectuați unele actualizări. * / // Versiunea instalată este înainte de 1.1 - upgrade la 1.1 dacă (version_compare ('1.1', $ installed_version)) // Cod pentru upgrade la versiunea 1.1 // Versiunea instalată este înainte de 1.3 - upgrade la 1.3 dacă (version_compare '1.3', $ installed_version)) // Cod pentru upgrade la versiunea 1.3 // Baza de date este acum actualizată: actualizați versiunea instalată la ultima versiune update_option ('wptuts_activity_log_version', $ current_version); 

Notă: Este important ca această rutină de actualizare să fie prezentă în iniţială deoarece va adăuga versiunea inițială (1.0) la baza de date. Dacă nu faceți acest lucru, pot apărea probleme pentru upgrade-urile de la 1.0 la 1.1.

Fiecare dintre rutinele de actualizare individuale ar trebui să asigure că baza de date este "actualizată" utilizând codul discutat în secțiunile anterioare. Foarte important, dacă facem orice modificare în CREATE TABLE SQL, trebuie să vă amintiți să executați această interogare dbDelta () (în exemplul nostru, sunând wptuts_create_tables () ca parte a rutinei de actualizare) pentru ca modificările să aibă efect.

Fiți atenți la modul în care gestionați actualizările atunci când le utilizați dbDelta. Rețineți că unii utilizatori ar putea să actualizeze două sau mai multe actualizări. Deci, dacă astfel de modificări nu pot fi făcute în paralel, atunci va trebui să faceți upgrade în etape, numind "dbDelta ()" de mai multe ori, făcând modificările corespunzătoare pentru etapa respectivă.


Dezinstalați rutina

În timp ce suntem la el, să ne uităm la curățarea după noi înșine atunci când plug-in-ul dezinstalat. Acestea sunt, în general, rutine foarte simple: eliminați pur și simplu tabela de baze de date, orice opțiuni salvate și orice lucrare cron care poate fi activată de plug-in-ul dvs. Cârlig noastre de rutină pe cârligul de dezinstalare folosind cârlig de dezinstalare registru ()

 înregistrați cârligul de dezinstalare (__ FILE __, 'wptuts_uninstall_plugin'); funcția wptuts_uninstall_plugin () global $ wpdb; // Eliminați masa noastră (dacă există) $ wpdb-> interogare ("DROP TABLE IF EXISTĂ $ wpdb-> wptuts_activity_log"); // Eliminați versiunea bazei de date delete_option ('wptuts_activity_log_version'); / * Eliminați orice alte opțiuni instalate de plug-in-ul dvs. și ștergeți toate lucrările cron plug-in * /
Cod