nächsten freien num. Wert ermitteln

Hier dreht es sich um den PostGre Server

Moderator: Moderatoren

Antworten
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

nächsten freien num. Wert ermitteln

Beitrag von Werner_Bayern »

Servus,

habe eine Tabelle mit einem (bisher) serial-Wert. Wg. Offline-Nutzung - Kunde möchte mit Notebooks unterwegs arbeiten, ohne Internetverbindung - kopiere ich die komplette Datenbank inkl. aller Tabellen lokal auf die Notebooks.

Wird jetzt ein neuer Datensatz erzeugt, funktioniert das ab sofort nicht mehr mit Serial. Weder im Büro noch auf den Notebooks, wenn dann die Daten zusammengeführt werden sollen. Also bekommt jeder Benutzer einen Bereich zugeordnet. Serial ist bekanntlich ein 4 Byte Integer, geht also von –2147483648 bis +2.147.483.647.

Den nächsten freien Wert ermittle ich jetzt so für Notebook 1 mit Wertebereich 83 - 10083:

Code: Alles auswählen

select min(id + 1) from ticket WHERE id >= 83 AND id <= 10083 AND id + 1 NOT IN (select id from ticket) LIMIT 1
Scheint auch zu funktionieren. Denke aber, dass das ganz schön viele CPU-Zyklen benötigt?

Alternativ gings auch so:

Code: Alles auswählen

select a.id + 1 from ticket a left outer join ticket b on b.id = a.id + 1 where a.id > 83 AND a.id <= 10083 and b.id is null order by a.id LIMIT 1
Was ist besser, oder wie geht's besser? Hab ich was übersehen?
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 851
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: nächsten freien num. Wert ermitteln

Beitrag von Marcus Herz »

Ich mach das anders:
ich hole mir die letzte vergebene
select max(id) from ticket WHERE id >= 83 AND id <= 10083 ;
und zähl dann 1 hoch, coalesce um einen NULL Wert abzufangen, wenn s die erste ID ist
update <table> set id = coalesce((select max(id) from ticket WHERE id >= 83 AND id <= 10083 ),83)+1

Ist das das was du meintest oder hab ich was übersehen?
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von ramses »

Hallo Werner

Serial kennt keine negativen Werte nur 1 bis 2147483647.
du könntest auch bigserial verwenden der geht von 1 bis 9223372036854775807

MIt einem Trick würde in deinem Fall auch Serial funktionieren.
Einfach für jeden Nutzer in der PG Datenbank eine Reihe leerer Datensätze anlegen(Reservieren).
Bei Offline Nutzung darf der entsprechende User nur die für Ihn reservierten leeren Datensätze auffüllen aber keine neuen Datensätze anlegen. Mit ein wenig Programmlogik klappt dann auch die Synschronisation und die Logik der Serial ist gerettet...
Valar Morghulis

Gruss Carlo
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: nächsten freien num. Wert ermitteln

Beitrag von nightcrawler »

ein ganz anderer Ansatz wäre ein zusätzliches Feld "siteID", welches in jeder Kopie anders gesetzt wird. Der Schlüssel ergibt sich dann aus dem zusammengesetzten Feld.
Grundsätzlich setze ich seit längerer Zeit nur noch auf GUID (seit vor Jahrzehnten beim ADS Replikation eingeführt wurde).
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von ramses »

nightcrawler hat geschrieben: Di, 16. Feb 2021 10:03 Grundsätzlich setze ich seit längerer Zeit nur noch auf GUID (seit vor Jahrzehnten beim ADS Replikation eingeführt wurde).
Es gibt ja keine Garantie dass die GUID wirklich einmalig sind. Hattest du in dieser Zeit noch nie doppelte GUID's?
Valar Morghulis

Gruss Carlo
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: nächsten freien num. Wert ermitteln

Beitrag von nightcrawler »

