php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 24.10.2010, 22:12  
Neuer Benutzer
 
Registriert seit: 24.10.2010
Beiträge: 5
PHP-Kenntnisse:
Anfänger
Morik befindet sich auf einem aufstrebenden Ast
Standard 3 MySQL-Tabellen per JOIN verknüpfen

Guten Tag zusammen,
Ich bin zur Zeit dabei meine Datenbanken zu Normalisieren und entsprechende Abfragen an die neuen Strukturen anzupassen.
Dabei bin ich nun auf ein Problem gestoßen welches ich leider so nicht selbstständig gelöst bekomme
Bisher hatte ich (grob) folgende Tabelle mit entsprechenden Spalten:
Zitat:
myinfos
id (int)
text (varchar)
infotyp1 (int)
infotyp2 (int)
infotyp3 (int)
infotyp4 (int)
length (int)
In den Spalten infotyp1-x sind die Vorkommnise verschiedener Schlüsselinformationen innerhalb des textes vermerkt, anhand derer ich später spezifische texte suchen kann.
Die entsprechende Abfrage dazu sah dann etwa wie folgt aus:
PHP-Code:
 SELECT text 
FROM myinfos
WHERE 
AND (infotyp1 <= "2")
AND (
infotyp2 <= "0")
AND (
infotyp3 <= "1")
AND (
infotyp4 <= "1")
ORDER BY length DESC
LIMIT 0 
10 
Die Abfrage ging auch sehr schnell usw und erfüllte gut seinen Zweck.
Nun haben sich allerdings mit der Zeit immer mehr "infotyp"en angesammelt, sodass ich an die Grenze von 16 Spalten für nen Index stieß und die ganze tabelle zudem extrem unübersichtlich wurde. Drum hab ich mich mal rangesetzt und hab die eine Tabelle versucht in 3 sinnvolle umzuwandeln was dann etwa so aussah:
Zitat:
myinfos
id (int)
text (varchar)
length (int)
Zitat:
zw_tabel
id (int)
id_info (int)
id_type (int)
counter (int)
Zitat:
info_type
id (int)
info_type (varchar)
Als info noch kurz die etwaige Größe der Tabellen:
myinfos: über 100k Datensätze
zw_tabel: über 1mio Datensätze
info_type: ~20 Datensätze

Soweit so gut, hab ich in nem Text den Infotyp 1 mindestens einmal wird zur Verknüpfung in der zw_tabel nen datensatz angelegt, keine Vorkommnisse bedeuten kein Datensatz^^

Nun versuche ich also im grunde die ganz oben gepostete Abfrage anzupassen und hab dabei folgendes überlegt:
PHP-Code:
SELECT m.text
FROM zw_tabel x
LEFT JOIN info_type i ON 
x.id_type  i.id )
LEFT JOIN myinfos m ON x.id_info  m.id )
WHERE
x.counter <AND i.info_type 'bli')
OR ( 
x.counter <AND i.info_type  'bla')
OR ( 
x.counter <AND i.info_type  'blubb')
ORDER BY m.length DESC
LIMIT 0 
10 
Nun meine Probleme:
1. Ich schaffe es nicht ORDER BY sinnvoll einzusetzen, nutze ich die Sortierung braucht die abfrage sehr lange (weit über 10 secs). Die länge gibt gleichzeitig Informationen über die Qualität des Datensatzes, und ist daher ein wichtiges Kriterium. Ich hab versucht dazu verschiedene sinnvolle Indices anzulegen jedoch ohne Erfolg...
2. Bekomme ich auch Ergebnisse mit nicht genannten info_type, ich hab versucht diese mit "i.info_type IN (1,2,3,4)" in der where-Bedingung rauszufiltern, leider ohne Erfolg...

Ich hoffe ich hab alle Infos die vll gebraucht werden genannt und dass mir vll einer helfen kann meine Abfrage zu vervollständigen
Morik ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 24.10.2010, 23:05  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.266
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Hallo und willkommen im Forum!

Ein Index auf myinfos.length bringt keine Beschleunigung? Kannst du statt "bli", "bla", "blubb" Integer-Konstanten verwenden?
Kannst du die info_type-Bedingung statt in WHERE in die ON-Bedingung einbauen?

Probier das ganze mal. Ein Index muss auf allen Spalten, die du für WHERE/ON oder ORDER BY verwendest, gesetzt werden. Dadurch verlangsamen sich allerdings die Einfüge/Bearbeitungs-Operationen gegebenenfalls.
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 25.10.2010, 09:15  
Erfahrener Benutzer
 
