issca
Goto Top

Herausforderung bei der vorzeitigen ID Vergabe in PHP MySQL-Portal. Lösungsansätze gesucht

Hallo zusammen,

Derzeit befinde ich mich in einer Umschulung zum Fachinformatiker und arbeite während meines Praktikums an der Lösung einer speziellen Aufgabe. Dabei handelt es sich um ein Portal, das mithilfe von PHP erstellt wurde und mit einer MySQL-Datenbank verknüpft ist. In diesem Portal werden neue Aufträge erstellt, wobei die Datenbank automatisch fortlaufende Inkrement-IDs für jeden neu erstellten Auftrag vergibt.

Allerdings benötige ich die ID im Voraus, bevor ich einen Auftrag erstelle. Dies ist notwendig, da ich die ID zuvor in ein anderes System eintragen muss, um die erforderlichen Daten für den neuen Auftrag zu erhalten. Die ID sollte ausschließlich für diesen speziellen Auftrag registriert sein. Das bedeutet, dass, falls in der Zwischenzeit ein anderer Benutzer auf derselben Seite einen neuen Auftrag erstellen möchte, er nicht dieselbe ID erhalten darf. Dies liegt daran, dass ich sie bereits in das andere System eingetragen habe, jedoch in unserer Datenbank noch keinen Datensatz mit dieser ID angelegt habe.

Die Frage ist, wie ich dieses Problem lösen kann, insbesondere wenn die ID-Vergabe durch MySQL mit Auto-Increment automatisch und fortlaufend erfolgt.

Momentan habe ich es so gelöst, dass ich einen leeren Datensatz bzw. einen neuen Auftrag angelegt habe. Nach dem Anlegen des neuen Auftrags öffnet sich eine Seite, um diesen Datensatz zu bearbeiten. Der Datensatz bleibt in der Datenbank so lange leer und für mich reserviert, bis ich die Daten eingebe und sie übertrage. Ist dies ein guter Ansatz, oder gibt es bessere Lösungsmöglichkeiten?


Danke allen im voraus.

Content-ID: 42668042423

Url: https://administrator.de/contentid/42668042423

Ausgedruckt am: 24.11.2024 um 10:11 Uhr

Crusher79
Crusher79 11.01.2024 um 15:25:23 Uhr
Goto Top
Hallo,

vermutlich dann nur so und nicht anders? Sonst arbeitest du gegen das System.

Ggf. mit curl o.ä. die Dummy Aufträge wie voon dir beschrieben erstellen - leerer Rumpf. Mehr geht eigentlich nciht. Sonst würde man gegen das System arbeiten oder direkt am Server manipulieren.
Jugg3r
Jugg3r 11.01.2024 um 15:33:03 Uhr
Goto Top
Da Du die IDs nicht kennst, must Du sie Dir von der DB erstellen lassen.

Einen leeren Datensatz zu erstellen halte ich für den besten Ansatz.
Die Alternative wäre, den Datensatz bis zum Schreiben offen zu halten und das wäre ein No-Go.

Sonst sehe ich nur die Möglichkeit, den Vorgang an sich ab zu ändern, sodass Du die IDs nicht im Vorfeld benötigst.

Generell wäre es nicht schlimm, wenn leere Zeilen generiert werden. Dann sollte man nur die Db regelmäßig "aufräumen" und komprimieren.

  • just my 2 Cents *
StefanKittel
StefanKittel 11.01.2024 um 15:44:58 Uhr
Goto Top
Moin,
soweit so richtig.
Du erstellst einen Datensatz mit einem Status der anzeigt, dass dieser in Vorbereitung ist.
z.B.
ID = Autowert
Status = 0 (Init)
Status = 1 (Created)

Wenn Die Erstellung des Datensatzes dann abgebrochen wird, löscht man den Eintrag.
Oder, wenn man wie ich z.B. ungern was löscht, setzt man den Status einfach auf -1 (deleted).

Alternativ (gebastelt) kann man eine zufällige ID generieren lassen, prüfen ob diese nicht bereits verwendet wird und hoffen, dass die Wahrscheintlichkeit von 1:1.000.000.000.000.000 ausreicht, dass Niemand anderes diese ID zufällig erzeigt. Oder sie in Memcache ablegen oder ähnliches.

Stefan
issca
issca 11.01.2024 um 15:45:56 Uhr
Goto Top
Vielen Dank für die Antworten, also war ich garnicht mal schlecht mit meiner Lösung.

Leider kann der Vorgang nicht verändert werden weil die Auftragsdaten von einem externen Firma nur zur Verfügung gestellt werden wenn von uns eine eindeutige ID an die weiter gegeben wird.