ramses hat geschrieben: Di, 16. Feb 2021 10:08Es gibt ja keine Garantie dass die GUID wirklich einmalig sind. Hattest du in dieser Zeit noch nie doppelte GUID's?
Theoretisch ist das schon möglich, aber extrem unwahrscheinlich. Bisher hatte ich noch keine Probleme. Und da viele DBs intern auf GUID setzen, müssten die Probleme überall auftauchen.
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: nächsten freien num. Wert ermitteln

Beitrag von Tom »

Es gibt ja keine Garantie dass die GUID wirklich einmalig sind.
:lol:

Eine UUID ist mit einer Wahrscheinlichkeit von eins zu zehn hoch sechsunddreißig(!) wiederholbar. Ich denke, dass ist eine hinnehmbare Unsicherheit. Ich setze UUIDs inzwischen überall ein, wo es um die eindeutige, aber nach außen nicht relevante Verknüpfung von Daten und Tabellen geht. Schön daran ist u.a., dass man sich auch beim Mergen von Daten keinerlei Gedanken machen muss.

Edit: Aus dem Wikipedia-Text zu UUIDs/GUIDs: "Obwohl die Wahrscheinlichkeit, dass ein UUID dupliziert wird, nicht null ist, liegt sie nahe genug bei null, um vernachlässigbar zu sein." Tatsächlich (mein Text) ist die Wahrscheinlichkeit, mit irgendwelchen gegeneinander abgesicherten, sequentiellen Zählsystemen fälschlicherweise Doppelungen zu erzeugen, so extrem viel höher, dass man sie auf keinen Fall verwenden sollte, wenn man UUIDs alternativ zur Verfügung hat (etwa über die Funktionen "UuidCreate()" und "UuidToChar()" in Xbase++). Ansonsten - siehe oben. Wikipedia sagt es so: "Informationen, die von unabhängigen Parteien mit UUIDs gekennzeichnet wurden, können daher später in einer einzigen Datenbank zusammengefasst oder auf demselben Kanal mit einer vernachlässigbaren Wahrscheinlichkeit von Duplikaten übertragen werden." Das ist eine Situation, die wir in Mehrmandantensystemen oder beim Zusammenführen von Kundensystemen im Rahmen von Fusionen oder Übernahmen häufiger haben. Durch die Verwendung von UUIDs lassen sich solche Datenbanken nahezu völlig konfliktfrei zusammenfahren, und man muss sich nur noch um die nach außen sichtbaren, aber für die technische Datenhaltung irrelevanten Zählsysteme (wie Rechnungsnummern, Personalnummern usw.) kümmern.
Herzlich,
Tom
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von Werner_Bayern »

Marcus Herz hat geschrieben: Di, 16. Feb 2021 8:54 select max(id) from ticket WHERE id >= 83 AND id <= 10083 ;
und zähl dann 1 hoch, coalesce um einen NULL Wert abzufangen, wenn s die erste ID ist
update <table> set id = coalesce((select max(id) from ticket WHERE id >= 83 AND id <= 10083 ),83)+1
Das ist es, nach was ich gesucht habe. Danke! Spart den not in select.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von Werner_Bayern »

ramses hat geschrieben: Di, 16. Feb 2021 8:59 Serial kennt keine negativen Werte nur 1 bis 2147483647.
du könntest auch bigserial verwenden der geht von 1 bis 9223372036854775807

MIt einem Trick würde in deinem Fall auch Serial funktionieren.
Einfach für jeden Nutzer in der PG Datenbank eine Reihe leerer Datensätze anlegen(Reservieren).
Bei Offline Nutzung darf der entsprechende User nur die für Ihn reservierten leeren Datensätze auffüllen aber keine neuen Datensätze anlegen. Mit ein wenig Programmlogik klappt dann auch die Synschronisation und die Logik der Serial ist gerettet...
Danke für die Klarstellung, war mir bewußt, der Wertebereich bezieht sich auf 4 Byte Integer.
Ich sehe jedoch keinen Vorteil bei Deinem Vorschlag, eher aufwändiger? Mit meiner Lösung und Marcus’ Optimierung dürfte das für meinen Fall die beste Lösung sein.
Je länger ich mit SQL arbeite, desto mehr Spaß macht es. Die Möglichkeiten sind schon gewaltig.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von Werner_Bayern »

