sql >> Database >  >> RDS >> Mysql

PDO MySQL-back-upfunctie

Dat back-upscript is belachelijk en niemand zou er een andere versie van moeten maken. Ik heb dat script eerder gezien, evenals soortgelijke pogingen, en ze hebben veel problemen:

  • Geeft geen scheiding tussen tabelnamen in back-ticks
  • Verwerkt geen NULL's
  • Verwerkt geen tekensets
  • Verwerkt geen binaire gegevens
  • Maakt geen back-up van VIEWs
  • Maakt geen back-up van TRIGGER's of OPGESLAGEN PROCEDURES of OPGESLAGEN FUNCTIES of EVENEMENTEN
  • Gebruikt een verouderde mysql-extensie (maar dit is waarom je een PDO-versie wilt, nietwaar?)
  • Gebruikt addlashes() in plaats van een echte MySQL-escape-functie.
  • Voegt alles toe gegevens voor alle tabellen in één hele lange reeks, voordat de hele inhoud wordt uitgevoerd. Dit betekent dat je je hele database in één string moet kunnen opslaan, wat vrijwel zeker je maximale PHP-geheugenlimiet zal opblazen.

Zie ook mijn eerdere antwoord over het ongelukkige back-upscript van David Walsh:

Opnieuw uw opmerking:

Lees de opmerkingen op de pagina waarnaar u linkt. Veel mensen hebben problemen geïdentificeerd en sommigen hebben oplossingen of op zijn minst suggesties.

Het feit dat dit script alles in één string toevoegt, is een dealbreaker, denk ik, maar het zou niet moeilijk moeten zijn om het script te wijzigen om het uitvoerbestand eerst te openen , voer vervolgens de gegevens van elke rij uit tijdens de lus en sluit vervolgens het bestand na de lus. Dat is nogal een no-brainer, ik weet niet zeker waarom het script dat niet doet. Maar het is vrij duidelijk dat het script niet erg goed is getest.

Maar goed, ik zou niet proberen dit wiel opnieuw uit te vinden. Mysqldump of mydumper doen dit werk prima. FWIW, u hoeft mysqldump niet uit te voeren op dezelfde server waar de database zich bevindt. Mysqldump ondersteunt een optie voor --host zodat u mysqldump overal kunt uitvoeren om een ​​back-up van een externe database te maken, zolang firewalls uw client niet blokkeren om verbinding te maken. Kortom, als je een PHP-app kunt verbinden met de database vanaf een clienthost, kun je mysqldump verbinden.

Als dat echt geen optie is, dan zou ik de database dump-functie van phpmyadmin gebruiken. Deze zijn volwassen en goed getest en ze dumpen alles correct. Hier is een artikel dat beschrijft hoe je de dump-functie gebruikt:

http://www.techrepublic. com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/

[Mijn opmerkingen kopiëren van uw antwoord:]

Dit gaat over code-review, wat niet het doel is van StackOverflow. Maar kort:

  • geen goede ondersteuning voor NULL (je converteert ze naar '');
  • de tabelnamen worden niet consequent afgebakend;
  • niet-ANSI dubbele aanhalingstekens gebruiken als tekenreeksscheidingstekens;
  • het gebruik van gebufferde query's op enorme tabellen zal de maximale geheugenlimiet van PHP breken;
  • het toevoegen van alle rijen voor een grote tabel zal de maximale geheugenlimiet van PHP overtreden;
  • addlashes() gebruiken in plaats van PDO::quote();
  • controleren op queryfouten alleen aan het einde van de functie;
  • niet controleren op mislukte aanmaak van bestanden;
  • gzip-extensie kan niet worden geladen
  • Ondersteunt waarschijnlijk nog steeds geen UTF8-gegevens.

Ja, dit is beter dan het originele David Walsh-script. :-)

NULL is niet hetzelfde als '' in SQL (behalve in Oracle, maar ze voldoen in dit geval niet aan de SQL-standaard). Zie MySQL, beter om NULL of leeg in te voegen tekenreeks?

Ik heb de code over het probleem met de geheugenlimiet verkeerd gelezen. U schrijft uitvoer voor elke rij, dus dat is goed (tenzij de rij een blob van 1 GB of iets dergelijks bevat).

Maar u moet niet zomaar een enkele INSERT-instructie uitvoeren met een door komma's gescheiden reeks rijen. Zelfs mysqldump --extended-insert voert een eindige lengte van gegevens uit en start vervolgens een nieuwe INSERT-instructie. Het criterium is of de lengte van de INSERT-instructie past binnen het optieargument voor --net-buffer-length .

In ANSI SQL worden enkele aanhalingstekens '' gebruikt om letterlijke tekenreeksen of letterlijke datums af te bakenen. Dubbele aanhalingstekens "" worden gebruikt om id's zoals tabelnaam of kolomnamen af ​​te bakenen. Standaard behandelt MySQL ze hetzelfde, maar dit is niet standaard. Zie Gebruiken verschillende databases verschillende naamcitaten? . Als u probeert uw back-upgegevens te importeren op een MySQL-server waar u SET SQL_MODE=ANSI_QUOTES , zal het importeren mislukken.

Voorbeeld:query('SELECT * FROM '.$table); en in feite elk van de andere gevallen waarin u $table in een query gebruikt. Je hebt de tabel maar één keer afgebakend, in de INSERT-instructie wordt je script uitgevoerd.

MySQL herkent back-ticks altijd als identifier-scheidingstekens, en enkele aanhalingstekens voor strings/dates. Maar dubbele aanhalingstekens veranderen van betekenis, afhankelijk van de SQL_MODE die ik noemde. U kunt niet aannemen welke SQL_MODE van kracht is op de MySQL-instantie waarop u herstelt, dus het is het beste als u de back-ticks gebruikt voor identifiers en enkele aanhalingstekens voor strings. De reden dat u ze zou afbakenen als u uw tabel opvraagt, is dat u tabelnamen kunt hebben die gereserveerde SQL-woorden zijn, of die speciale tekens bevatten, enz.

U kunt alle numerieke typen invoegen zonder scheidingstekens. Alleen tekenreeksen en datums hebben scheidingstekens nodig. Zie dev.mysql.com/doc/refman/5.6/en/literals.html



  1. wat verhindert dat PHP verbinding maakt met mijn MySQL-database?

  2. MySQL ASIN() Functie – Retourneer de boogsinus van een getal

  3. Hoe u de huidige datum en tijd kunt krijgen met tijdzoneverschuiving in PostgreSQL

  4. Hoe bepaalde Hex-waarden en Char()-waarden te vinden in een MySQL SELECT