MySQL: SELECT * FROM * (alle Tabellen in einer Datenbank) geht nicht. Wie mache ich das dann?
Als Beispiel nehme ich mal eine fiktionale Datenbank "passagiere" einer Fluggesellschaft.
In dieser Datanbank gibt es die Tabellen "flug001", "flug002", [...], "flug999".
In jeder Tabelle gibt es die Spalten "name", "vorname", "anschrift".
Ich möchte in der Datenbank "passagiere" eine neue Tabelle "alle_passagiere" erstellen mit den Spalten "name", "vorname", "anschrift".
Ich hätte ja gedacht man macht das mit INSERT INTO alle_passagiere(name, vorname, anschrift) SELECT * FROM * oder SELECT * FROM FULL DATABASE oder SELECT * FROM ALL, aber hat alles nicht funktioniert.
Ich führe den Befehl bereits in der Datenbank "passagiere" aus.
Hat jemand eine schnelle Lösung ohne alle Flug-Tabellen einzeln abzutippen?
4 Antworten
In dieser Datanbank gibt es die Tabellen "flug001", "flug002", [...], "flug999".
Nein solche Tabellen gibt es in dieser Datenbank nicht.
In dieser Datenbank gibt es nur eine Tabelle namens "flug" und die hat eine Spalte "flugnummer".
Und dann gibt es in dieser Datenbank noch eine Tabelle "passagier" und die hat die Spalten "flugnummer", "name", usw.
die ganze Tabelle "passagiere" nach der Flugnummer durchsuchen
Partitionierung, Indexierung
Nein, das müsstest Du nicht. Nur müsstest Du dein Wissen über Datenbankstrukturen und Indizes etwas auffrischen. Mach das, es lohnt sich. Und es ist erstaunlich einfach.
Was ist denn das für ein Modell ich erstell doch nicht pro Flug eine Tabelle wenn die Daten alle die gleiche Form haben.
Hmm ok kann ich auf jedenfall für MSSQL nich bestätigen. Die Daten werden dort ohne Order by nach dem Clustered index oder mindestens dem primary key sortiert. Aber stimmt ich hab nich wirklich Ahnung das wurd mir immer nur von dem Datenbankspezialisten in meiner Arbeit so erzählt.
Ja hast recht so extrem meint ich das jetzt auch nich. Aber die Aussage das gruppierte Indizes nicht mehr existieren versteh ich nicht. Die Orte der Daten werden doch trotzdem in Baumstruktur nach der Reihenfolge des clustered index abgelegt. Und die nicht gruppierten Indizes geben dann nur Werte der Clustered Indizes in Baumstruktur an. Wenn eine Zeile dazwischen eingefügt wird kann die Adresse der Zeile einfach zur entsprechenden Page hinzugefügt werden da dort sowieso schon Platz dafür ist.
Das ist die Technologie der 70ger Jahre. Meine Datenbank ist mehr als 20 Jahre alt und da kann ich sowohl auf einzelne Spalten als auch Gruppen einen Index einrichten, auf- oder absteigend und optional auch eindeutig. Gespeichert werden die Daten immer in der Reihenfolge ihres Eingangs dort, wo gerade Platz ist (am Tabellenende oder an einer freigewordener Stelle wegen Löschung).
Man kann die gespeicherte Reihenfolge sogar testen, indem man die Daten ohne Sort anzeigt.
Achso wenn du also in der Passagier Tabelle schnelle abfragen auf einen Flug haben willst solltest du darüber nachdenken den clustered index an die Flug id zu vergeben.
Ein clustered index wurde in den 70-ger bis 80-ger Jahren verwendet. Heute gibt es sowas nicht mehr. Vielleicht noch bei Filesystemen, aber nicht bei Datenbanken. Das würde ein ständiges Reorganisieren erfordern, ähnlich wie das Defragmentieren bei den Filesystemen. Die Art und Weise der physikalischen Verwaltung wird schon deshalb nicht mehr zur Adressierung von Anwenderdaten herangezogen, weil die Anwendung gar nicht mehr weiß, wo die Daten gespeichert werden. Am besten wird das am Internet veranschaulicht. Wenn man da eine datenbank einrichtet, stehen die Daten irgendwo in der Cloud, vermutlich sogar auf einem RAID-Sytem mehrfach auf verschiedenen Platten verteilt.
Also ehrlichgesagt hab ich das noch nie gehört. Ich hab bis jetzt aber auch nur mit mssql gearbeitet. Dort wird der clustered index wie gesagt sogar standardmäßig auf den Primary key gelegt. Deshalb zweifle ich etwas an deiner Aussage. Was ich nicht wirklich weiß welche Spalten man als clustered index setzen sollte. Es kann schon sein das es nicht so klug ist die flug id als clusterd index zu nehmen da ich gerade gelesen hab das man keine nicht eindeutigen Spalten nehmen soll.
Da gibt es vermutlich mehrere Dinge, von denen Du noch nichts gehört hast.
Wenn Du Deine Daten nach Deinem Primärschlüssel ablegst, wie willst Du dann einen Satz einfügen, der laut Schlüssel irgendwo in der Mitte rein muss, wo auf der Platte kein Platz mehr frei ist?
Was glaubst Du, wie schwierig das damals war, so einen Satz einzufügen, als man noch darauf angewiesen war, Sätze in der geordneten Reihenfolge abzulegen? Die Sätze waren aneinander gekettet, indem jeder Satz die Plattenadresse des folgenden Satzes enthalten hat. Beim Einfügen wurde der neue Satz dort eingefügt, wo noch Platz war oder, was meistens zutraf, hinten angehängt. Die Kette wurde an der Stelle aufgebrochen und mit dem hinten eingefügten Satz neu verkettet. Weil der Lesekopf der Platte dadurch mehr Bewegung benötigte, wurde die Verarbeitung auch immer langsamer. Man musste in regelmäßigen Abständen die daten reorganisieren, also alles auf Band auslagern und dann neu auf die Platte laden. Heute gibt es zum Glück bessere Methoden. Die Anordnung der Daten auf der Platte wird heute in keiner Datenbank mehr berücksichtigt, schon lange nicht mehr.
Ich sag dir eins mach nie sowas absurdes nur um Geschwindigkeit zu sparen weil du dadurch eh keine sparst. Eine Datenbank ist darauf spezialisiert Daten möglichst schnell bereitzustellen. Du solltest dich über Indizes informieren wenn du einen primary key anlegst wird dieser immer standardmäßig als clustered index angelegt. Heißt in dieser Reihenfolge werden deine Daten auf der Platte abgelegt. Wenn du also eine Abfrage auf den clustered Index machst ist es kein Problem für deine Datenbank diese Daten schnell zu finden (genauer gesagt steigt die Geschwindigkeit logarithmisch an was vernachlässigbar ist). Du kannst auch noch weiter Indizes anlegen die dann aber nur Zeiger auf den clustered index sind und somit etwas langsamer sind. Deine Anfrage auf alle Passagiere wird bei vielen Datensätze ewig dauern.
Doch, weil das Auslesen der Tabelle eines Fluges viel schneller geht als in einer Passagierdatenbank mit Millionen Passagieren die Passagiere eines bestimmten Fluges rauszufiltern.
Bei richtig konzipierter Datenbank spielt die Anzahl der Datensätze in einer Tabelle praktisch keine Rolle. Hier war wohl ein Laie am Werk, der nicht weiß, wie man einen Index richtig einrichtet.
Außerdem kann ich mir nicht vorstellen, dass unter einer Flug-Nr Mllionen von Fahrgästen gespeichert werden, auch wenn das Flugzeug ggf. mehrmals hin- und herfliegen würde.
Das bildest Du Dir ein, weil Du Dich mit Datenbanken nicht auskennst. Wenn Du die Datenbank richtig konzipierst, hat die Datenmenge nur einen geringfügigen Einfluss auf die Zugriffsgeschwindigkeit.
Stell Dir mal die Mautkontrolle für LKW vor, wo jede Sekunde Hunderte von LKWs an den bundesweit installierten Stationen erfasst und die Daten an eine zentrale Datenbank weitergeleitet werden. Denkst Du, dass man da für jeden LKW eine eigene Tabelle eingerichtet hat?
Vielen Dank an mastema666. Ich habe seine MySQL-Befehle in meinem php-Quelltext verwendet und bin somit (etwas umständlich) zur Lösung gekommen: Hier der Quellcode:
<html><head></head><body> <?php
echo "php geladen<br>";
$verbindung = mysql_connect("localhost", "benutzer", "passwort")
or die ("Anmeldung fehlgeschlagen");
if ($verbindung == true){
echo "verbunden<br>";
}
$datenbank = 'passagiere';
$datensatz = 'fluege';
$datensatz2 = "alle_passagiere";
$spalte = "flug_nr";
$datenbank_waehlen = mysql_select_db("$datenbank") or die ("Datenbank nicht gefunden");
if ($datenbank_waehlen == true){
echo "Datenbank gewaehlt<br>";
}
$erstellen = "CREATE TABLE $datensatz ($spalte VARCHAR(20))";
$erstellt = mysql_query($erstellen);
if ($erstellt == true){
echo "Datensatz erstellt<br>";
}
$eintragen = "INSERT INTO $datensatz ($spalte)
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='$datenbank'";
$eingetragen = mysql_query($eintragen);
if ($eingetragen == true){
echo "Fluege eingetragen<br>";
}
$auslesen = "SELECT * FROM $datensatz";
$ergebnis = mysql_query($auslesen);
while($row = mysql_fetch_object($ergebnis)) {
$eintrag = "INSERT INTO $datensatz2
(name, vorname, anschrift) SELECT * FROM $row->flug_nr";
$eingetragen2 = mysql_query($eintrag);
if ($eingetragen2 == true){
echo "Passagierdaten eingetragen";
}
}
?>
SELECT Name, Vorname, Anschrift FROM Passagiere;
Wenn du das unbedingt als einzelne Tabelle brauchst kannst dus ja in n view packen obwohl das keinen Sinn ergibt.

Wenn ich die Datenbank so strukturiert hätte, wie du es hier beschreibst, müsste man, wenn man alle Passagierdaten eines bestimmten Fluges auslesen möchte, die ganze Tabelle "passagiere" nach der Flugnummer durchsuchen. Dies würde im Alltag bei Millionen Passagieren ewig dauern. Viel schneller geht es, einfach die Passagierliste eines bestimmten Fluges aufzurufen.