nightcrawler hat geschrieben: Di, 16. Feb 2021 10:03 ein ganz anderer Ansatz wäre ein zusätzliches Feld "siteID", welches in jeder Kopie anders gesetzt wird. Der Schlüssel ergibt sich dann aus dem zusammengesetzten Feld.
Grundsätzlich setze ich seit längerer Zeit nur noch auf GUID (seit vor Jahrzehnten beim ADS Replikation eingeführt wurde).
Interessanter Ansatz.

ADS kann seit Jahrzehnten Replikation? PG kann das auch in der 12er Version nicht, nur Cluster und logische Replikation. Beides funktioniert nur in eine Richtung. Kann der ADS eine Master-Slave und Slave-Master Replikation?
es grüßt

Werner

<when the music is over, turn off the lights!>
ramses
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2513
Registriert: Mi, 28. Jul 2010 17:16
Hat sich bedankt: 12 Mal
Danksagung erhalten: 77 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von ramses »

Werner_Bayern hat geschrieben: Di, 16. Feb 2021 22:23 Ich sehe jedoch keinen Vorteil bei Deinem Vorschlag, eher aufwändiger? Mit meiner Lösung und Marcus’ Optimierung dürfte das für meinen Fall die beste Lösung sein.
Wenn du einen vorgegeben fortlaufenden Nummernkreis z.B. für irgendwelche Nummern verwenden musst in welchem keine Duplikate erlaubt sind .....

Hauptsache ist du kannst deine Aufgabe erfüllen.
Valar Morghulis

Gruss Carlo
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von Werner_Bayern »

ramses hat geschrieben: Mi, 17. Feb 2021 8:58 Wenn du einen vorgegeben fortlaufenden Nummernkreis z.B. für irgendwelche Nummern verwenden musst in welchem keine Duplikate erlaubt sind .....
So ist es.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: nächsten freien num. Wert ermitteln

Beitrag von nightcrawler »

Werner_Bayern hat geschrieben: Di, 16. Feb 2021 22:46 ADS kann seit Jahrzehnten Replikation? PG kann das auch in der 12er Version nicht, nur Cluster und logische Replikation. Beides funktioniert nur in eine Richtung. Kann der ADS eine Master-Slave und Slave-Master Replikation?
Jahrzehnte vielleicht nicht ganz, aber schon ganz schön lange, nämlich seit V8 (wenn man bedenkt, dass der ADS seit 6 Jahren kein Update mehr bekommen hat und seitdem V12 trägt).
Beim ADS werden Datensatzänderungen in eine Queue geschrieben und dann an die andere Datenbank gepusht, sofern diese erreichbar ist. Ansonsten verbleibt der Datensatz halt etwas länger in der Queue (übrigens non-blocking für das Programm). Das ganze kann die Gegenseite auch. Konflikte muss man über Trigger lösen (ON CONFLICT DELETE, ON CONFLICT UPDATE).

Falls Du damals in Isernhagen mit dabei warst, hast Du bestimmt mein Buch rumliegen. Seite 222.
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
Benutzeravatar
HaPe
1000 working lines a day
1000 working lines a day
Beiträge: 995
Registriert: So, 15. Nov 2015 17:44
Wohnort: 71665 Vaihingen-Enz
Hat sich bedankt: 17 Mal
Danksagung erhalten: 15 Mal

Re: nächsten freien num. Wert ermitteln

Beitrag von HaPe »

Hallo Zusammen !

Ich habe für dieses Thema auf dem SQL-Server folgende Lösung im MS SQL Server-Forum erarbeitet:
https://social.msdn.microsoft.com/Forum ... qlserverde

Der Zugriff sollte ohne Anmeldung laufen.
Ich hoffe, dass diese Lösung (geht auch unter PostGreSQL) für den Einen oder Anderen nützlich sein könnte.
--
Hans-Peter
Antworten