Primärschlüssel mit uniqid()

@hpvw:
Ja, das ist richtig....
Nur zur Erklärung, warum es so viele Datensätze bei den Plätzen sein können:

Beispiel (eher am unteren Limit):
1. Es gibt 30 Saalpläne
2. Jeder Saalplan besteht aus 20 Sektoren
3. Jeder Sektor besteht aus einem Feld (Array) mit 100 Reihen und 500 Plätzen = 50.000 Elemente

Damit ergibt sich dann eine Datensatzanzahl von:
30 (Saalpläne) * 20 (Sektoren) * 50.000 (Elemente)=
30.000.000 Datensätze (30 mio).

Jetzt verstehst Du sicher mein Probem. Ich befürchte einfach, dass ich über kurz oder lang am Limit mit BIGINT sein werde, und suche daher nach einem anderen Primärschlüssel, der einen eindeutigen Wertebereich hat.

Und dann gibt es natürlich noch das Performance Problem... (wie reagiert MySQL mit einer Tabelle mit z.B. 500mio datensätzen!?). Ich kenne leider niemanden, der einen MySQL Server schon so an seine Grenzen getrieben hat...

LG
Mike
 
Dann rechnen wir doch mal rückwärts mit höheren Werten:
Code:
   18.446.744.073.709.551.615 IDs
 /                    250.000 Sektorelemente pro Sektor
 /                         50 Sektoren pro Saalplan
-------------------------------------------------------
 >          1.475.739.525.896 Saalpläne
 >                 1 Billarde Saalpläne
Und noch ungünstiger:
Code:
   18.446.744.073.709.551.615 IDs
 /                  1.000.000 Sektorelemente pro Sektor
 /                        100 Sektoren pro Saalplan
-------------------------------------------------------
 >            184.467.440.737 Saalpläne
 >             184 Milliarden Saalpläne
Ich verstehe nicht, was es da zu fürchten gibt?

Gruß hpvw
 
Wie willst Du denn aus 16 hoch 13 verschiedenen Werten 16 hoch 32 verschiedene Werte machen?
Oh, dummer Denkfehler, du hast natürlich recht. Allerdings habe ich meine Aussage auf einen leeren Prefix-Parameter und nicht-gesetzten LCG-Parameter bezogen. Wenn beide gesetzt sind, sieht das Ganze wieder anders aus.
 
@hpvw:
Wahrscheinlich hast Du recht.. Ich fürchte einfach nur, dass irgendwann (vl. in zwei Jahren) das Ende der Fahnenstange erreicht sein wird..

Zur Performance:
Hast Du damit Erfahrung? Ab wann sackt die Performance in den Keller? Ich habe mal von einem ersten Performance-Knick bie 1mio Datensätzen gehört... Weiß aber nicht, ob das tatsächlich stimmt..

Danke jedenfalls für alles & LG
Mike
 
Mik3e hat gesagt.:
Zur Performance:
Hast Du damit Erfahrung? Ab wann sackt die Performance in den Keller? Ich habe mal von einem ersten Performance-Knick bie 1mio Datensätzen gehört... Weiß aber nicht, ob das tatsächlich stimmt..