Diese Lösung muss dann wohl so wie ich es gelöst habe implementiert werden.

Falls noch andere Tipps kommen nehme ich sie gerne an. Ich muss ja schließlich noch etwas lernen face-smile.


Wünsche allen noch eine schöne Woche.
Crusher79
Crusher79 11.01.2024 um 15:57:34 Uhr
Goto Top
Frage ist ja auch, ob es sonst Lücken geben dürfte.

Bei Rechnungen o.ä. will man immer zusammhängende im Nummerkreis haben. Lücken kann man mal mit IT Wechsel o.ä. erkären, aber nicht immer.

Wenn du Nummern nur dafür blockst, muss eh der Auftrag doch darauf - wie jetzt auch - geschrieben werden. Sonst läfut es wieder auseinander und du hättest 2 Nummern.

Es gibt komplexe PHP und Syonfony Geschichten. Oder rel. einfache. Wo man einfach munter mal einen POST mit ein paar Daten absetzen kann. Je nach Umfang kannst du damit zumindest die Generierung der Aufträge vereinfachen oder schon Dinge mitgeben/ eintragen.

Mehr Optimierungspotential sehe ich hier leider nicht.

Bei anderen Systemen oder manuellen Eintragungen besteht auch immer die Gefahr, dass Lücken auftauchen. Einer ID Range sind Lücken egal. Sind das Auftrags oder Rechnungsnummern wird es kritischer.

"Mit den System arbeiten" - wie du es ja schon machst. Und ggf. ein Paar Mausklicks und Keystrokes mittels curl oder Google Chrome Automa einsparen.
issca
issca 11.01.2024 um 16:06:03 Uhr
Goto Top
Hallo Crusher79,

da die ID von der Datenbank die ich bekomme immer einem bestimmten Auftrag zugeordnet wird (beider externen Firma von den wir die Daten bekommen) bevor die Auftragsdaten in der Datenbank übertragen wird ist es immer eindeutig welcher ID zu welchem Auftrag gehört gibt es keine Lücken bzw. leere Datensätze. Auch wenn die Daten erst später ankommen wird der Datensatz mit der ID aufgerufen um die Daten einzupflegen.

Also ne andere Lösung konnte ich mit meinem Wissensstand nicht finden. Ich stehe ja auch noch am Anfang meines Praktikums.

Danke.
Crusher79
Crusher79 11.01.2024 um 16:22:14 Uhr
Goto Top
Ich kaute nur etwas auf @StefanKittel Beitrag herum.

Alternativ (gebastelt) kann man eine zufällige ID generieren lassen, prüfen ob diese nicht bereits verwendet wird und hoffen, [...]

Blocken oder round-robin sich eine schnappen geht ja nicht. Da wir mit der externen Firman ein 100% Match brauchen. Immer und zu jederzeit.

Es gebe noch eine andere Methode. Mit 2x Nummerkreisen arbeiten. Dann muss es aber absprachen und ggf. eine Zusatztabelle geben.

2 Systeme, mit unterschiedlichen IDs für einen Auftrag. Eine Art "Übersetzung". Sowas hat man in ERP Systemen fürs Material. Eigene Material-Nr/ Fremd-Material Nummer.

Also ganz bewusst mit unterschiedlichen, machmal gleichen IDs arbeiten, die aber NIE zusammenkommen. In getrennten Systemen stehen. Über Logik und eine "Übersetzungstabelle" werden dann die Bausteine wieder zusammengesetzt.

Letzteres heisst aber Absprachen, ggf. Software-Anpassung, Zusatz-Modul um am Ende wieder ein Mapping zu erreichen.
StefanKittel
StefanKittel 11.01.2024 um 16:41:35 Uhr
Goto Top
Hallo,

das von Crusher79 finde ich jut (wie ein Berliner sagen würde).

Tabelle TBL_ExternReference
ID=Autowert
PartnerName = String (z.B. Firmenname)
oder
PartnerID = 5 (=Firma X)
Status = (0=init, 1=ok, 2=error)

Du erstellst erst diese Reference.
Dazu verwendest Du die ID (Autowert) dieser Tabelle

Wenn das alles OK ist, erstellst Du den Auftrag
ReferenceID = ID aus TBL_ExternReference

Stefan
Crusher79
Crusher79 11.01.2024 um 17:20:44 Uhr
Goto Top
Naja ich hätte mal gerne Datensätze als Bsp.

Ist das andere System auch MySQL? Man kann ja auch andere DB, Tabellen dazu linken. Bzw. mit INSERT und UPDATE Statements hin und her springen.

