Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.
Eigentlich hat sie ja jeder MySQL-Nutzer - die FEDERATED ENGINE - nur ist sie per Default nicht aktiviert. Mit Hilfe der FEDERATED Engine kann auf Tabellen von "fernen" Datenbanken zugegriffen werden. Die "ferne" Datenbank kann aber auch eine zweite MySQL Version auf dem lokalen Rechner sein.
* MySQL 5.5.9
* MySQL 5.1.55
/* my.ini / my.cnf auf MySQL 5.5.9 */
[mysqld]
...
# siehe auch (http://www.mysqlfanboy.com/2010/07/federated-tables/)
federated=On
Ob die FEDERATED Engine aktiv ist, läßt sich zum Beispiel mit SHOW ENGINES herausfinden.
mysql> show engines;
+------------+---------+----------------------------------------------------------------+--------------+-----+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+------------+---------+----------------------------------------------------------------+--------------+-----+------------+
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| FEDERATED | YES | Federated MySQL storage engine | NO | NO | NO |
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
+------------+---------+----------------------------------------------------------------+--------------+-----+------------+
8 rows in set (0.03 sec)
Die FEDERATED Engine kann bei mir (trotz gegenteiliger Meinung) mit (=ON oder =On oder =1 ) in der Konfigurationsdatei aktiviert werden. Ein Neustart der MySQL Datenbank ist allerdings nötig, damit die Konfiguration neu eingelesen wird.
Zuerst muss die Originaltabelle auf der "fernen" Datenbank (in meinem Fall die MySQL 5.1.55) mit einigen Daten erzeugt werden.
/* mysql 5.1.55-community */
CREATE TABLE city(
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(35) NOT NULL,
countrycode VARCHAR(3) NOT NULL,
district VARCHAR(20) NOT NULL,
population INT NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
INSERT INTO city VALUES
( NULL, 'Name-1', 'N-1', 'District-1', 0),
( NULL, 'Name-2', 'N-2', 'District-2', 0),
( NULL, 'Name-3', 'N-3', 'District-3', 0),
( NULL, 'Name-4', 'N-4', 'District-4', 0),
( NULL, 'Name-5', 'N-5', 'District-5', 0);
Nun kann die "lokale" Tabelle mit der FEDERATED ENGINE erzeugt werden. Ganz wichtig ist, es muss eine absolut identische Tabellenstruktur sein. Daten brauchen "lokal" keine eingefügt werden. Die holen wir uns ja aus der "fernen" Datenbank.
/* mysql 5.5.9 MySQL Community Server (GPL) */
CREATE TABLE city_remote(
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(35) NOT NULL,
countrycode VARCHAR(3) NOT NULL,
district VARCHAR(20) NOT NULL,
population INT NOT NULL,
PRIMARY KEY (id)
) ENGINE = FEDERATED
connection='mysql://username:passwort@localhost:3306/testdatenbank/city';
/* noch eine leere "lokale" city Tabelle die später gefüllt wird */
CREATE TABLE city(
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(35) NOT NULL,
countrycode VARCHAR(3) NOT NULL,
district VARCHAR(20) NOT NULL,
population INT NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
Auf der MySQL 5.5.9 Datenbank führen wird nun folgende Abfrage aus.
/* MySQL 5.5.9 */
mysql>SELECT * FROM city_remote;
ERROR 1430 (HY000): : 2003 : Can't connect to MySQL server on 'localhost' (10061)
So (Listing 5:) sieht es aus, wenn keine Verbindung zur Remotedatenbank hergestellt werden kann. Sei es weil sie "down" ist oder die Verbindungsdaten falsch sind. Und so sieht das Ganze aus, wenn es funktioniert..(Listing 6:)
/* MySQL 5.5.9 */
mysql>SELECT * FROM city_remote;
+----+--------+-------------+------------+------------+
| id | name | countrycode | district | population |
+----+--------+-------------+------------+------------+
| 1 | Name-1 | N-1 | District-1 | 0 |
| 2 | Name-2 | N-2 | District-2 | 0 |
| 3 | Name-3 | N-3 | District-3 | 0 |
| 4 | Name-4 | N-4 | District-4 | 0 |
| 5 | Name-5 | N-5 | District-5 | 0 |
+----+--------+-------------+------------+------------+
5 rows in set (1.01 sec)
/* MySQL 5.5.9 */
mysql>SELECT * FROM city_remote;
+----+--------+-------------+------------+------------+
| id | name | countrycode | district | population |
+----+--------+-------------+------------+------------+
| 1 | Name-1 | N-1 | District-1 | 0 |
| 2 | Name-2 | N-2 | District-2 | 0 |
| 3 | Name-3 | N-3 | District-3 | 0 |
| 4 | Name-4 | N-4 | District-4 | 0 |
| 5 | Name-5 | N-5 | District-5 | 0 |
+----+--------+-------------+------------+------------+
5 rows in set (0.00 sec)
Der erste Select "dauert" relativ lang, der zweite identische Select ist schnell (ein Query Cache wird aber nicht laut Doku unterstützt).
mysql> explain select * from city_remote;
+----+-------------+-------------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | city_remote | ALL | NULL | NULL | NULL | NULL | 5 | |
+----+-------------+-------------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
Wie man sieht, ist auch ein EXPLAIN auf die ferne Datenbank möglich. Dies ist eine extrem praktische Möglichkeit bei einer Fernbetreuung.
INSERT INTO city
SELECT * FROM city_remote;
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
Mit dieser doch sehr einfachen Methode haben wir uns die Daten aus der "fernen" Datenbank (Tabelle: city_remote) in unsere "lokale" Datenbank (Tabelle: city) kopiert.
SELECT COUNT(*)
FROM city_remote cr
JOIN city c
ON c.id = cr.id
WHERE cr.id = 5;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
Auch ein JOIN über Datenbankgrenzen hinweg ist möglich. Sicherlich wird dies - je nach Datenmenge - nicht performant sein. Da für den JOIN einiges an Daten über das Netzwerk transportiert werden muss.
Die FEDERATED Engine bietet nicht die gleichen Möglichkeiten wie InnoDB oder MyISAM. Normale SELECT, INSERT, UPDATE und DELETE sind erlaubt, aber ALTER TABLE, Transaktionen, Cache etc. werden nicht unterstützt. Details dazu bitte in der Dokumentation unter Kapitel 14.7.3. der jeweiligen MySQL-Version nachlesen.
Die FEDERATED Engine bietet interessante Möglichkeiten, aber die Doku dazu ist dünn und ob diese Speicher-Engine "produktiv" eingesetzt werden sollte ist unklar. Nichts desto trotz bietet sie praktische Möglichkeiten für die Administration.
Creating FEDERATED tables with a stored procedure
Developed In: SQL — Contributed by: Roland Bouman
http://forge.mysql.com/tools/tool.php?id=54