Andavos: Mehr Tables oder mehr Einträge??

Hallo,
also ich schreibe einen Counterscript für mehr als eine Statistik, sprich Besucher können sich auf der Seite anmelden und sehen dann ihre Statistik.

Damit ich jetzt nicht mehrere tausend Tables erhalten, habe ich mich entschlossen immer 15 Accounts in eine Table zu speicher.
Eine ID (Counterid) kennzeichnet dann die zugehörigen Daten zu den Accounts.

Jetzt weiß ich aber nicht wie ich es bei eine Tables machen soll.
Diese bekommt pro Monat ca. 350 Einträge (je nach Besucheranzahl) und es wird für 6 Monate gespeichert.
Also insgesamt 350*6= 2100 Einträge pro Account.

Wenn jetzt 15 Kunden die Table benutzen, so sind das dauerhaft ca. 32 000 Einträge in der einen Table

Dieses Problem (2100 Einträge pro Monat pro Account) betrifft insgesamt 3 Tables.
Die andere Tables haben deutlich weniger Einträge, darum lassen wir die jetzt außen vor.

Also als Datenbank benutze ich MySQL und PHP für den Counter.

Jetzt wollte ich mal fragen was besser ist:

Angenommen dort wären 500 User. Wenn ich für jeden Kunden diese 3 Tables erneut erstelle, wären es 1500 Tables in der Datenbank.
Allerdings würde in jeder nur ca. 2100 Einträge stehen.

Wenn ich die Kunden zusammenlege (immer 15er Gruppen), so wären es nur 100 Tables, allerdings hätte jeder rund 32 000 Einträge.

Ich wollte mal fragen wie es mit der Stabilität aus sieht. Ist es eher Problematisch wenn man 1500 Tables oder 100 Tabelles mit je 32 000 Einträgen hat.

Was würdet ihr Empfehlen??
Vielleicht hat ja jemand Erfahrungen mit größeren Projekten bzw. kennt einen Link zu einem guten Artikel wo es dort weiter erklärt wird.
Oder ab wieviel Einträgen/Table sollte man lieber eine andere Tabelle benutzen.

Der Server wird bei 500 Personen ein echter Root-Server sein, allerdings möchte ich nicht das die User sich über die schlechte Stabilität der Datenbank aufregen.
Denn Erreichbarkeit ist bei einem Counterdienst sehr wichtig ;)

Danke im vorraus.