Der Nachteil ist nur, dass dann die Nummern in beiden Systemen ohne die Zwischentabelle sich nicht ableiten lassen. Ist normal ja auch großes Problem. Je nachdem, was halt dahinter steht.

Aufträge und Rechnungen hat man meist einen zusammenhängenden Nummernkreis. Wenn "Auftrag" abe rein für interne Zweckde dient und es mehr einen Sachverhalt beschreibt, so ist man freier!


Wenn möglich stell mal anonymisiert die beiden Systeme hier mit Datensätzen dar. Auch ob es um rechtssichere Belege oder andere Workflows/ Verfahren geht. Ggf. kleine Verfahrensbeschreibung ?!?
StefanKittel
StefanKittel 11.01.2024 um 17:30:21 Uhr
Goto Top
Stichwort ist hier EDI (electronic data interchange).
Eine Schnittstelle zwischen zwei getrennten und nicht kompatiblen Systemen.
Crusher79
Crusher79 11.01.2024 um 17:42:48 Uhr
Goto Top
Zitat von @StefanKittel:

Stichwort ist hier EDI (electronic data interchange).
Eine Schnittstelle zwischen zwei getrennten und nicht kompatiblen Systemen.

Haben wir auch. Bzw. noch Lobster dazwischen.

Nur hier wurde es auch vom ERP vorgesehen. A1,A2,A3... B1,B2,B3... arbeiten mit OpenSUSE und Informix

https://4js.com/support/ibm-i4gl-to-genero/

Lobst ist ja eh kein muss. EDI läuft ja schon seit Jahrzehnten?! immer gleich ab. Allerdings muss man etwas dafür tun face-wink
em-pie
em-pie 11.01.2024 um 20:10:00 Uhr
Goto Top
Moin,

Mal ne blöde Frage:
Ist die Anbindung von eurem Partner an euch ein Pull oder Push-Prinzip?
Also holt ihr die Daten oder bekommt ihr sie und meldet dann zurück?

Denn was wäre, wenn ihr einen Webservice anbietet, in dem euer Partner euch den Kram sendet, ihr den verarbeitet und weil es ein (a)synchroner Job ist, ihr eurem Partner eure ID zurücksendet?
issca
issca 12.01.2024 um 07:58:09 Uhr
Goto Top
Moin zusammen,

also die ID wir von uns an die externe Firma per Mail übermittelt und bekommen die Daten die wir für den Auftrag brauchen auch wieder per Mail. Dahinter ist ein ticket System was die Firma nutzt, wird also alles manuell gemacht. Es gibt keine direkte Verbindung oder Synchronisation oder ähnliches. Ich vermute das die sogar mit Excel Tabellen im Hintergrund arbeiten. Wir haben kein Einblick darauf. Sowie ich es verstanden habe wollen sie das auch weiterhin so handhaben weil sie kein Geld und Zeit ausgeben wollen, da auch im Jahr nur so ca. 250 bis 300 Aufträge sind die an uns übermittelt werden.

Ich habe eben die Aufgabe bekommen da eine Lösung zu finden weil das auch gleichzeitig meine Projektarbeit für die IHK Abschlussprüfung sein wird.

Die Lösung die ich gefunden habe wird denke ich für diese menge an Aufträge soweit problemlos funktionieren.
Ich höre mir immer gerne weitere Lösungen, Vorschläge usw. von erfahrenen Profis an da ich selbst noch nicht viel Übung darin habe.

Ich danke Euch allen. Wünsche jetzt schon mal ein schönes und ruhiges Wochenende.


Gr.Ayhan
Crusher79
Crusher79 12.01.2024 um 08:40:11 Uhr
Goto Top
Oh man.....

Ja, abe reicht das für die IHK? Gut, man kann aus ###e kein Gold machen. Aber das hier ist etwas unfair oder? Industrie 4.0 etc.

@StefanKittel hat ja ähnliches geschrieben. Im Idefall könnte man hier ggf. Projekt etwas frisieren und es doch so durchziehen. Hauptsache du hast es gemacht und ist abgezeichnet.

Aber ehrlich? Hier haben doch einige gepennt! Oder keine Ahnung vin EDI; Industrie 4.0 etc. "Wir optimieren den Weg zum Kaffee holen." Finde es als IHK Projekt eher bescheiden. Vor allem weil die eig. Lösung durch Mangel an Motivation in weite ferne rückt!
issca
issca 12.01.2024 um 09:28:04 Uhr
Goto Top
Das mit dem Projekt für die IHK bin ich auch noch nicht sicher ob das reicht. Habe noch ein zweites Projekt in petto. Automatische Rechnungserstellung als PDF und senden als Mail. Der Chef schaut sich das an und wird dann entscheiden welches ich als Projekt nehmen soll. Er ist selbst IHK Prüfer.
HansDampf06
HansDampf06 12.01.2024 um 12:52:20 Uhr
Goto Top
Ich werfe meine fünf Pfennige in den Ring:

Zitat von @StefanKittel:
das von Crusher79 finde ich jut (wie ein Berliner sagen würde).

Tabelle TBL_ExternReference
ID=Autowert
PartnerName = String (z.B. Firmenname)
oder
PartnerID = 5 (=Firma X)
Status = (0=init, 1=ok, 2=error)

Du erstellst erst diese Reference.
Dazu verwendest Du die ID (Autowert) dieser Tabelle

Wenn das alles OK ist, erstellst Du den Auftrag
ReferenceID = ID aus TBL_ExternReference

Bei hinreichend genauer Betrachtung des Problems ist das der (wohl einzig) richtige Ansatz!

Warum? Man darf sich nämlich nicht von der Autowert-ID der betreffenden Tabelle in der Datenbank in die Irre führen lassen. Denn in einer relationalen Datenbank dient diese ID-Spalte in erster Linie der eineindeutigen Identifizierung und Referenzierung der einzelnen Tabellenzeile zu anderen Tabellen / Datenquellen.
Hingegen ist das nicht (zwingend) mit der Auftragsnummer, die letztlich auf das Papier gedruckt wird, gleichzusetzen.

Wird die Autowert-ID der bisherigen Auftragstabelle zugleich als Auftragsnummer auf dem Papier verwendet, dann ist es selbstredend, dass in dieser Tabelle temporäre / ungenutzte / leere Zeilen nichts zu suchen haben. Erst wenn die Erstellung des Auftrags final abgeschlossen ist, darf (/ sollte) in dieser Auftragstabelle eine neue Zeile geschrieben und dadurch ein neuer ID-Wert generiert werden, insbesondere wenn es - z.B. aus steuerlichen Gründen - keine ungenutzten "Lücken" im Nummernkreis geben darf / soll / etc.

Unter dieser Prämisse führt die Problemlage zwingend zu einer notwendigen zweiten Tabelle, die der zuordnenden Referenzierung dient. Eine solche Referenztabelle kann und darf dann auch obsolete / ungenutzte / abgebrochene Auftragserstellungsvorgänge und somit "leere" Zeilen enthalten, die das finale Stadium nicht erreicht haben und somit in der Auftragstabelle keine zugehörige Tabellenzeile haben.

Entscheidend bei dem Ansatz ist aber, dass die Datenbank mit der Auftragstabelle mit einer solchen Referenztabelle ergänzt werden kann. Dann würde der Vorgang so ablaufen, wie es @Crusher79 in seinem Vorschlag beschrieben hat. In der Referenztabelle, die natürlich auch eine Autowert-ID hat, wird eine neue Tabellenzeile generiert und der Status wird automatisch auf „Bearbeitung“ gesetzt (= Defaultwert). Diese Autowert-ID ist diejenige ID, die an die andere Datenbank zum Erhalt der notwendigen Daten für den Auftrag übermittelt wird. Erreicht der Auftragserstellungsvorgang das finale Ende, so wird in der Auftragstabelle eine neue Zeile mit den finalen Auftragsdaten befüllt und die dabei generierte Autowert-ID wird im dritten Feld der Referenztabelle eingetragen. Mit diesem Eintrag zusammen wird zugleich der Status auf abgeschlossen aktualisiert.

Natürlich funktioniert das alles genauso, wenn nicht in der Auftragsdatenbank, aber dafür in der anderen Datenbank eine solche Referenztabelle erstellt und genutzt werden kann. Und wenn alle Stränge reißen, bedarf es eben einer kleinen dritten Datenbank mit "nur" dieser Referenztabelle; in dem Fall könnte diese Datenbank sogar einen direkten Datenlink zu den anderen beiden Datenbanken haben. Die Zugangsdaten dürften augenscheinlich in der Webanwendung hinterlegt sein.

Im Ergebnis: Auf diese Art und Weise sind beide Datenbanken mittels der Referenztabelle jederzeit relational eineindeutig miteinander verknüpft. Es lassen sich alle relevanten Anforderungen an die Datenverarbeitung sicher umsetzen.