Danke jedenfalls für alles & LG
Mike
Ich fülle gerade eine Testtabelle (id BIGINT und feld CHAR) mit Millionen von Datensätzen (auf Athlon XP 2500+, 512MB Ram, Win2k, MySQL 4.1..., PHP 5).
Erstes Zwischenergebnis:
Der Code
PHP:
while (true) {
    $f="";
    for ($i=0;$i<100;$i++) {
        $f.=chr(rand(65,90));
    }
    DB::getInstance()->query("INSERT INTO megatable SET feld='$f'");
}
schafft in 30 sec über 21.000 Datensätze in folgende Struktur einzutragen:
Code:
CREATE TABLE `megatable` (
  `id` bigint(20) unsigned zerofill NOT NULL auto_increment,
  `feld` char(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
In meiner Datenbankklasse befindet sich zusätzlich noch eine if-Abfrage zur Fehlerkontrolle.
Ich habe das Eintragen jetzt mit header("location..., also Selbstaufruf, nach 25 sec automatisiert (um das 30 sec limit zu umgehen) und lasse ihn erstmal laufen, inzwichen sind ca. 500.000 Datensätze in der Tabelle.

Danach mache ich mal ein paar Selects mit like und where-Klausel und schaue mal, wie lange er braucht.

Wenn sich an den Tabellen selten etwas ändert, wird in dem Fall der Query-Cache vermutlich gute Performance-Steigerungen erzielen.

Gruß hpvw
 
Gumbo hat gesagt.:
Oh, dummer Denkfehler, du hast natürlich recht. Allerdings habe ich meine Aussage auf einen leeren Prefix-Parameter und nicht-gesetzten LCG-Parameter bezogen. Wenn beide gesetzt sind, sieht das Ganze wieder anders aus.
LCG=true wird natürlich das Ergebnis des Vergleichs umkehren (16 hoch 23 > 2 hoch 64), der Prefix sollte allerdings keinen Unterschied machen, es sei denn er wird selbst zufällig oder per [phpf]uniqueid[/phpf] bestimmt. Die tatsächliche Anzahl unterschiedlicher IDs, die sich daraus dann ergeben, will ich nicht bestimmen müssen.

Gruß hpvw
 
Hallo!

Wie sieht es denn aus, wenn du dir als Primärschlüssel einen String (VARCHAR) verwendest? Das sind 255 Zeichen à 8Bit = 2040 Bit, wenn ich mich nicht irre, sind das 2^2040 Möglichkeiten?

Und selbst wenn du pro Zeichen nur 64 Möglichkeiten (=6 Bit; a..z & A..Z & 0..9 & 2 weitere Zeichen) zulässt, wären wir bei 1530 Bit, also 2^1530 Möglichkeiten.

Reicht das?

Mamphil
 
@hpvw:
Und, bist Du schon bei einer brauchbaren Anzahl an Datensätzen angelangt
Interessant wäre folgender Testlauf:

1. Eine Testtabelle anlegen:
Code:
# tabelle_test
pk_id (BIGINT, AUTO INCREMENT)
testattribut (TEXT)

2. Eine Methode (hier als Pseudocode), die einen Insert macht, anschließend einen Select und dabei die Zeit mißt. Die Anzahl der Inserts sollte aber linear steigen, da ansonsten der zeitvergleich nicht stimmt. Und es sollte auch immer nur ein SELECT auf einen Datensatz sein:

PHP:
function performancetest() {
   for($i=0;$i<=1000000000) {
       INSERT INTO TABELLE....;
       setze $timestamp start;
       SELECT * FROM TABELLE WHERE pk_id='1';
       echo SELECT_ERGEBNIS;
       setze $timestamp ende;
       echo "ABFRAGEZEIT BEI ".$i." DATENSÄTZEN:". $timestamp_ende - $timestamp_start;
   }
}
Mit dieser Methode sieht man dann schön, ab welcher Datensatzanzahl die Lesezeit absackt. Man könnte auch noch die Zeit des Inserts messen, obwohl die vermutlich unabhängig von der Datensatzanzahl ist.

Hast Du eine TestDB irgendwo rumliegen, um diese Funktion zu testen? Ich hab hier leider nur mein Echtsystem.

Wäre wirklich spannend zu wissen, welches Ergebnis das liefert...
 
Zuletzt bearbeitet:
Deine Testumgebung ist mir ehrlich gesagt zu zeitaufwändig.
Da immer nur relativ wenige (im Verhältnis zu mehreren Millionen) INSERTs pro Aufruf möglich sind entwickelt sich bei der Datenflut eine Menge an Einzelversuchen, die nicht mehr sinnvoll überschaubar ist und deren weitere Analyse Statistikprogramme erfordert, die entsprechende Grafiken erzeugen und vor allem Regressionsanalysen durchführen können. Dazu noch ein bisschen Mathe, vor allem die Mathematik von meinem persönlichen Erzfeind, der Statistik und man könnte einen "Knick" in der Schätzfunktion suchen, um den kritischen Punkt zu ermitteln. Excel wird vermutlich bei der Datenflut explodieren.

Daher habe ich bei statischer Anzahl Datensätze (rund 2,1 Mio) einfach ein paar Querys laufen lassen und deren Zeiten aufgeschrieben.
  • SELECT id,feld FROM megatable WHERE feld LIKE '%abc%' LIMIT 0,1000
    2,1 sec, LIMIT erreicht
  • SELECT id,feld FROM megatable WHERE feld LIKE '%abcd%' LIMIT 0,1000
    29,3 sec, Ergebnistabelle leer.
  • SELECT id,feld FROM megatable LIMIT 0,10000
    16,7 sec, LIMIT erreicht
  • SELECT id,feld FROM megatable WHERE feld LIKE '%mwml%' LIMIT 0,1000
    11,2 sec, LIMIT erreicht.
  • SELECT id,feld FROM megatable WHERE feld LIKE 'LGCQL...YKIJ' LIMIT 0,1000
    (ohne Platzhalter, einen Eintrag aus den vorigen Ergebnissen herauskopiert)
    29,6 sec, 76 Ergebniszeilen
    OT: -> mieser Zufallszahlengenerator in PHP, es sollte über 3 * 10 hoch 141 Möglichkeiten geben, aber bereits bei 2 * 10 hoch 6 tritt ein Ergebnis 76 mal auf. Wenn ich keinen Denkfehler habe liegt die Periodenlänge im PHP-Zufallszahlengenerator unter 300.000.
  • SELECT id,feld FROM megatable WHERE id=1486759
    0,052 sec, 1 Ergbniszeile
Mit einer Suche nach der ID lässt sich leben, der Rest ist ziemlich daneben.

Eine Zeichenkette als Primärschlüssel scheidet nach dieser Analyse IMHO aus.
Ich versuche gerade noch einen Index auf feld zu legen, um zu überprüfen, ob sich bei der Suche deutliche Besserungen ergeben. Allerdings legt sich zur Zeit eher der Rechner schlafen, als dass er den Anschein erweckt, dass er mit dem Index anlegen heute noch fertig wird. Merke: Erst den Index anlegen, dann die Daten eintragen.

Der Test zeigt auch, dass Dein Versuchsaufbau relativ unnütz ist, da die Ergebnisse relativ passable Zeiten zeigen, wenn es nur um einen einzelnen Datensatz geht, der über die ID identifiziert ist.

Die Tabelle verbraucht übrigends über 600 MB, laut PHPMyAdmin.

Gruß hpvw
 
Eine halbe Stunde arbeitet er am Index, aber jetzt will ich meine Platte wiederhaben.
Sorry, aber der Test mit Index wird nichts mehr.
 
Zurück