MFG
Andavos

  1. Hi,

    Angenommen dort wären 500 User. Wenn ich für jeden Kunden diese 3 Tables erneut erstelle, wären es 1500 Tables in der Datenbank.

    Daten mit der selben Struktur kommen *immer* in die selbe Tabelle. Plane Dein DB-Layout so, dass es *nie* geändert wird[1].

    Oder ab wieviel Einträgen/Table sollte man lieber eine andere Tabelle benutzen.

    Ab 10^2.371, vorher nicht.

    Cheatah

    [1] Natürlich wird es in der Praxis ab und zu kleine Anpassungen geben, aber auf keinen Fall aufgrund der Zahl der Datensätze. Damit hat ein DB-Layout *nichts* zu tun!

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hi,

      Angenommen dort wären 500 User. Wenn ich für jeden Kunden diese 3 Tables erneut erstelle, wären es 1500 Tables in der Datenbank.
      Daten mit der selben Struktur kommen *immer* in die selbe Tabelle. Plane Dein DB-Layout so, dass es *nie* geändert wird[1].

      Im Prinzip ja.

      Aber:

      Wenn es sich um Daten unterschiedlicher Kunden handelt, könnte man ggf. darüber nachdenken, aus Sicherheitsgründen die Daten der einzelnen Kunden komplett zu trennen - in komplett getrennten, aber identisch strukturierten, Datenbanken, mit unterschiedlichen User-Accounts, so daß jeder Kunde nur auf seine eigenen Daten zugreifen kann.

      cu,
      Andreas

      --
      Warum nennt sich Andreas hier MudGuard?
      Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
      1. Hallo,
        ihmm hab mich glaub ich nicht richtig ausgedrückt.

        »»Daten mit der selben Struktur kommen *immer* in die selbe Tabelle.

        Dort ist z.B. die Herkunft von Besuchern.

        Falls für jeden Kunden diese Table angelegt wird:
        id
        tag
        monat
        jahr
        herkunft

        Falls 15 Leute eine Table erhalten:
        id
        counterid
        tag
        monat
        jahr
        herkunft

        Also die Strucktur ist die gleiche, nur das dort noch eine Counterid steht, die die Daten einem Account zuweisen.

        Naja wenn jeder Kunde jetzt 350 Herkunft URLs hat und die Speicherzeit 3 Monate ist, so sind das 2100 Einträge/pro Kunde.
        Das betrifft 3 Accounts

        Entweder ich erstelle bei 500 Accounts 1500 (3*500) Tables mit je 2100 Einträgen oder

        ich erstelle 100 Tables (3/15 * 500) mit je 32 000 Einträge.
        Jeder Kunde würde ja nur 3/15 Tables brauchen, und beim Prinzip Nr. 1 würde er 3 Tables brauchen.

        Darum die Frage: Wo ist die Performance und die Stabilität besser??

        MFG
        Andavos

        1. Hi,

          Entweder ich erstelle bei 500 Accounts 1500 (3*500) Tables mit je 2100 Einträgen oder
          ich erstelle 100 Tables (3/15 * 500) mit je 32 000 Einträge.

          oder Du erstellst eine Tabelle mit 3.200.000 Einträgen. Die beiden anderen Optionen sind nämlich widersinnig. Die Daten habe alle die selbe Struktur! Damit gehören sie auch alle in die selbe Tabelle.

          Darum die Frage: Wo ist die Performance und die Stabilität besser??

          Bei einer Tabelle. Genau wie die Wartbarkeit und die Nutzung. Und so ziemlich alles andere, was mit Datenbanken zu tun hat.

          Cheatah

          --
          X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
          X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. Hallo,
            das Problem bei 3 Mio Einträgen würde ich darin sehen, dass der Datenbankserver dies nicht schafft, denn irgendwann ist die Grenze erreicht.

            Denn bei immer wenn ein Besucher auf eine Homepage geht (500 Kunden * 250 Seitenaufrufe/Tag = 125 000 DB Zugriffe) müssen die Tables durchsucht werden, ob es einen Eintrag für die Eigenschaft schon gibt, wenn nicht muss ein neuer Angelegt werden.

            Das bedeutet, der Server muss 125 000 mal am Tag rund 9 Mio. (3 Tables á 3 Mio Einträge) Einträge durchsuchen und ggf. einen neuen Eintrag erstellen.

            Wenn ich es aufteile, so müsste nur 125 000 mal am Tag rund 96 000 (3 Tables á 32k Einträge) oder 125 000 mal am Tag rund 6 300 (3 Tables á 2100 Einträge) durchsuchen.

            Bei der Variante wo alle Daten in 1 Table steht, könnte ich mir gut vorstellen, das die Zugriffszeiten zu lange sind.
            Selbst wenn man einen Binären Baum benutzt zum Zugriff, gabe es im schlimmsten Fall tausende von falschen Datensätzen die er vorher überprüfen müsste.

            MFG
            Andavos

            1. Hi,

              das Problem bei 3 Mio Einträgen würde ich darin sehen, dass der Datenbankserver dies nicht schafft, denn irgendwann ist die Grenze erreicht.

              äh? Dann würde er es bei x-hundert Tabellen noch viel weniger schaffen. Außerdem gibt es die Skalierung.

              Denn bei immer wenn ein Besucher auf eine Homepage geht (500 Kunden * 250 Seitenaufrufe/Tag = 125 000 DB Zugriffe) müssen die Tables durchsucht werden, ob es einen Eintrag für die Eigenschaft schon gibt, wenn nicht muss ein neuer Angelegt werden.

              Ja, und?

              Das bedeutet, der Server muss 125 000 mal am Tag rund 9 Mio. (3 Tables á 3 Mio Einträge) Einträge durchsuchen und ggf. einen neuen Eintrag erstellen.

              Nein, wieso?

              Bei der Variante wo alle Daten in 1 Table steht, könnte ich mir gut vorstellen, das die Zugriffszeiten zu lange sind.

              Nein, ggf. sogar schneller.

              Selbst wenn man einen Binären Baum benutzt zum Zugriff, gabe es im schlimmsten Fall tausende von falschen Datensätzen die er vorher überprüfen müsste.

              Hoppla, rechnest Du mit zwei hoch mehreren Tausend Datensätzen? Ich dachte, es ging nur um drei Milliönchen? Und außerdem: Wieso "selbst wenn", was für eine Alternative siehst Du denn?

              Cheatah

              --
              X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
              X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
              X-Will-Answer-Email: No
              X-Please-Search-Archive-First: Absolutely Yes
              1. Hallo,

                was für eine Alternative siehst Du denn?

                Könnte ja sein das er mit FAT arbeitet ^^
                Naja aber welcher Server hat das heutzutage noch ;)

                Bei der Variante wo alle Daten in 1 Table steht, könnte ich mir gut vorstellen, das die Zugriffszeiten zu lange sind.

                »»Nein, ggf. sogar schneller.
                Hmm irgendwie verstehe ich das nicht.

                Also ein Besucher kommt auf die Seite, aktiviert den PHP Script.
                Dieser schaut erstmal welche Tabelle dem User gehören (steht in einer Tabelle drin).

                z.B. CounterID:3

                Dann fragt er die Tabelle c_herkunft_3 z.B. ab.
                In dieser Tabelle sind rund 2100 Einträge vorhanden.
                Diese zu dursuchen, ob es schon einen bestimmten Eintrag gibt, geht doch bestimmt deutlich schneller, also wenn die c_herkunft geöffnet wird, und der Server dort 3 Mio. Einträge durchsuchen muss.

                Also für mich würde es keinen Sinn machen, denn weniger Einträge = schnelleres Ergebnis.

                MFG
                Andavos

                1. Hi,

                  Bei der Variante wo alle Daten in 1 Table steht, könnte ich mir gut vorstellen, das die Zugriffszeiten zu lange sind.
                  Nein, ggf. sogar schneller.
                  Hmm irgendwie verstehe ich das nicht.

                  dann reduziere die Antwort bitte auf das erste Wort.

                  In dieser Tabelle sind rund 2100 Einträge vorhanden.
                  Diese zu dursuchen, ob es schon einen bestimmten Eintrag gibt, geht doch bestimmt deutlich schneller, also wenn die c_herkunft geöffnet wird, und der Server dort 3 Mio. Einträge durchsuchen muss.

                  Nö. Es werden ca. 22 Zugriffe für die 3 Mio. gebraucht und 12 Zugriffe für die 2.100, plus den zusätzlichen Roundtrip für die Wahl der Tabelle, plus Berechnung des neuen Statements, plus Laden des neuen Index, plus was weiß ich was noch alles. Jeder Vorgang, den die DB ohnehin machen muss, muss sie bei jeder neuen Tabelle _noch einmal_ machen - bei einem objektiv nicht messbaren Geschwindigkeitsgewinn im letzten Schritt. Für einen deutlichen Verlust willst Du also erhebliche Mehrarbeit auf Dich nehmen.

                  Also für mich würde es keinen Sinn machen, denn weniger Einträge = schnelleres Ergebnis.

                  Falsch.

                  Cheatah

                  --
                  X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
                  X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
                  X-Will-Answer-Email: No
                  X-Please-Search-Archive-First: Absolutely Yes
                  1. Hallo,
                    Also zuerst wird die Usertabelle abgefragt, dies ist einfach Notwendig für andere Einstellungen.
                    Dort ist dann eine Zahl gespeichert, z.B. $gruppe=3;

                    Dann werden die Tabellennamen erstellt:
                    $herkunftdb = "c_herkunft_".$gruppe;

                    Das wäre dann z.B. c_herkunft_3

                    Danach kommt die Überprüfung ob es den Wert schon gibt.

                    SELECT id, anzahl FORM $herkunftdb WHERE counterid = '45' AND herkunft LIKE 'www.google.de'

                    Das counterid Feld ist ein SMALLINT Feld, das Herkunftfeld ist ein VARCHAR(100) Feld.

                    Angenommen da wären jetzt 32 000 Einträge, dann müsste erst erst die 32k Einträge überprüfen ob counterid = 45 ist, und dann ob als herkunft www.google.de eingetragen ist.

                    Ohne mehrere Tabellen:
                    //Abfrage der Usertable, muss für andere Sachen sein

                    Dann die Tabelle:
                    $herkunftdb = "c_herkunft";

                    Danach die Abfrage:
                    SELECT id, anzahl FORM $herkunftdb WHERE counterid = '45' AND herkunft LIKE 'www.google.de'

                    Dort würde doch jetzt der DB-Server die Tabelle öffnen, die Einträge überprüfen (3 Mio.) und dann evt. TRUE bzw. FALSE zurück geben.
                    Nach Beendigung des Scripts wird doch die Verbindung + Table geschlossen.

                    Bei der Variante mit 32 000 Einträgen wäre es doch genau das gleiche, er würde 1 Table öffnen, 32k Einträge überprüfen, dann TRUE bzw. FALSE zurück geben und dann die Verbindung + Table schließen.

                    Oder lädt der Server Tabellen die er oft braucht irgendwie in den RAM/Cache um so schneller darauf zugreifen zu müssen, ohne sie immer erneut laden zu müssen?

                    MFG
                    Andavos