erster freier wert einer index-spalte

Fragen und Probleme rund um die Abfragespache SQL.

erster freier wert einer index-spalte

Beitragvon marcomania » So 5. Nov 2006, 19:36

hallo!

ist es möglich sich mit einem SQL-befehl den ersten "freien" wert anzeigen zu lassen? also wenn eine index-spalte z.b. die folgenden werte hat:

ID
1
2
3
5
6
7

würde dann 4 herauskommen.

ich habs zuerst mit einem einfachen algorithmus gelöst, der jeden wert ab 1 beginnend einzeln auf vorhandensein prüft. allerdings ist das sehr langsam.

dank & gruß, marco
marcomania
Neuer Benutzer
 
Beiträge: 1
Registriert: So 5. Nov 2006, 19:30

Beitragvon akretschmer » So 5. Nov 2006, 20:02

marcomania hat geschrieben:hallo!

ist es möglich sich mit einem SQL-befehl den ersten "freien" wert anzeigen zu lassen? also wenn eine index-spalte z.b. die folgenden werte hat:

ID
1
2
3
5
6
7

würde dann 4 herauskommen.

ich habs zuerst mit einem einfachen algorithmus gelöst, der jeden wert ab 1 beginnend einzeln auf vorhandensein prüft. allerdings ist das sehr langsam.

dank & gruß, marco



Wozu?

Nenne mir einen triftigen Grund dafür, dann denk ich drüber nach.

Bis dahin: Deine offensichtlich von einer Sequenz erzeugte ID ist eindeutig und erfüllt exakt ihren Zweck.
Sie ist nicht dafür bestimmt, fortlaufend zu sein, nur eindeutig. Das ist sie.


Btw.: Dein 'algorithmus' hat vermutlich und ganz sicher einen Knackpunkt: er ist nicht
Multiuser-fähig.

Und ja: falls Du jetzt z.B. mit Finanzamt und fortlaufener Rechnungsnummer kommst:
ja, das mag ein Problem sein, welches aber Dein 'algorithmus' auch nicht lösen kann.
Hint: Rechnungsdatum.
akretschmer
Erfahrener Benutzer
 
Beiträge: 5938
Registriert: So 29. Okt 2006, 14:35
Wohnort: Kaufbach, Sachsen, Germany, Germany

Beitragvon alexander_ro » So 12. Nov 2006, 17:58

Hallo,

ich bin neu in diesem Forum, arbeite aber schon einige Jahre mit Datenbanksystemen ob nun Oracel, DB2 oder MySql, am liebsten immer mit Postgres. Ich habe in diesem Forum schon viel gelesen und einiges gefunden das mir bei meiner arbeit geholfen hat. Also danke an alle die hier so fleisig schreiben.

Macht durchaus Sinn:
Unter Zahlreichen Bedingungen ist es erforderlich diese Lücken zu Nutzen. Erstes Beispiel sind automatische Abrechnungs oder Auftragssystem im Telekomunikationsbereich. In solchen Systeme laufen Sequezes trotz ihrer beachtlichen größe nach einem Jahr über. Zweites Beispeil ist ein profane Artikel-Nr.. In einem von mir verwaltetem Productkatalog gibt es Täglich ca. 10.000 Updates. Aus juristischen Gründen dürfen aber bisher für den Verkauf verwendete Productdatensätze nicht einfach gelöscht werden. Deshalb und aus Performensgründen werden die neuen Daten einfach mit neuer Product-ID eingefügt. Ein Überlauf ist hier weniger das Problem aber die Product-Nr wird in Katalogen und Online Shops verwendet und die lesbarkeit für Menschen nimmt mit jeder Stelle mehr deutlich ab. Wenn nach Ablauf einer bestimmten Zeit diese Sätze gelöscht werden ist es zwingend notwendig diese Lücken neu zu vergeben. Sind nur zwei von vielen Beispielen (Kunden oder Lieferanten Nummern, Konto-Nr. bei der Fibu, usw.).

