Announcement

Collapse
No announcement yet.

Wie Datensätze fortlaufend durchnummerieren ?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Wie Datensätze fortlaufend durchnummerieren ?

    Hallo allerseits,
    1)
    in einer Tabelle einer Datenbank will ich Zahlenpaare ablegen, wobei die 1. Zahl eines Zahlenpaars die Nummer des Zahlenpaars darstellen muß und alle 2. Zahlen jeweils verschieden sein müssen.
    Die Nummerierung beginnt bei 1 und zählt dann fortlaufend um 1 hoch.
    Ein Datensatz besteht also aus 2 Spalten.
    Datensätze konnten also z.B. so aussehen:
    1, 1
    2, 4
    3, 9
    4, 16
    5, 25
    6, 3
    7, 19
    ....

    Die Zahl 16 darf nicht eingefügt werden (als 8,16) da die 16 schon mal vorkommt, nämlich im Datensatz (4, 16)

    2)
    Meine Idee war, die 1. Spalte als Primärschlüssel zu definieren und die 2. Spalte also UNIQUE zu definieren.
    Solange ich dann Zahlenwerte einfügen will, die (auf die 2. Spalte) bezogen alle verschieden sind, funktioniert das einwandfrei.
    Wenn ich allerdings z.B. die Zahl 16 (als 2. Spaltenwert) einfügen will, wird dieser DB-Zugriff korrekterweise verweigert, aber der Primärschlüssel wird trotzdem hochgezählt und ich habe keine fortlaufende Nummerierung mehr.
    Beispiel:
    // In die leere Tabelle wird die Zahl 4 eingefügt, als Zahlenpaar:
    (1,4)
    Wenn ich jetzt nochmals die 4 einfügen will, wird dies verweigert.
    Wenn ich jetzt z.b. 17 einfügen will, wird in die DB folgender Datensatz eingefügt:
    (3,17)
    und mir geht die fortlaufende Nummerierung flöten.

    3)
    Wie kann ich das Problem lösen ?

    4)
    Gilt dies auch für eine MS-ACCESS Datenbank ?

    mfg
    Bh

  • #2
    Wozu willst du eine Nummerierung?
    Wo ist das ein Problem?
    Es kann dir doch egal sein, ob Lücken im PrimaryKey sind.
    Eine Datenbank hat per se keine Sortierung. Eine Datenbank arbeitet mit Mengen. Nur weil du dir die Daten so anzeigen lässt, siehst du eine Reihenfolge. Würdest du sie nach der 2. Spalte sortieren, wo ist da die Reihenfolge? Oder würdest du nur bestimmte Datensätze selektieren, liegt auch keine Reihenfolge mehr vor. Der oder die PK dienen zu eindeutigen Identifikation der Datensätze. Mehr nicht.
    Sofern du eine bestimmte Sortierung der Datensätze brauchst, füge eine Spalte "sort" hinzu, mit der du die Reihenfolge bestimmst. D.h. du fügst selbst den nächsten Wert ein

    Üblicherweise prüft man die Daten vor dem speichern in die DB. D.h. man lässt sich nicht in eine DB-Exception fallen. Man fragt also vorher ab, ob es schon einen Datensatz mit der neuen Nummer in der Spalte 2 gibt. Wenn ja, erfolgt keine Speicherung in die DB, sondern man gibt bsp. eine Fehlermeldung aus oder schreibt das in ein Logfile
    Zuletzt editiert von Christian Marquardt; 19.11.2016, 12:34.
    Christian

    Comment


    • #3
      Wenn Du nur ein Programm/einen Thread hast was auf die Datenbank zugreift ist ein fortlaufender Schlüssel relativ einfach zu implementieren. Nimm eine Tabelle mit genau einer Zeile und schreib dort die zuletzt benutzte Zahl rein, aber nur wenn Du diese Zahl benutzt hast, ansonsten nicht. Falls mehrere Programme oder Threads darauf zugreifen wünsche ich Dir viel Spaß das ist wahrscheinlich eins der komplexesten Probleme in der IT überhaupt bzw. ist es bei parallelen Zugriffen von der Natur des Problems schon unmöglich eine wirklich fortlaufende Nummer zu generieren. Wenn drei Programme parallel eine neue Zahl wollen, welche bekommen sie dann?

      Comment


      • #4
        Originally posted by fanderlf View Post
        Wenn Du nur ein Programm/einen Thread hast was auf die Datenbank zugreift ist ein fortlaufender Schlüssel relativ einfach zu implementieren. Nimm eine Tabelle mit genau einer Zeile und schreib dort die zuletzt benutzte Zahl rein, aber nur wenn Du diese Zahl benutzt hast, ansonsten nicht. Falls mehrere Programme oder Threads darauf zugreifen wünsche ich Dir viel Spaß das ist wahrscheinlich eins der komplexesten Probleme in der IT überhaupt bzw. ist es bei parallelen Zugriffen von der Natur des Problems schon unmöglich eine wirklich fortlaufende Nummer zu generieren. Wenn drei Programme parallel eine neue Zahl wollen, welche bekommen sie dann?
        Hallo fanderif,
        1) Ich benutze genau 1 Programm, das auf diese DB zugreift.
        2) Leider habe ich deine Idee nicht verstanden:
        "Nimm eine Tabelle mit genau einer Zeile und schreib dort die zuletzt benutzte Zahl rein,
        aber nur wenn Du diese Zahl benutzt hast, ansonsten nicht."
        Aus welchen Spalten soll die Tabelle bestehen?
        Warum nur eine Zeile?
        Wenn man mehrere Datensätz einfügt, gibt es doch mehrere Zeile!
        Was meinst du genau?

        mfg
        Bh

        Comment


        • #5
          Hallo Christian,
          >
          >Wozu willst du eine Nummerierung?
          >Wo ist das ein Problem?
          >Es kann dir doch egal sein, ob Lücken im PrimaryKey sind.
          >
          Ich will ein mathematisches Problem lösen und dazu eine DB "zweckentfremden".

          >
          >Üblicherweise prüft man die Daten vor dem speichern in die DB. D.h.
          >man lässt sich nicht in eine DB-Exception fallen.
          >Man fragt also vorher ab, ob es schon einen Datensatz mit der neuen Nummer
          >in der Spalte 2 gibt. Wenn ja, erfolgt keine Speicherung in die DB,
          >sondern man gibt bsp. eine Fehlermeldung aus oder schreibt das in ein
          >
          geht das auch einfacher ?

          mfg
          Bh

          Comment


          • #6
            Ich will ein mathematisches Problem lösen und dazu eine DB "zweckentfremden".
            Sicherlich nicht mit dem automatisch erzeugten PK

            geht das auch einfacher ?
            Was sollte da einfacher gehen?
            Üblicherweise hat man wohl ein Frontend für die DB. Warum da keine Fehlerprüfung?
            Christian

            Comment


            • #7
              Ich will ein mathematisches Problem lösen und dazu eine DB "zweckentfremden"
              Klingt leider so als wolltest du mit einer Motorsäge einen Nagel in die Wand hauen. Wenn du das willst ok. Aber bitte nachher nicht über praktisch ungeeignete Motorsägen meckern

              Um wie viele Zahlenpaare geht es denn hier? Nicht mehr als maximal ein paar Zehntausend? Dann denkt dir eine simple binäre Struktur deiner Zahlenpaare aus und schreib die komplett als Blob in die DB (Eine Zelle einer Tabelle).
              Lade dann immer komplett alle aus der DB und schreib die komplett wieder zurück. Es nützt nix nicht relationale Daten in eine relationale Struktur packen zu wollen.

              // In die leere Tabelle wird die Zahl 4 eingefügt, als Zahlenpaar:
              (1,4)
              Wenn ich jetzt nochmals die 4 einfügen will, wird dies verweigert.
              Wenn ich jetzt z.b. 17 einfügen will, wird in die DB folgender Datensatz eingefügt:
              (3,17)
              und mir geht die fortlaufende Nummerierung flöten.
              Wenn du nie löscht dann definiere den PK nicht als Generator/AutoInc Wert sondern einfach als simplen Integer. Ermittle dann selbst den nächsten Schlüsselwert (count(*)+1)

              > Üblicherweise prüft man die Daten vor dem speichern in die DB. D.h.
              Um das klar zu sagen. Das gilt allgemein maximal in einer Singleuser Umgebung. In diesem merkwürdigen Problem hier ist das möglicherweise auch ok. Aber sich nicht üblicherweise.

              Comment


              • #8
                Um das klar zu sagen. Das gilt allgemein maximal in einer Singleuser Umgebung.
                Seltsam, wir machen das auch in Client/Serveranwendungen.
                Warum sollte ich falsche Daten in die DB schreiben wollen?
                Also prüfe ich vorher, ob bsp. eine Telefonnumer nur Ziffern, eine IP nur Ziffern und Punkt enthält
                Christian

                Comment


                • #9
                  Um das klar zu sagen. Das gilt allgemein maximal in einer Singleuser Umgebung.
                  Seltsam, wir machen das auch in Client/Seranwendungen.
                  Warum sollte ich falsche Daten in die DB schreiben wollen?
                  Also prüfe ich vorher, ob bsp. eine Telefonnumer nur Ziffern, eine IP nur Ziffern und Punkt enthält.
                  Falsche Daten werden schon durch die Anwendung abgewiesen und der Nutzer muss ggf. korrigieren
                  Christian

                  Comment


                  • #10
                    Warum sollte ich falsche Daten in die DB schreiben wollen?[/COLOR]
                    Zwischen prüfen und schreiben in die Datenbank kann sich der Zustand der Datenbank geändert haben, das Ergebnis der Prüfung sollte also völlig egal sein du musst den Zustand des System beim schreiben sicherstellen. Die Alternative wäre mit dem prüfen entsprechende Sperren auf die zu ändernden Daten zu legen. Das will man nur in ganz bestimmten Anwendungsfällen die sicherlich nicht unter der Bezeichnung üblich firmieren.

                    Also prüfe ich vorher, ob bsp. eine Telefonnummer nur Ziffern, eine IP nur Ziffern und Punkt enthält.
                    Du prüfst vielleicht das Format aber du würdest nicht prüfen ob die Telefonnummern schon da ist und dich dann nach der Prüfung darauf verlassen das beim tatsächlichen Schreiben in die DB die Telefonnummer auch tatsächlich nicht in der Datenbank ist. Diese Garantie würde teure Datenlocks nötig machen und/oder eine zweite Prüfung beim schreiben (Constraint, Indizes etc.) die die erste Prüfung weitestgehend unnötig machen.

                    Comment


                    • #11
                      1)
                      ok

                      2)
                      ein Primärschlüssel garantiert eben keine fortlaufenden Zahlen, sondern nur eindeutige Werte(!, nicht mal Zahlen)
                      (eigentlich nichts anders als eine spezielle Form Deines Unique für die Spalte 2)

                      3)
                      die fortlaufende Zahl per Select erzeugen: <Select max(id)+1 from mytable> *1 oder
                      die Zahl in der Anwendung per Zähler verwalten und im Insert verwenden
                      die fortlaufende Zahl per DB Code erzeugen oder
                      die fortlaufende Zahl gar nicht mit abspeichern, sondern nur mit Ausgeben, wenn (ab)gefragt *2 oder

                      oder
                      oder

                      4)
                      weiß nicht, mglw. ist Access da anders als die Masse, ist es ja auch sonst an vielen Stellen. Allein deswegen würde ich aber niemals Access verwenden. Es gibt viele viele Alternativen.


                      *1, normalerweise zu vermeiden, im singel user Betrieb wahrscheinlich ok,
                      *2, nicht ganz gewöhnliches Vorgehen, kommt auf die sonstigen Anforderungen / Einsatz an, ob es taugt
                      Gruß, defo

                      Comment


                      • #12
                        Hallo Ralf,
                        Originally posted by Ralf Jansen View Post
                        Aber bitte nachher nicht über praktisch ungeeignete Motorsägen meckern
                        So lange ich mir nicht die Hand dabei absäge, kann ich ja ein paar Experimente machen :-))
                        Ich will mich etwas mit Datenbanken beschäftigen und auf die üblichen BWL-Aufgaben (welche Person verdient mehr als 1000 Euro und ist bei der Firma Makeall beschäftigt) habe ich keine Lust. Deswegen habe ich versucht eine mathematische Aufgabe umzusetzen (induktiv definierte Mengen, siehe unten).
                        Kennst du DB-Aufgaben mit mathematischem Hintergrund ?

                        Um wie viele Zahlenpaare geht es denn hier? Nicht mehr als maximal ein paar Zehntausend?
                        Es geht um folgendes Problem:
                        Nach dem "Urknall" gibt es die 2 Atome (Bausteine) 3 und 5
                        3, 5
                        Die folgende Regel R gibt an, wie aus einer Menge von Bausteinen eine neue Menge entsteht, die die alte Menge enthält:
                        Addiere jeweils 2 Atome (die ungleich sein müssen, also nicht 2 gleiche Atome) aus der alten Menge und füge sie später der alten Menge hinzu.
                        Beispiel:
                        3,5
                        Erweiterung1: 8 ergibt:
                        3,5, 8
                        Erweiterung2: 11, 13 ergibt:
                        3,5, 8, 11, 13
                        Erweiterung3: 14, 16, 19, 24, 18, 21 ergibt:
                        3,5, 8, 11, 13, 14, 16, 19, 24, 18, 21
                        ...
                        Diese immens wachsenden Zahlen will ich in eine Tabelle einer DB schreiben.
                        Wenn ich die Zahlen nicht durchnummeriere, muß ich jedes Mal mit SELECT alle Zahlen
                        in eine Tabelle (Arbeitsspeicher) einlesen. Das ergibt ein schlechtes Laufzeitverhalten.
                        (und wenn die DB immer größer wird, muß man immer mehr Zeilen einlesen - intern wird das ein Array o.ä. sein -
                        das dann immer größer wird und durch die Größe des wobei Arbeitsspeichers beschränkt ist).
                        Wenn ich die Zahlen dagegen durchnummeriere (so meine Idee) kann ich jedes Mal gezielt
                        eine Zahl durch ihre Nummer in eine Variable einlesen (und nicht alle - was vermutlich nicht viel bringt, da ich ja auch alle Datensätze einlesen muß).
                        Wie kommt man die Durchnummerierung hin ?
                        Vor jedem Einfügen des Zahlenpaares (durch 2 Spalten realisiert) bestimme ich mit COUNT(*) in der SELCT Anweisung die Anzahl der Datensätze.
                        Diese Zahl+1 ist dann die neue Nummer des einzufügenden Datensatzes.

                        Dann denkt dir eine simple binäre Struktur deiner Zahlenpaare aus und schreib die komplett als Blob in die DB (Eine Zelle einer Tabelle).
                        Lade dann immer komplett alle aus der DB und schreib die komplett wieder zurück. Es nützt nix nicht relationale Daten in eine relationale Struktur packen zu wollen.
                        Das habe ich nicht ganz verstanden:
                        Kann man in SQL nicht nur elementare Datentypen wie z.B. Integer in einer Spalte ablegen, sondern auch "selbstgebastelte" Datentypen wie z.B. ein Zahlenpaar oder eine noch komplizieret Struktur oder was hast du damit gemeint ?

                        Um das klar zu sagen. Das gilt allgemein maximal in einer Singleuser Umgebung. In diesem merkwürdigen Problem hier ist das möglicherweise auch ok. Aber sich nicht üblicherweise.
                        Ja klar, das Programm soll nur von genau einem Rechner mit genau einem Thread realisiert werden.


                        mfg
                        Bh

                        Comment


                        • #13
                          Die Regel habe ich begriffen sehe aber keine sinnvolle Verwendung eine DB darin (Wir reden immer von Datenbank meine aber relationale Datenbank. Anders strukturierte Datenbanken könnten da hilfreicher sein).
                          Ich könnte mir vorstellen das man da was nettes mit einer recusive Common Table Expressions machen kann. Das ist aber nix zum kennen lernen von Datenbanken sondern gehört in die Advanced Ecke.

                          Kann man in SQL nicht nur elementare Datentypen wie z.B. Integer in einer Spalte ablegen, sondern auch "selbstgebastelte" Datentypen wie z.B. ein Zahlenpaar oder eine noch komplizieret Struktur oder was hast du damit gemeint ?
                          Eigentlich jede DB unterstütz unspezifizierte Daten in einer Spalte abzulegen (meist BLOB genannt). Das heißt aber nicht das die Datenbank was genaueres über diesem Datentyp weiß. Es ist einfach ein Haufen Bytes.
                          Die Datenbank kann nix anderes als die Daten ablegen und wieder rausrücken. Du kannst keine sinnvolle andere Methoden auf diese Daten anwenden. Wäre fast so als würdest du deine Daten einfach in ein File schreiben.
                          Du hättest die Datenbank benutz ohne die Datenbank ~wirklich~ zu benutzen. Aber du hast ja auch kein ~wirkliches~Datenbank Problem zur Hand.


                          Edit: Ich habe mal folgendes probiert.

                          [Highlight=SQL]CREATE TABLE Atoms (Atom bigint NOT NULL);
                          INSERT INTO Atoms(Atom) VALUES (3),(5);
                          WHILE (10000 > (SELECT count(*) FROM Atoms))
                          BEGIN
                          INSERT INTO Atoms
                          SELECT distinct(a1.atom+a2.atom)
                          FROM Atoms a1
                          INNER JOIN Atoms a2 ON a1.atom != a2.atom
                          WHERE NOT EXISTS (SELECT atom FROM Atoms a3 WHERE a3.atom = (a1.atom + a2.atom))
                          END[/Highlight]

                          Das wird aber schnell sehr langsam wenn man noch mehr Atome haben will (40000 Atome haben hier ~7 Minuten gebraucht)
                          Beim ausprobieren hatte ich den Gedanken das das Beispiel auch wenn nicht passend für relationale Datenbank vielleicht doch ganz lehrreich ist. Kann es sein das du zu sehr algorithmisch über dein Problem nachdenkst? SQL im engeren Sinn beschreibt KEINE Algorithmen es beschreibt ein Ergebnis.

                          Hat deine beschrieben Regel mit den Atomen einen Namen? Erscheint mir irgendwie merkwürdig denn man sollte ganz schnell immer alle natürliche Zahlen drin haben. Außer eben ein paar Lücken nahe den Startwerten.
                          Zuletzt editiert von Ralf Jansen; 20.11.2016, 15:21.

                          Comment


                          • #14
                            Originally posted by bernhart View Post
                            Hallo Ralf,

                            So lange ich mir nicht die Hand dabei absäge, kann ich ja ein paar Experimente machen :-))
                            Ich will mich etwas mit Datenbanken beschäftigen und auf die üblichen BWL-Aufgaben (welche Person verdient mehr als 1000 Euro und ist bei der Firma Makeall beschäftigt) habe ich keine Lust. Deswegen habe ich versucht eine mathematische Aufgabe umzusetzen
                            Na dann fangen wir mal an und steigern uns. Hier in der Schweiz gab es von ein paar Jahre die Volksinitiative '1:12 - Für gerechte Löhne'. Diese Initiative verlangte, dass der höchste Lohn im Unternehmen maximal dem 12-fachen des niedrigsten Lohns sein darf.

                            Aufgabe: Schreibe ein SELECT (oder UPDATE) Statement welches diese Forderung umsetzt für den Fall das die Volksinitiative an der Urne angenommen worden wäre.
                            Es gibt natürlich mehrere Lösungen, entweder den Lohn des CEO kürzen oder die Löhne der niedrigen Einkommensstufen hoch setzen.

                            Gruss

                            Comment


                            • #15
                              Originally posted by Wernfried View Post
                              Volksinitiative '1:12 - Für gerechte Löhne'. Diese Initiative verlangte, dass der höchste Lohn im Unternehmen maximal dem 12-fachen des niedrigsten Lohns sein darf.
                              Sehr interessant, was ist draus geworden?
                              Haben die Spitzenleute jetzt auch alle mehrere Jobs, liegt ja beim Fußvolk voll im Trend.
                              Oder wird der Faktor 12 auf die Wochen/Monats/Jahresarbeitszeit berechnet?
                              Und gibt es auch eine Volumenbetrachtung über die Anzahl der niedrig und hoch vergüteten Jobs in diesem Modell?
                              Gruß, defo

                              Comment

                              Working...
                              X