Viel Erfolg und viele Grüße
HansDampf06
em-pie
em-pie 13.01.2024 aktualisiert um 09:43:21 Uhr
Goto Top
also die ID wir von uns an die externe Firma per Mail übermittelt und bekommen die Daten die wir für den Auftrag brauchen auch wieder per Mail. Dahinter ist ein ticket System was die Firma nutzt, wird also alles manuell gemacht. Es gibt keine direkte Verbindung oder Synchronisation oder ähnliches.
Häh?
Also fragt ihr euren Partner immer „Habt ihr einen Auftrag für uns?“
Normalerweise klingelt doch der Kunde mit einer Bestellung und all seinen Daten an. Ihr legt einen Auftrag mit all den Daten an und gebt ihm, passend zu seiner BestellNr., die ihr bei euch mit hinterlegt, eure AuftragsNr (nebst Positionen) zurück. Fertig!

Und wie oben schon beschrieben:
In eurer DB gibt es dann eine autoinkrementelle ID (bzw. GUID), die zusätzlich zur lesbaren Auftragsnummer im Datensatz abgelegt wird.
bloodstix
bloodstix 13.01.2024 um 13:57:28 Uhr
Goto Top
Kannst du nicht mit uuid's arbeiten? Die kann man in PHP generieren und sollten immer einzigartig sein.
StefanKittel
StefanKittel 13.01.2024 um 18:14:46 Uhr
Goto Top
Zitat von @bloodstix:
Kannst du nicht mit uuid's arbeiten? Die kann man in PHP generieren und sollten immer einzigartig sein.

"Warnung:Diese Funktion garantiert nicht die Eindeutigkeit der Rückgabewerte. Da die meisten System die Systemzeit durch NTP oder ähnlich justieren, ändert sich die Systemzeit kontinuierlich. Daher ist es möglich, dass diese Funktion keine eindeutige ID für den Prozess/Thread zurückgibt. more_entropy kann verwendet werden, um die Wahrscheinlichkeit der Eindeutigkeit zu erhöhen.". Quelle: https://www.php.net/manual/de/function.uniqid.php

Prinzipbedingt kann es eindeutige Werte nur durch eine Tabelle oder ähnliches geben.
Wobei in den meisten Fällen eine UUID ausreicht.

Aber warum das "Risiko" eingehen. Mit dem Autowert einer Transfer-Tabelle ist man auf der sicheren Seite.

Stefan
bloodstix
bloodstix 13.01.2024 um 18:25:01 Uhr
Goto Top
Ok, danke für den Hinweis, war mir bisher auch nicht bewusst. Hatte aber noch nie einen Fall in dem das schief ging. Ansonsten hilft vielleicht die Seite: https://www.uuidgenerator.net/dev-corner/php
Da isn Rezept um RFC 4122 compliant Version 4 UUIDs zu generieren.

Aber Recht hast du, völlig sicher ist es mit der Transfer-Tabelle.
StefanKittel
StefanKittel 13.01.2024 um 22:06:28 Uhr
Goto Top
Zitat von @bloodstix:
Ok, danke für den Hinweis, war mir bisher auch nicht bewusst. Hatte aber noch nie einen Fall in dem das schief ging.
Das geht auch auch nur 1 mal in Deinem Leben schief.
Da aber keiner damit rechnet ist das ein einmaliger Glitch der dazu führt, dass irgendwo ein Atomkraftwerk abbrent.

Man kann es aus praktischen Gründen unproblematisch nutzen.

Man sollte es aber nicht nutzen weil es schlechtes Programmieren ist.
Aus Prinzip halt.

Stefan
Crusher79
Crusher79 13.01.2024 um 22:15:08 Uhr
Goto Top
Naja ansonsten kommt es auf die genutzten Plattformen und Datenbanken an. Wenn man Anwendng für MS-SQL und Oracle hat, wird schon die Erstellung zum Problem.

UPDATE, INSERT, SELECT laufen meist in vielen DBs gleich. Speziell bei der UID Erstellung muss ggf. noch explizite Schritte ausführen oder die gesamte Erstellroutine anpassen. IDs sind da leichter zu handhaben. Auch Anomalien fallen direkt auf. Eine weitere Alternative wären noch zusammengesetzte Schlüssel, die eine Eindeutigkeit herstellen können.

Naja UID, ID sind uns ja allen sonst soweit klar. Löst nur sein Problem nicht. Ich hab mich auch gedanklich verzettelt . Wäre vlt. gut wenn er die Workflows nochmal gegenüberstellt. Wenn es ein Projekt ist, wäre eine Lösung nicht verkehrt. Prüfer sehen zwar gerne, wenn man Zeiten korrigiert. Da man sich in der Duchführungsphase dann doch hier und da schneller oder langsamer war.

Nur hier ist ggf. wegen fehlenden know-how oder Mitwirklung das Ganze zum Scheitern verurteilt.