Dieser Artikel beschreibt MySQL, ein effektives Tool zur Entwicklung von E-Commerce- und anderen komplexen, dynamischen Websites unter Verwendung von Datenbanken von Drittanbietern. MySQL ist ein schneller, multithreadfähiger SQL-Server mit vollem Funktionsumfang. Neben der Beschreibung der grundlegenden Architektur des MySQL-Systems enthält dieser Artikel auch einfache, in Tcl und C++ geschriebene Beispiele, die Sie bei der Entwicklung datenbankgestützter Webanwendungen unterstützen. Dieser Artikel beschreibt MySQL, ein effektives Tool zur Entwicklung von E-Commerce- und anderen komplexen, dynamischen Websites unter Verwendung von Datenbanken von Drittanbietern. MySQL ist ein schneller, multithreadfähiger SQL-Server mit vollem Funktionsumfang. Neben der Beschreibung der grundlegenden Architektur des MySQL-Systems enthält dieser Artikel auch einfache, in Tcl und C++ geschriebene Beispiele, die Sie bei der Entwicklung datenbankgestützter Webanwendungen unterstützen.
Eine Anwendung, die große Mengen an Informationen speichern oder darauf zugreifen muss, kann von der Verwendung eines Datenbankprodukts eines Drittanbieters erheblich profitieren. Dies gilt insbesondere dann, wenn der Zugriff auf Informationen über mehrere Instanzen des Programms erfolgen muss. Webbasierte Anwendungen (einschließlich elektronischer Handel) sind hierfür gute Beispiele.
Warum eine eigenständige Datenbank verwenden?
Webserver müssen in ihren Verarbeitungsskripten die Möglichkeit haben, Informationen über ihren Status für den späteren Zugriff zu speichern. Obwohl es möglich ist, einfachere Methoden zu verwenden – etwa das Speichern in einer Textdatei oder das Entwickeln einer selbst erstellten Minidatenbank –, kann nur eine vollwertige Datenbankanwendung alle Dienste bereitstellen, die eine komplexere Webanwendung erfordert. Das Schreiben einer benutzerdefinierten anwendungsspezifischen Datenbank-Engine bietet keinen großen Nutzen, da für diesen Zweck einige frei verfügbare Softwarepakete verfügbar sind. Darüber hinaus entfällt durch die Verwendung einer Datenbank eines Drittanbieters auch die Notwendigkeit für Webentwickler, sich der Aufgabe der Entwicklung und Pflege einer Datenbank zu widmen.
MySQL-Datenbank
Die Integration von Datenbanken in Linux-Anwendungen kann durch den Einsatz von Skriptsprachen und kompilierten Systemsprachen wie C recht einfach sein. Die frei verfügbare MySQL-Datenbank (vertrieben unter der GNU Public License) bietet eine Reihe ausgefeilter SQL-Funktionen und lässt sich leicht in Anwendungen integrieren. MySQL ist schnell, multithreaded und unterstützt ANSI- und ODBC-SQL-Standards. Zusammen mit Software von Drittanbietern unterstützt MySQL transaktionssichere Tabellen für Anwendungen zur Transaktionsverarbeitung.
Hinweis: Was ist Transaktionsverarbeitung?
Eine Transaktion ist eine Reihe von Änderungen an einer Datenbank, die atomar durchgeführt werden müssen. Entweder müssen alle ausgeführt werden, oder keiner von ihnen muss ausgeführt werden. Beispielsweise bilden alle notwendigen Datenbankänderungen beim Verkauf eines Produkts im Web eine einzige Transaktion.
Die Datenbank muss sowohl den Kundenkontostand als auch den Produktbestand subtrahieren, andernfalls schlägt sie fehl und keiner der Vorgänge wird ausgeführt.
Ein Serverabsturz, aus welchem Grund auch immer, sollte nicht dazu führen, dass Transaktionen teilweise ausgeführt werden. Überhöhte Rechnungen, nicht gelieferte Produkte oder ungenaue Lagerbestände können beispielsweise die Folge unvollständig abgeschlossener Transaktionen sein.
Eine Datenbank, die die Transaktionsverarbeitung unterstützt, kann einen Satz Datenbankcode in einer Transaktion kapseln. Jeder Fehler während der Ausführung der Transaktion führt dazu, dass die Datenbank in den Zustand vor Beginn der Transaktion zurückgesetzt wird.
Dies wird durch die Führung eines Protokolls aller Datenbankvorgänge sowie einer Kopie der ursprünglichen Statustabelle erreicht, sodass Rollback-Vorgänge beim nächsten Neustart des Servers nach einem Ausfall möglich sind. Dieser Zeit- und Platzaufwand ist ein notwendiger Kompromiss für ein transaktionssicheres Datenbanksystem.
Ein einzelner MySQL-Server steuert eine Reihe von Datenbanken, auf die alle auf ähnliche Weise über den Server zugegriffen werden. Jede Datenbank besteht eigentlich aus einer Reihe beliebig vieler Tabellen, ähnlich im Konzept wie bei Benutzern anderer SQL-Datenbanken. Jede Tabelle besteht aus typisierten Datenspalten. Die Daten können ganze Zahlen, reelle Werte, Zeichenfolgen oder andere Typen sein, einschließlich roher Binärströme. Jede Zeile in der Tabelle ist ein in der Datenbank gespeicherter Datensatz.
MySQL ist als Client/Server konzipiert und strukturiert. Der Server mysqld kann auf jedem Computer ausgeführt werden, auf den über das Internet zugegriffen werden kann (vorzugsweise auf demselben Computer wie der Webserver oder so nah wie möglich, um angemessene Antwortzeiten zu gewährleisten). Der MySQL-Client verwendet Anfragen, um den MySQL-Server zu kontaktieren, um die Datenbank des Servers zu ändern oder abzufragen. In einer datenbankbasierten Webanwendung ist der Datenbank-Client der Webserver oder ein vom Webserver generiertes CGI-Skript. Diese Clients können in einer High-Level-Skriptsprache oder einer Low-Level-Systemsprache geschrieben sein, sofern für diese Sprache eine Datenbank-API vorhanden ist. Unter Linux sind die meisten Skriptsprachen in C implementiert, und da die MySQL-C-API vorhanden ist, sollte es einfach sein, MySQL-Unterstützung zu jeder vorhandenen Skriptsprache oder jedem vorhandenen Skripttool hinzuzufügen. Die meisten Skriptsprachen haben diesen Schritt bereits abgeschlossen.
MySQL-API
Die MySQL-API ist in einer Vielzahl von Sprachen verfügbar, darunter fast allen Sprachen, die tatsächlich zum Schreiben von Website-Backends verwendet werden. Mithilfe dieser APIs können wir einen MySQL-Client erstellen, der von einem Webserver gesteuert wird.
Die API (für den Datenbankzugriff) arbeitet im verbindungsbasierten Modus. Als Erstes muss der Client eine Verbindung zum MySQL-Server herstellen. Dazu gehört die ordnungsgemäße Authentifizierung der Verbindung mit einem dem Server bekannten Benutzernamen und Passwort. Nachdem die Verbindung hergestellt wurde, wählt der Server eine bestimmte Datenbank zur Verwendung aus. Sobald die Initialisierung festgelegt ist, kann die Clientanwendung (in unserem Fall das serverseitige CGI-Skript) auf zwei Arten mit der Datenbank interagieren: Sie kann reguläre SQL-Befehle ausführen, einschließlich des Hinzufügens und Löschens von Tabellen sowie des Hinzufügens von Datensätzen Sie können auch Abfragen für die Datenbank ausführen, die Ergebnisse zurückgeben. Die Abfrage generiert eine Reihe von Datensätzen, die der Abfrage entsprechen, und der Client kann dann einzeln auf die Datensätze zugreifen, bis alle Datensätze angezeigt wurden, oder der Client bricht den ausstehenden Datensatzabruf ab. Sobald das Skript die Arbeit mit der Datenbank beendet hat, wird die Verbindung zum Server geschlossen.
Um eine Website zu erstellen, die den Datenbankzugriff integriert, müssen Sie CGI-Skripte schreiben, um dynamische Ergebnisse basierend auf dem Datenbankstatus zu generieren. Webserver starten CGI-Skripte und geben dann entsprechend formatiertes HTML in ihren Standardausgabestream aus. Der Webserver erfasst den HTML-Code und sendet ihn an den Client zurück, als ob es sich um eine Anforderung für eine statische HTML-Seite handeln würde. Beim Generieren von HTML können Skripte die Datenbank ändern oder die Ergebnisse abfragen und in ihre Ausgabe integrieren.
Als Beispiel zur kurzen Erläuterung des obigen Prozesses fragt der folgende Code (geschrieben in C und Tcl) eine Datenbank ab, die eine Liste der von einem Unternehmen zum Verkauf stehenden Produkte enthält. Dies nutzt keineswegs alle Funktionen der MySQL-API in beiden Sprachen, sondern stellt ein schnelles und einfach erweiterbares Beispiel dar, das jeden SQL-Befehl auf den Inhalt der Datenbank ausführen kann. In diesem Beispiel zeigt das Skript alle Produkte unterhalb eines bestimmten Preises an. In der Praxis könnte der Benutzer den Preis in einen Webbrowser eingeben und ihn dann an den Server senden. Wir haben die Details zum Lesen von Umgebungsvariablen zur Bestimmung von HTML-Formularwerten weggelassen, da es sich nicht von der Ausführung in einem CGI-Skript unterscheidet, das keine Datenbank unterstützt. Der Übersichtlichkeit halber gehen wir davon aus, dass bestimmte Parameter (z. B. der abzufragende Preis) vorab festgelegt werden.
Der folgende Code wird in Tcl mithilfe der frei verfügbaren Tcl Generic Database Interface implementiert. Der Vorteil einer solchen Schnittstelle besteht darin, dass Tcl interpretiert wird und den Code schnell entwickeln und ändern kann.
Tcl-Beispiel
#Dieser Code druckt alle Produkte in der Datenbank aus
# die unter einem bestimmten Preis liegen (der als festgelegt gilt).
# vorher und in der Variablen targetPrice gespeichert)
# Die Ausgabe erfolgt im HTML-Tabellenformat, geeignet für CGI-Ausgabe
#laden Sie auch die SQL-Shared-Object-Bibliothek
#wurden mit der Bibliothek kompiliert, sodass diese Zeile überflüssig ist
Laden Sie /home/aroetter/tcl-sql/sql.so
#diese sind vorher genau definiert, oder sie könnten es
#wird an das Skript übergeben
set DBNAME „clientWebSite“;
set TBLNAME „products“;
setze DBHOST „backend.company.com“
setDBUSER „mysqluser“
setze DBPASSWD „abigsecret“
set targetPrice 200;
#mit der Datenbank verbinden
Handle setzen [sql connect $DBHOST $DBUSER $DBPASSWD]
sql selectdb $handle $DBNAME ;# Testdatenbank abrufen
#Führen Sie eine Abfrage mit dem angegebenen SQL-Code aus
SQL-Abfrage $handle „select * from $TBLNAME where price <= $targetPrice“
#HTML-Tabellenkopf ausdrucken
setzt „<table border=4>“
puts „<th>Product Id <th width=200>Description <th>Price ($)“
#Tabellenzeilen ausgeben – jede Abrufzeile ruft ein Ergebnis ab
#aus der SQL-Abfrage
while {[set row [sql fetchrow $handle]] != ""} {
set prodid [lindex $row 0]
Beschreibung festlegen [lindex $row 1]
Preis festlegen [lindex $row 2]
puts „<tr><td>$prodid <td align=center>$descript <td>$price“
}
setzt „</table>“
#empty den Abfrageergebnispuffer – sollte in diesem Fall bereits leer sein
SQL-Endquery-$handle
#Schließen Sie die Datenbankverbindung – in der Praxis dieselbe Verbindung
#wird für mehrere Abfragen verwendet
SQL-Disconnect $handle
Der folgende Code ist das entsprechende Skript, das in C++ unter Verwendung der offiziellen MySQL C++-API MySQL++ geschrieben wurde. Der Vorteil dieser Version besteht darin, dass sie kompiliert und daher schneller ist als interpretierte Sprachen. Datenbankcode, der häufig auf einer bestimmten Site verwendet wird, sollte in C oder C++ geschrieben werden und dann über Skripte oder direkt vom Webserver aus aufgerufen werden, um die Gesamtlaufzeit zu verbessern.
C++-Beispiel
#enthalten
#enthalten
#enthalten
const char *DBNAME = "clientWebSite";
const char *DBTABLE = "Produkte";
const char *DBHOST = "backend.company.com";
const char *DBUSER = "mysqluser";
const char *DBPASSWD = „abigsecret“:
int main() {
versuchen {
//Datenbankverbindung öffnen und abfragen
Verbindung con(DBNAME, DBHOST, DBUSER, DBPASSWD);
Abfrage query = con.query();
//gültigen SQL-Code in das Abfrageobjekt schreiben
query << "select * from " << DBTABLE;
//Führen Sie die Abfrage aus und speichern Sie die Ergebnisse
Ergebnis res = query.store();
//Schreibe den HTML-Tabellenheader aus
cout << "<table border=4>n";
cout << "<th>Produkt-ID <th width=200>Beschreibung"
<< "<th>Preis ($)" << endl;
Ergebnis::iterator curResult;
Reihenreihe;
//über jedes Ergebnis iterieren und es in eine HTML-Tabelle einfügen
for (curResult = res.begin(); curResult != res.end(); curResult++) {
row = *curResult;
cout << "<tr><td align=center>" << row[0]
<< "<td>" << row[1]
<< "<td>" << row[2] << endl;
}
cout << "</table>" << endl;
} Catch (BadQuery äh) {
// eine fehlerhafte Abfrage verarbeiten (normalerweise verursacht durch einen SQL-Syntaxfehler)
cerr << "Fehler: " << er.error << endl;
return -1;
} Catch (BadConversioner) {
//Konvertierungsfehler auch aus der Datenbank behandeln
cerr << "Fehler: "" << er.data << "" kann nicht in ein " konvertiert werden
<< er.type_name << ""." << endl;
return -1;
}
0 zurückgeben;
}
Sicherheit
Beim Erstellen webbasierter Anwendungen im Web gibt es einige Probleme, die Entwickler berücksichtigen müssen. Alle Probleme im Zusammenhang mit CGI-Programmen auf dem Webserver, wie z. B. Verarbeitungsberechtigungen des Webservers und Eingabeprüfungen auf der Skriptseite, müssen weiterhin berücksichtigt werden.
Darüber hinaus ist es auch notwendig, die Sicherheit des Datenbanksystems aufrechtzuerhalten. Dazu gehört die Sicherung des Berechtigungssystems des Datenbankservers und die Sicherung der Verbindungen von Datenbank-Clients zum Server.
MySQL bietet ein umfassendes Sicherheitssystem, das manche als „fortgeschritten, aber nicht standardmäßig“ bezeichnen. MySQL ermöglicht den Client-Zugriff basierend auf dem Benutzernamen, dem Client-Host und der Datenbank, auf die zugegriffen werden soll. Um ein sicheres System zu schaffen, lassen Sie alle Benutzer sichere Passwörter verwenden und gewähren Sie ihnen keinen Zugriff, den sie nicht unbedingt benötigen. Dazu gehören scheinbar harmlose Privilegien wie Handle-Privilegien, die es einem Benutzer ermöglichen, alle laufenden Prozesse anzuzeigen, einschließlich derjenigen, die die Passwörter anderer Benutzer ändern. Der beste Ansatz besteht darin, den Serverprozess selbst als unprivilegierter Unix-Benutzer auszuführen, damit bei einer Kompromittierung einer Datenbank nicht das gesamte System zum Absturz gebracht wird. Dies ähnelt dem Ausführen von httpd als Benutzer „nobody“ statt als „root“. Tabellen, die den Systemzugriff beschreiben, werden als separate MySQL-Datenbanken gespeichert und können vom MySQL-Root-Benutzer aktualisiert werden. Beachten Sie, dass der MySQL-Server Berechtigungen basierend auf MySQL-Benutzernamen gewährt, die sich von Unix-Benutzernamen unterscheiden. Es gibt jedoch einen MySQL-Root-Benutzernamen, der über vollständige Berechtigungen für die Datenbank verfügt. Sobald der Server feststellt, wer die verbindenden Clients sind und mit wem sie eine Verbindung herstellen möchten, wird der Zugriff auf der Grundlage eines bestimmten Satzes von Berechtigungen gesteuert. Um zu verhindern, dass Hostnamen in der Zugriffstabelle durch DNS gefälscht werden, können Sie die IP-Adressen aller Hosts eingeben oder den Server bitten, die IP-Adressen wieder in die ursprünglichen Hostnamen aufzulösen, um es anderen zu erschweren, DNS-Anfragen und -Antworten abzufangen .
Neben Serverzugriffstabellen muss auch die Kommunikation mit dem Server sicher sein. Bei der Anmeldung am Server vom Client aus wird das Passwort nicht im Klartext gesendet; alle nachfolgenden SQL-Befehle werden jedoch im Klartext gesendet. Für mehr Sicherheit verwenden Sie ssh, um die Portweiterleitung einzurichten. Es verschlüsselt die gesamte Kommunikation zwischen Server und Client und verhindert so, dass jemand sie während der Übertragung beobachten kann. Daten vom Client werden an den Port auf dem lokalen Computer des Clients gesendet, auf dem der lokale SSH-Server lauscht. Es wird vom lokalen SSH-Server verwendet, verschlüsselt und an den Remote-SSH-Server gesendet, der es entschlüsselt und an den MySQL-Server-Port weiterleitet.
In der Praxis besteht der sicherste Ansatz darin, den Datenbankserver auf demselben Computer wie den Webserver auszuführen und die vom Webserver generierten CGI-Skripte über UNIX-Sockets (native) mit dem MySQL-Server kommunizieren zu lassen. Mit dieser Einstellung kann der Datenbankadministrator alle Remoteverbindungen zum MySQL-Server deaktivieren. Wenn sich die Web- und Datenbankserver auf unterschiedlichen Maschinen befinden müssen, verschlüsseln Sie die gesamte Kommunikation zwischen ihnen oder verbinden Sie die beiden Maschinen über ihre eigenen dedizierten, physisch isolierten Netzwerke. Erstellen Sie nur ein Benutzerkonto (außer dem Root-Benutzer), das vom Webserver zum Anmelden beim Datenbankserver verwendet wird.
Datenbankgesteuerte Websites sind leistungsstarke Tools, mit denen Entwickler dynamische Websites erstellen können, die aktualisierte Informationen bereitstellen und es ermöglichen, dass vom Kunden initiierte Änderungen über mehrere Sitzungen hinweg bestehen bleiben. Der Einsatz von Back-End-Datenbanken ist für die Verwaltung von Benutzern von E-Commerce- und anderen Anwendungen unerlässlich. Durch die Verwendung frei verfügbarer Software ist es möglich, eine datenbankgesteuerte Site zu erstellen, die die Datenbankkonnektivität sicher in die bestehende CGI-Architektur der Site integriert.