Soviel zur Erklärung warum es durchaus Sinn macht und jetzt einen möglichen Lösungsansatz der auch Multiuserfähig ist (Nur mal so angemerkt es läst sich auch das durchzählen Multiuserfähig realisereren aber wie marcomania schon anmerkte eine langsame Lösung.)

Lösungsmöglichkeit:
Schneller gehts wenn man in einer eigenen Tabelle solche Lücken verwaltet. Wird ein Datensatz gelöscht diesen Index in die Liste eintragen und beim nächsten Insert einen Wert aus der Tabelle lesen und diesen dann Löschen. Mit der Verwendung von Transaktionen und Satzsperren kann die Multiuserfähikeit sicher gestellt werden.

Will man die Anwendung nicht mit dem Speichern belasten läst man einen Prozess mitlaufen der nach der durchzählen Methode nach Lücken sucht und diese dann in einer eigenen Tabelle speichert. Diesem Prozess muß man aber unbedingt die CPU Zeit begrenzen da er sonst eine hohe Systemlast verursacht.

Man kann diese Methode noch an vielen Stellen verfeinern ich wollte nur mal grob eine prinzipielle möglichkeit beschreiben.

Viele Grüße
Alexander
alexander_ro
Benutzer
 
Beiträge: 82
Registriert: So 12. Nov 2006, 13:29

Beitragvon akretschmer » So 12. Nov 2006, 18:22

alexander_ro hat geschrieben:Hallo,

Macht durchaus Sinn:
Unter Zahlreichen Bedingungen ist es erforderlich diese Lücken zu Nutzen. Erstes Beispiel sind automatische Abrechnungs oder Auftragssystem im Telekomunikationsbereich. In solchen Systeme laufen Sequezes trotz ihrer beachtlichen größe nach einem Jahr über.

Viele Grüße
Alexander


Zeig mir Anwendung und Hardware, die pro Sekunde ca. 292471208677 Daten erzeugt.

Hint: bigseriel geht bis 9223372036854775807.
akretschmer
Erfahrener Benutzer
 
Beiträge: 5938
Registriert: So 29. Okt 2006, 14:35
Wohnort: Kaufbach, Sachsen, Germany, Germany

Beitragvon ads » So 12. Nov 2006, 18:54

Selbst wenn dies alles nicht reichen sollte, gibt es im Contrib Verzeichnis von PostgreSQL einen Datentyp, der 128 Bit breit ist. Das dürfte dann genügen, um alle Atome im Universum zu zählen.

Du siehst also, an Grenzen stoßen wir nicht ;-)
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support
ads
Erfahrener Benutzer
 
Beiträge: 4147
Registriert: Mi 8. Feb 2006, 11:58
Wohnort: MD

Beitragvon alexander_ro » So 12. Nov 2006, 19:32

Was glaubst Du wieviele Abrechnungsdaten ein Telefonnetze pro sekunde erzeugt?

Viel Spaß wenn Du so eine '9223372036854775807' Bestell-Nr oder Kunden-Nr oder oder oder auf einen Bestellschein schreiben mußt. Ein Unternehmen das sowas einem Kunden zumutet ist Pleite bevor es richtig gegründet wurde.

Größe ist nicht alles es ist immer noch die Frage wer diese Indexe handeln muß. Menschen oder Maschinen. Also gibt es immer noch gute Gründe Lücken im Index wieder zu verwenden.
alexander_ro
Benutzer
 
Beiträge: 82
Registriert: So 12. Nov 2006, 13:29

Beitragvon ads » So 12. Nov 2006, 19:42

alexander_ro: die von dir angesprochenen Probleme bewegen sich sicher ein einem ganz anderen Bereich als die des Originalposters. Wenn ich weiss, das ich pro Tag mehrere Millionen Datensätze generiere, dann schaue ich auch, das dieses System damit einige Jahre mehr arbeiten kann. Für den Normalverbraucher von Sequenzen kommt so etwas aber weniger in Betracht.