Registriert seit: 21.12.2009
Beiträge: 415
PHP-Kenntnisse:
Fortgeschritten
G.Schuster ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Ein JOIN bezieht sich immer auf die beiden Tabellen, zwischen denen er steht - ein JOIN von myinfos mit info_type macht also überhaupt keinen Sinn, da verwundert es auch nicht, dass du falsche Werte erhältst.
Many2Many muss Tabelle A über die Verknüpfungstabelle X auch mit Tabelle B verbinden (A-X-B), nicht wie bei dir X-B-A.
Beachte dabei aber auch die Bedeutung von RIGHT/LEFT JOIN, INNER/OUTER JOIN etc.
Das Ganze könnte/sollte/müsste dann wohl in etwa so aussehen:
PHP-Code:
SELECT `m`.`text`
FROM `myinfos` AS `m`
LEFT JOIN `zw_table` AS `zwON `m`.`id` = `zw`.`id_info`
RIGHT JOIN `info_type` AS `iON `zw`.`id_type` = `i`.`id`
WHERE (`zw`.`counter` < AND `i`.`info_type` = 'bli') OR (`zw`.`counter` < AND `i`.`info_typeIN('bla''blubb'))
ORDER BY `m`.`lengthDESC
LIMIT 0
10 
Ich hab dir mal eine recht hilfreiche Aufstellung der verschiedenen JOINs angehängt.
// Edit: die dank Forensoftware nicht nutzbar ist...wer verbricht solche Einstellungen?
Dann halt so:
Miniaturansicht angehängter Grafiken
3-mysql-tabellen-per-join-verknuepfen-joins.jpg  
__________________
actra.development - Schwabstr. 2 - 70825 Münchingen
www.actra.de/velopment/ - eMail: php.de@actra.de
Zend Certified Engineer for PHP5

Geändert von G.Schuster (25.10.2010 um 09:19 Uhr).
G.Schuster ist offline   Mit Zitat antworten
Alt 25.10.2010, 15:47  
Neuer Benutzer
 
Registriert seit: 24.10.2010
Beiträge: 5
PHP-Kenntnisse:
Anfänger
Morik befindet sich auf einem aufstrebenden Ast
Standard

Hallo nochmal und danke für die Antworten !

@Chriz:
Die Infotypen auf integer zu setzen wäre zwar prinzipiell möglich (und wurde auch bisher ähnlich gehandhabt) setzt aber voraus dass ich entsprechende infos dann im php-Teil als array hardcode was ich in Zukunft gerne vermeiden wollte, um eine höhere Flexibilität zu gewährleisten (in der Tabelle sind auch noch nen paar zusätzliche Infos zu den entsprechenden Typen wir ne kurze Beschreibung usw die ich beim erstellen eines geeigneten Abfrageformulars bei Bedarf auslese)
Ansonsten wäre es natürlich einfacher aus dem 3 tabellen-Problem auf ein 2 Tabellen-Problem zu reduzieren^^
Zu der Idee mit dem einbinden der Bedingungen in die ON-Klausel: soweit ich das verstanden habe sollte man dies nicht tun (steht zumindest im MySQL-Handbuch) zumal ich mir da auch gerade nicht ganz sicher bin wie ein entsprechendes Konstrukt aussehen müsste...


@G.Schuster:
Danke für deinen Vorschlag, dieser macht es nun zum ersten mal möglich bei einer Abfrage sinnvoll und schnell nach der Länge zu sortieren
Allerdings habe ich mit dem Anpassen der Abfrage noch eine kleine Schwierigkeit:
Mit der Where-Bedingung
PHP-Code:
`i`.`info_typeIN('bla''bla''blubb'
wollte ich eigentlich erreichen dass die gesuchten Datensätze nur diese drei Typen haben darf, ein 4ter wie z.B. 'boesertyp' hingegen soll nicht mit dem Datensatz verknüpft sein.
PHP-Code:
 SELECT `m`.`text`
FROM `myinfos` AS `m`
LEFT JOIN `zw_table` AS `zwON `m`.`id` = `zw`.`id_info`
RIGHT JOIN `info_type` AS `iON `zw`.`id_type` = `i`.`id`
WHERE 
`i`.`info_typeIN('bla''bla''blubb')
ORDER BY `m`.`lengthDESC
LIMIT 0
10 
Mit der obigen Anpassung versuchte ich nun genau dies zu erreichen, was jedoch nur dazu führt dass die Abfrage fast 1 minute benötigte...
Morik ist offline   Mit Zitat antworten
Alt 25.10.2010, 16:03  
Erfahrener Benutzer
 
Registriert seit: 21.12.2009
Beiträge: 415
PHP-Kenntnisse:
Fortgeschritten
G.Schuster ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Poste bitte die CREATE-Syntax der Tabellen und Beispieldaten, damit man testen kann, idealer Weise bitte als SQL-Datei zum direkten Einspielen.
__________________
actra.development - Schwabstr. 2 - 70825 Münchingen
www.actra.de/velopment/ - eMail: php.de@actra.de
Zend Certified Engineer for PHP5
G.Schuster ist offline   Mit Zitat antworten
Alt 25.10.2010, 16:41  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.266
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Wenn du die Zeilen erst in der WHERE-Bedingung beschränkst ist das kartesische Produkt eben riesig groß, bei der ON-Bedingung wird es nicht größer als nötig. Das ist zumindest mein aktuelles Wissen. Ein Test hätte ja nicht geschadet.
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 25.10.2010, 17:56  
Neuer Benutzer
 
Registriert seit: 24.10.2010
Beiträge: 5
PHP-Kenntnisse:
Anfänger
Morik befindet sich auf einem aufstrebenden Ast
Standard

@Chris:
dazu hatte ich mir bisher keine Gedanken gemacht...

@G.Schuster:
Ich hab mal ne kleine Test-DB mit Zahlen zusammen gebastelt, das Muster entspricht dem der Original-DB, nur wurde bei der hier zur Veranschaulichung nur Zahlen und deren Teilbarkeit verwendet.

Ne Beispielabfrage könnte nun z.B. so aussehen:

PHP-Code:
  SELECT `m`.`text`
FROM `myinfos` AS `m`
LEFT JOIN `zw_table` AS `zwON `m`.`id` = `zw`.`id_info`
RIGHT JOIN `info_type` AS `iON `zw`.`id_type` = `i`.`id`
WHERE 
`i`.`info_typeIN('TeilbarDurch02''TeilbarDurch03''TeilbarDurch07')
ORDER BY `m`.`lengthDESC
LIMIT 0
10 
Also bis zu 10 Zahlen in der DB gesucht werden die sich durch 2 , 3 und 7 Teilen lassen aber nicht durch 4, 5, 6 usw
Allerdings spuckt die Abfrage z.B. auch die Zahl 1080 aus obwohl diese auch z.B. durch 15 Teilbar ist (und das auch richtig in der zw.table steht^^)
Angehängte Dateien
Dateityp: zip testdb.sql.zip (25,6 KB, 7x aufgerufen)
Morik ist offline   Mit Zitat antworten
Alt 25.10.2010, 19:17  
erc
Erfahrener Benutzer
 
Registriert seit: 02.01.2009
Beiträge: 730
PHP-Kenntnisse:
Fortgeschritten
erc wird schon bald berühmt werden
Standard

Zitat:
Zitat von Morik Beitrag anzeigen
Guten Tag zusammen,
Ich bin zur Zeit dabei meine Datenbanken zu Normalisieren und entsprechende Abfragen an die neuen Strukturen anzupassen.
[...]
In den Spalten infotyp1-x sind die Vorkommnise verschiedener Schlüsselinformationen innerhalb des textes vermerkt, anhand derer ich später spezifische texte suchen kann.
Die entsprechende Abfrage dazu sah dann etwa wie folgt aus:
PHP-Code:
 SELECT text 
FROM myinfos
WHERE 
AND (infotyp1 <= "2")
AND (
infotyp2 <= "0")
AND (
infotyp3 <= "1")
AND (
infotyp4 <= "1")
ORDER BY length DESC
LIMIT 0 
10 
Die Abfrage ging auch sehr schnell usw und erfüllte gut seinen Zweck.

[...]

Als info noch kurz die etwaige Größe der Tabellen:
myinfos: über 100k Datensätze
zw_tabel: über 1mio Datensätze
info_type: ~20 Datensätze
Die neue Struktur passt nicht zur Aufgabe und bei der Datenmenge wird das ganze damit wahrscheinlich unpraktikabel. Erstens in der "zw_tabel" Tabelle hast du immer zw_tabel = myinfos * info_type, weil du die Null-Zuordnungen mit speichern musst, anonsten kannst du folgendes nicht abbilden:

PHP-Code:
(infotyp2 <= 0
Zweitens, wenn ich von einer gleichmässigen Verteilung der Infotypen ausgehen und die Anzahl ausser acht lasse bedeutet folgende Abfrage

PHP-Code:
AND (infotyp1 <= "2")
AND (
infotyp2 <= "0")
AND (
infotyp3 <= "1")
AND (
infotyp4 <= "1"
das die Datenbank 400.000 Datensätze verarbeiten muss. Beim Orginal hat es bedeutet einmal in den Index zu schauen. Ganz gewaltiger Unterschied...

Query sehe so aus:
PHP-Code:
SELECT 
    myinfos
.text,
    
COUNT(*) AS anzahl
FROM
    info_type INNER JOIN
    zw_tabel ON 
(...) INNER JOIN
    myinfos
WHERE
    
(
        (
x.counter <AND i.info_type 'bli') OR
        (
x.counter <AND i.info_type  'bla') OR
        (
x.counter <AND i.info_type  'blubb') OR 
        (
x.counter AND i.info_type  'böseinfo'
    )
GROUP BY
    myinfos
.id
HAVING
    anzahl 
'$anzahl der bedingungen'
ORDER BY
    myinfos
.length 
Man könnte natürlich auch für jeden Infotyp ein Join machen (bzw. 2 in dem Fall), damit könnte die Abfrage doch recht effektiv gelöst werden, aber schön ist was anderes.

PHP-Code:
SELECT 
    myinfos
.text
FROM
    myinfos INNER JOIN
    zw_tabel 
AS con1_zt ON (...) INNER JOIN
    info_type 
AS con1_it ON (con1_zt.info_id con1_it.info_id AND con1_it.info_type 'bli')  INNER JOIN
    zw_tabel 
AS con2_zt ON (...) INNER JOIN
    info_type 
AS con2_it ON (con2_zt.info_id con2_it.info_id AND con2_it.info_type 'blub'usw...
ORDER BY
    myinfos
.length 
Hier wäre die komplexität auch recht hoch, profetiert aber durch den Index.

Zitat:
Zitat von G.Schuster Beitrag anzeigen
Ein JOIN bezieht sich immer auf die beiden Tabellen, zwischen denen er steht.
Das ist falsch. Was vor dem JOIN steht ist völlig irrelevant, die Beziehung wird durch die Join Bedingung geregelt.
Schau dir den Query von Morik mal genau an, das ist nicht X-B-A sondern unterm Strich auch A-X-B.

Zitat:
Zitat von Chriz Beitrag anzeigen
Wenn du die Zeilen erst in der WHERE-Bedingung beschränkst ist das kartesische Produkt eben riesig groß, bei der ON-Bedingung wird es nicht größer als nötig. Das ist zumindest mein aktuelles Wissen. Ein Test hätte ja nicht geschadet.
Woher kommt dieser Scheiß mit dem Kreuzprodukt? Das ist absoluter quatsch... kein gängies RDBMS macht sowas. Die bilden alle ihr Ergebnis Zeilenweise.
erc ist offline   Mit Zitat antworten
Alt 25.10.2010, 19:56  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.266
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Zitat:
Zitat von erc Beitrag anzeigen
Woher kommt dieser Scheiß mit dem Kreuzprodukt? Das ist absoluter quatsch... kein gängies RDBMS macht sowas. Die bilden alle ihr Ergebnis Zeilenweise.
Ich geb zu ich habe diese Info nur aufgeschnappt. Macht aber Sinn, wenn man manche Queries durch kleine Änderungen vom Minuten-Bereich in den Millisekunden-Bereich optimieren kann.

Woher hast du deine Informationen?
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 25.10.2010, 21:02  
erc
Erfahrener Benutzer
 
Registriert seit: 02.01.2009
Beiträge: 730
PHP-Kenntnisse:
Fortgeschritten
erc wird schon bald berühmt werden
Standard

Zitat:
Zitat von Chriz Beitrag anzeigen
Ich geb zu ich habe diese Info nur aufgeschnappt. Macht aber Sinn, wenn man manche Queries durch kleine Änderungen vom Minuten-Bereich in den Millisekunden-Bereich optimieren kann.

Woher hast du deine Informationen?
Das stand glaub ich letztens in der Brigitte drin. Nein, ich weiß einfach wie eine Datenbank intern arbeitet. Das hier in einem Forum zu erläutern würde aber leicht den Rahmen sprengen. Man kann das ganze aber auch ganz leicht testen...

EXPLAIN SELECT * FROM b AS b1, b AS b2 WHERE b1.id = b2.id
EXPLAIN SELECT * FROM b AS b1 INNER JOIN AS b2 ON (b1.id = b2.id)
EXPLAIN SELECT * FROM b AS b1, b AS b2 HAVING b1.id = b2.id

Bei einem wird das Kreuzprodukt gebildet und danach gefilter... nur welchem

Warum man Queries vom Minuten auf Milisekunden trimmen kann ist auch recht einfach erklärt. Dumme Queries! Weit hergeholtes Beispiel... wir haben zwei Tabellen: Telefonnummern und Personen. Aufgabe such mir alle Telefonnummern deren Inhaber mit B anfängt, aber du musst von der Tabelle mit den Telefonnummern anfangen zu suchen und nicht von der Tabelle mit Personen die alphabetisch sortiert ist. Solche dummen Aufgaben senden manche an die Datenbank. In SQL ausgedrück:

PHP-Code:
SELECT
COUNT
(*)
FROM
telnr LEFT JOIN
persons ON 
(telnr.person_id persons.person_id)
WHERE
persons
.name LIKE 'b%' 
Aufgabe sinnvoll formuliert:
PHP-Code:
SELECT
COUNT
(*)
FROM
persons INNER JOIN
telnr ON 
(telnr.person_id persons.person_id)
WHERE
persons
.name LIKE 'b%' 
Bei erstern muss die Datenbank zu jeder Nummer schauen ob der Inhaber mit B anfängt, bei der anderen Variante sucht sie die Nummern der Inhaber mit B. (ausser die Datenbank ist der Meinung umgedreht sei besser, mit dem INNER JOIN kann die Datenbank selbst entscheiden was sie macht)

Ansonsten sind fehlende Indizies auch ein massives Problem. Letzter Query als Beispiel, diesmal ist auf telnr.person_id kein Index. Das heißt die Datenbank fängt für _jede_ gefundene Person an, die Tabelle telnr zu scannen bis sie die person_id gefunden hat. Vorher war die kompläxität durch den Index logaritmisch zur Anzahl Datensätzen, jetzt linear. Und da sind wir ganz schnell bei 200ms vs. 5min. 20.000 Personen * 100 Operation um die Nummer zu finden vs. 20.000 Personen * 10.000.000 Operation um die Nummer zu finden.
erc ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Tabellen Verknüpfen.. Hendrik PHP Tipps 2010 1 18.05.2010 00:40
mysql select if und else 2 tabellen sandrasandra Datenbanken 15 28.04.2010 00:37
Problem mit Abfrage für Suche (zwei Tabellen verknüpfen - JOIN?) Schlendrian Datenbanken 4 26.04.2010 12:55
[Erledigt] Geschwindigkeitsprobleme mit großer normalisierter Datenmenge (Apache Logs franzcois Datenbanken 9 01.04.2010 13:33
[Erledigt] join(?) über 3 Tabellen kn0wledge PHP Tipps 2010 13 18.03.2010 16:21
Tabellen miteinander verknüpfen Suzi Datenbanken 12 27.05.2009 11:40
brauche Hilfe bei mysql JOIN serious-cool Datenbanken 2 22.03.2009 20:29
[Erledigt] Join über 3 Tabellen BlackPanther Datenbanken 2 11.03.2009 19:56
PHP Array in MYSQL Tabellen schreiben Matt Datenbanken 1 26.02.2008 19:43
Problem mit Inner join Jabi Datenbanken 15 09.05.2006 14:10
tabellen verknüpfen philips Datenbanken 26 06.05.2006 11:15
LEFT OUTER JOIN für mehr als 2 Tabellen ? Alpha Centauri Datenbanken 4 05.04.2006 16:18
3 tabellen verknüpfen tomson Datenbanken 2 21.01.2006 12:53
3 Tabellen mit JOIN verknüpfen? becks123 Datenbanken 6 13.08.2005 00:05
INNER JOIN mit 4 tabellen ??? Dragon26mFR Datenbanken 5 01.05.2005 18:51

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
http://www.php.de/datenbanken/73198-3-mysql-tabellen-per-join-verknuepfen.html, mysql join, mysql tabellen verknüpfen, mysql join drei tabellen, mysql tabellen verknüpfen join, mysql join 3 tables, verknüpfungstabelle mysql, mysql suche über drei tabellen, mysql inner join über 3 tabellen, mysql join as, mysql inner join 3 tabellen, sql verknüpfungstabelle join, mysql drei tabellen zusammen, mysql join mehrere tabellen, mysql tabellen suche verknüpfen, mysql join 3 tabellen, mysql join or verknüpfung, mysql tabelle verknüpfung, mysql verknüpfung von tabellen mit bedingung, mysql joins verknüpfen

Alle Zeitangaben in WEZ +2. Es ist jetzt 10:54 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum