kleinste nicht vergene id heraussuchen?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • kleinste nicht vergene id heraussuchen?

    hallo!

    ich habe eine tabelle namens users, mit der spalte ids typ int(11)...

    nun, ich arbeite nicht mit auto_increcement, da manche ihre wunsch-id nutzen sollen können...

    nun aber die frage: falls jemand keine id möchte, soll die kleinste nicht vergeben id genommen werden - wie finde ich diese heraus?
    Mit freundlichem Gruß,
    Deathrow

  • #2
    Ich würde es vielleicht so machen:
    hol dir alle ids aus der DB. Sortiere das Array nach größe, dann gehst du eine Schleife durch und prüfst ob die id vorhanden ist, wenn nein, dann nimmst du die.

    Vielleicht bissle unklar erklärt aber du weist hoffentlich was ich meine.

    mfg

    herrmie
    Wer anderen eine Grube gräbt, der hat ein Grubengrabgerät.

    Kommentar


    • #3
      Original geschrieben von herrmie
      Ich würde es vielleicht so machen:
      hol dir alle ids aus der DB. Sortiere das Array nach größe, dann gehst du eine Schleife durch und prüfst ob die id vorhanden ist, wenn nein, dann nimmst du die.

      Code:
      SELECT MIN(id) FROM tabelle
      alles darunter ist frei

      dazwischen ist ein Problem ... aber das sollte man nicht dadurch lösen, dass man sich ALLE ids, aus der Datenbank in ein Array packt (man stelle sich das bei einer halbe Million Datensätze vor x_X)

      @to
      du hast aber nicht vor einmal vergebene IDs wieder "frei zu machen"? Ansonsten ist die id (id = identifier) kein Identifier mehr... und das wäre sehr ungünstig

      Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

      bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
      Wie man Fragen richtig stellt

      Kommentar


      • #4
        Re: kleinste nicht vergene id heraussuchen?

        Original geschrieben von Deathrow
        hallo!

        ich habe eine tabelle namens users, mit der spalte ids typ int(11)...

        nun, ich arbeite nicht mit auto_increcement, da manche ihre wunsch-id nutzen sollen können...

        nun aber die frage: falls jemand keine id möchte, soll die kleinste nicht vergeben id genommen werden - wie finde ich diese heraus?
        Welches DBMS? Ich gehe von MySQL aus, probiere mal:
        Code:
        SELECT t1.ids - 1 as newid FROM yourTable t1
           WHERE NOT EXISTS( SELECT *  FROM yourTable t2
                           WHERE t2.ids = t1.ids - 1)
           ORDER BY newid LIMIT 1

        Kommentar


        • #5
          Angenommen folgende IDs existieren: 0-5, 7-10.
          Ghostgamblers Vorschlag MIN(id) liefert 0, nicht 6!

          Es müßte eher sowas sein:
          SELECT MIN(id) FROM table WHERE id NOT IN(SELECT id FROM table)
          Geht so natürlich nicht, weil man da etwas selected, was eben noch nicht existiert (die ID ist ja frei, also nicht vergeben).

          Kommentar


          • #6
            Original geschrieben von onemorenerd
            Angenommen folgende IDs existieren: 0-5, 7-10.
            Ghostgamblers Vorschlag MIN(id) liefert 0, nicht 6!

            Es müßte eher sowas sein:
            SELECT MIN(id) FROM table WHERE id NOT IN(SELECT id FROM table)
            Geht so natürlich nicht, weil man da etwas selected, was eben noch nicht existiert (die ID ist ja frei, also nicht vergeben).
            genau so etwas meine ich...

            wenn halt 0-5 und 7-xxx vergeben sind, wie bewkomme cih die 6 raus?

            und nein, ich möchte das nciht wieder freigeben... bloß halt, das amnche ihre unsch-id's wählen können (z.b. halt 0-5 und 7-10 shcon vergeben) und die leute, welche sich ohne id anmelden, die niedrigste freie, in diesem fall die 6, bekommen...

            und ein array und dann ne schleife wäre nen bischen zu brutal

            @asp2php: bei deinem code kommt immer nur "-1" raus... es sollte aber 6 herauskommen
            Mit freundlichem Gruß,
            Deathrow

            Kommentar


            • #7
              es fehlte ein DESC bei asp2php

              Code:
              SELECT t1.id - 1 as newid FROM test t1
                 WHERE NOT EXISTS( SELECT *  FROM test t2
                                 WHERE t2.id = t1.id - 1)
                 ORDER BY newid DESC LIMIT 1
              Leider ist das die einzig funktionierende Lösung ... mit einer Variablen geht es auch nicht, weil mysql bei SELECT @pos:=@pos+1 nur zählt wenn der Datensatz zurück gegeben wird (was man ja nicht will) und wenn man WHERE @pos:=@pos+1 macht, landet da einfach nur die Anzahl der Datensätze drin...

              Die Möglichkeit von asp2php ist also die Einzige, aber ... der Explain lässt mich erschaudern >_<
              Code:
               id  	 select_type  	 table  	 type  	 possible_keys   key  key_len   ref	 rows  	 Extra
              1 	PRIMARY 		t1 	ALL 	NULL 		NULL 	NULL 	NULL 	2 	Using where; Using filesort
              2 	DEPENDENT SUBQUERY 	t2 	ALL 	NULL 		NULL 	NULL 	NULL 	2 	Using where
              ob das die freie Wahl von IDs aufwiegt....

              Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

              bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
              Wie man Fragen richtig stellt

              Kommentar


              • #8
                Welchem Zweck dient es eigentlich, User die ID ihres Datensatzes frei wählen zu lassen? Die wird üblicherweise nirgendwo sichtbar.

                Kommentar


                • #9
                  Original geschrieben von onemorenerd
                  Welchem Zweck dient es eigentlich, User die ID ihres Datensatzes frei wählen zu lassen? Die wird üblicherweise nirgendwo sichtbar.
                  keinem. Korrekterweise wird man in einem solchen Fall eine interne ID mit autoincrement vergeben
                  und zum primary key machen. Die user-gewählte id wird dann ein Feld wie die Telefonnummer,
                  die selbstgewählte Haarfarbe usw.

                  Ich würde die user-id der gestellten Aufgabe folgendermassen vergeben:
                  RANDOM(0.5*COUNT(*)+1, 2*COUNT(*)+3),
                  und falls es eine Kollision gibt, nochmals probieren.
                  Genaue Syntax: ad.lib. Die Parameter 0.5 und 2: auch je nach Geschmack.
                  Zuletzt geändert von gleiwitz19; 31.07.2006, 02:38.

                  Kommentar


                  • #10
                    Original geschrieben von Deathrow

                    @asp2php: bei deinem code kommt immer nur "-1" raus... es sollte aber 6 herauskommen
                    ich habe nur schnell eingetippt, es sollte doch möglich sein, selbst damit was anzufangen. Warum probierst du nicht aus?

                    Kommentar


                    • #11
                      Original geschrieben von ghostgambler
                      es fehlte ein DESC bei asp2php

                      Code:
                      SELECT t1.id - 1 as newid FROM test t1
                         WHERE NOT EXISTS( SELECT *  FROM test t2
                                         WHERE t2.id = t1.id - 1)
                         ORDER BY newid DESC LIMIT 1
                      Leider ist das die einzig funktionierende Lösung ... mit einer Variablen geht es auch nicht, weil mysql bei SELECT @pos:=@pos+1 nur zählt wenn der Datensatz zurück gegeben wird (was man ja nicht will) und wenn man WHERE @pos:=@pos+1 macht, landet da einfach nur die Anzahl der Datensätze drin...

                      Die Möglichkeit von asp2php ist also die Einzige, aber ... der Explain lässt mich erschaudern >_<
                      Code:
                       id  	 select_type  	 table  	 type  	 possible_keys   key  key_len   ref	 rows  	 Extra
                      1 	PRIMARY 		t1 	ALL 	NULL 		NULL 	NULL 	NULL 	2 	Using where; Using filesort
                      2 	DEPENDENT SUBQUERY 	t2 	ALL 	NULL 		NULL 	NULL 	NULL 	2 	Using where
                      ob das die freie Wahl von IDs aufwiegt....
                      Mit vernünftigen Index ist es auch kein Problem. Der Verzicht auf Autoincrement durch Verwenden von eigenen IDs mit Auffüllung von Lücken ist auch ziemlich gängig, was nicht unbedingt normal ist, aber das machen auch viele, und ich auch, wenn im Pflichtenheft sowas explizit steht.

                      Kommentar


                      • #12
                        Na wenn es wirklich so verbreitet ist, habe noch einen Vorschlag:

                        SELECT MIN(foo.id+1) AS nextID FROM foo
                        LEFT JOIN foo AS bar ON foo.id +1 = bar.id
                        WHERE bar.id IS NULL

                        Kann mich mit der Idee aber immernoch nicht anfreunden ...

                        Kommentar

                        Lädt...
                        X