Abgesehen davon, das große Datensatznummer nicht gleich Rechnungsnummer nicht gleich Kundennummer ist, wie die Daten intern gehandhabt werden, interessiert eher selten. Der Kunde sieht dann so etwas wie "Jahr/Monat/Kundennummer/Rechnungsnummer" und das entschärft viele Probleme.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören Bild

Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

PostgreSQL Service & Support
ads
Erfahrener Benutzer
 
Beiträge: 4147
Registriert: Mi 8. Feb 2006, 11:58
Wohnort: MD

Beitragvon akretschmer » So 12. Nov 2006, 19:56

alexander_ro hat geschrieben:Was glaubst Du wieviele Abrechnungsdaten ein Telefonnetze pro sekunde erzeugt?

Viel Spaß wenn Du so eine '9223372036854775807' Bestell-Nr oder Kunden-Nr oder oder oder auf einen Bestellschein schreiben mußt. Ein Unternehmen das sowas einem Kunden zumutet ist Pleite bevor es richtig gegründet wurde.

Größe ist nicht alles es ist immer noch die Frage wer diese Indexe handeln muß. Menschen oder Maschinen. Also gibt es immer noch gute Gründe Lücken im Index wieder zu verwenden.



Das Argument ist IMHO Unfug. Abrechnungsdaten sind für mich hier die reinen Verbindungsdaten,
die vielleicht in einer Tabelle anfallen, in der 10.000 oder von mir aus noch mehr Kunden
stehen. Der Kunde hat dann eine Kundennummer, die auch auf der Abrechnung steht,
nicht aber die Datensatznummer, mit der sein Anruf in Deiner internen Datenbank steht.

Und Indexe handelt in einer DB nie ein Mensch. Der vergißt nur, diese anzulegen...

Und für den Fragesteller:

Angenommen, die hast eine Table table_with_gaps, die Löcher enthält. Dir ist bekannt,
daß die höchste ID 10.000 ist. Du willst nun das erste Loch finden:

select generate_series(1,10000) except select id from table_with_gaps limit 1;

Allerdings performt das nicht wirklich. Wenn Du von Anfang an Dich um die 'Löcher'
kümmern willst, wirst Du diese mittels Trigger Dir merken müssen.
akretschmer
Erfahrener Benutzer
 
Beiträge: 5938
Registriert: So 29. Okt 2006, 14:35
Wohnort: Kaufbach, Sachsen, Germany, Germany

Beitragvon alexander_ro » Mo 13. Nov 2006, 00:03

Also dass es Indexe nur intern gibt kann ich mir kaum vorstellen.

Was bringt es mir für eine Kunden-Nr. einen zweiten internen Index der ebenfalls eindeutig sein muß zu generieren? Die Frage ob der Fragesteller es brauch kann ich nicht beantworten weil ich nichts über die Anwendung weiß. Das vergessen des Indexes durch Anwender verhindert die Datenbank und oder die Anwendung.

Aber ich sehe schon wir werden uns da wohl nicht einig werden also nix für ungut war nur ein Vorschlag und funktionieren tut er. Ob jemand das braucht muß er selber entscheiden ich verwende die Methode und finde sie auch in Ordnung. :D
alexander_ro
Benutzer
 
Beiträge: 82
Registriert: So 12. Nov 2006, 13:29

Beitragvon Xandrian » Mo 13. Nov 2006, 08:13

moin,

also das beispiel mit den kunden hinkt... erwartete weltbevölkerung bis Mai 2007 (quelle wikipedia):

6.600.000.000 (= 6,6 Mrd)

bigserial geht standardmäßig bis:

9.223.372.036.854.775.807

nur so am rande... aber wir werden off-topic...

cu tb.
pg-forum.de unterstützen? Meine Wunschliste

Bild Bild
Benutzeravatar
Xandrian
Erfahrener Benutzer
 
Beiträge: 1612
Registriert: Mi 23. Nov 2005, 10:17
Wohnort: Bayreuth

Nächste

Zurück zu SQL

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast