 Ja, herzlich willkommen hier im Medienteater auf der GPN 18. Als nächstes haben wir einen schönen Vortrag für alle Gruselfreunde hier. Es geht um Datenbanken, historisch Gewachsene und unser nächster Speaker hat mit eben solchen Sachen beruflich zu tun. Ich möchte, dass ihr mit mir hier erst mal herzlich SMTV begrüßt. Hallo. Hallo. Da sind die Mikros noch zu. Na doch, ich glaube die Mikros gehen. Wie gesagt, SMTV beschäftigt sich beruflich mit ERP-Systemen, unter anderem mit Nischen ERP-Systemen. Und was er da so im Laufe seiner letzten Jahre Berufserfahrung alles Schönes gefunden hat. Das seht ihr jetzt hier. Viel Spaß und einen großen Applaus für SMTV. Dankeschön. Ja, wir hatten ja gerade schon die Süßatmen Nightmares. Es ist eigentlich ganz passend im Track. Also wie schon gesagt, organische Fundstücke aus organisch gewachsenen Datenbanken. Vielleicht kurz, wie es dazu kam. Ich nenne das mal Motivation. Ihr kennt das vielleicht, der hat so einen komischen Brockenalter-Software rumliegen, die die Firma irgendwie einsetzt. Und dann geht das los, dann gibt es Performance-Issues und dann fängt man mal ein bisschen in der Datenbank rum zu popeln. Und so gerne gesehen, das Sachen sind so fehlende falsche Indizes. Bug Fixing auch immer beliebt, wenn das Frontend abgestürzt ist und da hat man plötzlich doppelte Rechnungsnummern, also was er Freude macht. Man möchte vielleicht ein Subsystem anbinden. Klassiker ist so Rufnummernauflösung für die Telefonanlage. Muss man dran flanschen. Bei so Nischen ERP-Systemen kann das natürlich nichts out of the box. Man will vielleicht ein paar Auswertungen machen. Komplexere individuellere Statistiken, ein paar Reports, die das Management steht da bekanntermaßen drauf. Unter Umständen will man auch, das habe ich bei einem System gemacht, ein Web-Interface dran flanschen, weil Delphi Fat Clients machen echt kein Spaß als Frontend. Auch in Kürze die üblichen Tools, die man da so verwenden kann, um sich ein bisschen Datenbank zu Reverse Engenieren oder durchzugraben. Die meisten haben eigentlich irgendwie ein Command-Lined-Interface oder auch die schöne Datenbank-Software von Microsoft SQL. Ihr findet Profiler, Logging-Systeme, es gibt häufig Metatables, Schematables, was in die Richtung einzelne Befehle sollte man sich vielleicht dann auch mal oder abfragen. Sollte man sich dann vielleicht auch mal so mit Explain und Describe auseinander nehmen, wie läuft eigentlich die Abfrage so an sich. Irgendwann hat man dann noch mal noch so eine kleine Sammlung an Skripten, die man ja hier rumliegen hat, um in der gesamten Datenbank einzelne Felder zu suchen, so Späße. Dann braucht man natürlich noch Geduld und Mathe, Kaffee und Pizza und dann kann man sich da mal ein bisschen mit auseinandersetzen. Die Quellen wurde schon an genannt, diverse ERP-Systeme, eher so Nischenfu für ERP-Systemhäuser, Gastronomie-Gewerbe, Ominöse, Getränke, Geschichten oder Ähnliches, fast alles Microsoft SQL Datenbanken, mit denen ich jetzt gebastelt habe. Häufig nicht schön und manchmal hat man das so Gefühl, früher stand da mal eine Excel-Tabelle, dann kam eine Access-Datenbank, dann kam irgendwie der Azubi und meinte Microsoft SQL machen zu wollen. Ich werde keine Namen nennen, aber ich habe euch mal so ein bisschen die Selbstbeschreibung der Hersteller auf den Webseiten rausgezogen. Gehören zu den führenden Anbietern im ERP-Software-Umfeld, international bewährte Server-Lösungen, erfahrene Software-Experten fand ich besonders toll. Aktuellste Sicherheitsstandards, zeitgemäße Verschlüsselungstechniken, könnt ihr euch mal für später vormerken. Schauen wir doch mal rein, ich fange mal einfach an, es geht so ein bisschen ums Naming. Ich habe da so eine Datenbank, da werden irgendwelche Artikel mitverwaltet und dann sucht man erstmal so, wo liegen denn, in welcher Tabelle liegen denn eigentlich die Artikel. Und dann sucht man so in diesem Schematabels, was ist denn alles, wo der Name Arty oder irgendwie sowas vorkommt, um die Tabelle zu suchen. Gut, gefunden, nicht ganz erwartet das Ergebnis. Besonders schön in einer Datenbank Artik AAA, Artik Alt als Tabellennamen. Hat so das Niveau von Powerpoint Version 4, jetzt neu aber wirklich. Also die sind genauso aus den laufenden Systemen und sind auch noch in dem Installdump, also in dem leeren Dump, was man bekommt, wenn man die Software installiert, genauso drin, keine Ahnung warum. Nicht sehr viel besser ist dann das Naming in den Spalten. Das ist jetzt aus einer Tabelle, es ist jetzt nicht so, dass das irgendwie verteilt ist. Alles dabei, Camelcase, Anderscore, ich hatte dann auch noch welche mit All, Uppercase und so weiter, also man wird da so ein bisschen verwirrt. Das ist schwierig lesbar, finde ich dann auch immer schön, wenn dann so direkt nebeneinander Beschreibung, Tiefstrich 1 und Zusatzinfo 1 direkt daneben steht. Muss man jetzt nicht unbedingt machen, kann man natürlich. Vielleicht resultiert dann daraus auch so ein bisschen was, was wir uns hier mal kurz anschauen. Ich habe da jetzt so als Beispiel mal eine Kundentabelle, ID 23, der Name ist Fuba von dem Kunden. Und dann muss man mal schauen, was denn dieser Kunde so gemacht hat und guckt sich dann in den anderen Tabellen die Referenzierung an. Und normalerweise würde ich jetzt erwarten, so okay, da gibt es jetzt dann einen Namen und da zieht sich überall durch und dann steht da halt in der Tabelle drin, das ist jetzt von der KundenID. In dieser Datenbank habe ich gefunden als Referenzierungsname, KundeID 3, KundeID, KundennID, CustomerID. Also irgendwie weiß dann auch wieder so kein Mensch, wo geht es denn eigentlich hin. Ähnliche Spaß geht dann weiter beim Username, da haben wir den Usertable, auch ein Username drin, in dem Fall auch mal wieder ein bisschen Fuba. Und dann schaut das man jetzt in der anderen Tabelle sagt, naja, UserID ist die 23, 0, da steht geändert von und der Name steht drin. Wenn ich jetzt den Username in der Usertable ändere, dann steht da halt immer noch drin, der Herr Fuba hat es geändert und kein Mensch findet mehr, wer das ursprünglich geändert hat. Es sollte vielleicht ungefähr so aussehen, also einfach nur auf die Basis und ein vernünftiges Naming. Ich habe jetzt hier mal als Beispiel geschnommen, Change by UserID, dann weiß man eigentlich so gleich, wenn man diese Tabellen auseinander nimmt, geändert von. Okay, und dann UserID, alles klar, ich schaue in der Tabelle User nach und da spalt UserID wunderbar gefunden. Es gibt da so einen schönen Satz, was diese Keys betrifft, das ist the key, the whole key and nothing but the key, so help me cod. Ein paar Kichern etwas, cod war ein britischer Mathematiker und Datenbanktheoretiker, der hat, dem haben wir eigentlich so das moderne, relationale Datenbankdesign in irgendeiner Form mal grundlegend zu verdanken, der hat sich da sehr viel mit beschäftigt. Kann man sich so ein bisschen merken, wenn man damit zu tun hat, kümmert euch um die Keys. Was es Naming betrifft, mal so kurz zusammengefasst, da ist natürlich keine Wahrheit, da kann man vieles machen und da jeder sein anderes Geschmäckler, wie man so schön sagt. Es gibt aber ein paar Basics, keine Sonderzeichen, also ein Tabell namens AS und OS, schwierig, keine reservierten Wörter, gibt tatsächlich Datenbanken, wo man dann drinnen sieht, dass dann die Tabelle Select heißt. Ihr könnt euch vorstellen, wie viel Spaß das macht, das zu debaggen. Ich nenn's jetzt mal Juno Uno Sprache, diesen wilden Mix aus deutschen Begriffen, englischen Begriffen im Naming, macht's einfach gleich englisch, ihr werdet vielleicht irgendwann doch mal noch einen externen Programmierer oder sonst was haben. Pascal Case oder Anderscore, vielleicht nicht unbedingt alles gemischt, oder vielleicht mit nem stringenten Schema, so kann man ja auseinandernehmen. Never use all caps, kann man machen, ist echt ekelhaft lesbar, gerne dann auch in so ganz alten Datenbanken, wo dann alle Tabellennamen maximal 8 Zeichen haben. Abkürzung, nur wenn allgemein verständlich. Also erinnert euch vielleicht vorher an dieses komische roh, EK, TTF, Null, irgendwas. Ihr braucht Jahre, um eure anderen Mitarbeiter oder Leute einzuarbeiten, wo die ihre Tabellen suchen müssen. Wenn er sie einfach benennt, dann ist das klar, dann schreibt sich das runter wie ein Satz immer. Die Primary Key Spalte vielleicht nicht unbedingt nur ID nennen, sonst hat man nämlich plötzlich überall irgendwie Select ID und dann ID und wieder ID und ich muss irgendwelche Konstrukte machen mit S irgendwas oder sonst was und ich weiß nicht mehr welcher ID das war und plötzlich kommt ne Fehlermeldung und ich krieg's überhaupt nicht mehr auseinander klamüsert, macht ne vernünftige Spalte da daraus. Konsistenzreferenzierung, habe ich mal 1.11 hinten dran geschrieben, auch da erspart ihr euch und allen euren Mitmenschen sehr viel Ärger, wenn ihr das einfach durchzieht und dann, wenn die Kunden ID halt Kunden ID heißt, nicht plötzlich Customer ID zu schreiben, kommt man später noch schön dazu was dann wo das dazu hinführt. Eine Wahrheit gibt's, legt es vorher fest. Normalisierung, kann man sich drüber streiten, das ist das Original aus einer Datenbank. Kunden ID, Tell 1, Tell 2, Tell 3, Tell 4, Tell 5, kleines Schmankerl am Rande, die Spalte Tell 4 ist immer leer. Im Frontend fehlt das Formular. Wie man es vielleicht eigentlich machen würde, also ich kenne Leute, die haben mehr als nur 4 Telefonnummern, wenn man jetzt hier aufgeschmissen, könnte man eigentlich so machen, einfach hinzugehen, okay, man normalisiert das, eigene Tabelle, hier ganz wunderbar, Nummer ID, Kunden ID und dann die Telefonnummer hinten dran, kann ich dann so viele Nummern speichern wie ich will, macht's euch auch deutlich einfacher bei der Duplettensuche und Ähnliches oder wenn man da irgendwas anderes dran flanscht. Zur Ehrenrettung des Herstellers von der Software, wo ich das gefunden hab, in der neuen Version haben sie das Problem erkannt, angegangen, die Tabelle sieht so aus. Phone 4 bleibt auch in der neuen Version leer, keine Angst. Bitte, ein Nähstring, Wachar 20 oder so was, also so bei ausländischen Wilden, nur man könnte schwierig werden. Bei den Datentypen auch sehr schön, ich bin ein ganz großer Freund von DateTime, ich mag so diese Timestamp-Geschichten nicht so. Komm mal später dazu, in dieser schönen Tabelle gab's dann diese so Spalte erfasst, Datentyp DateTime, ich so, yay, sie haben DateTime verwendet, aber der Value sieht ein bisschen komisch aus. Ich will doch eigentlich die Uhrzeit mitspeichern, wenn ich irgendwie erfasst am, nur das Datum reicht eigentlich nicht, man will die Zeit mit drin haben und guck ich so, Spalte nebendran. Gut, die heißt erfasst Tim, also, eh war keins dran, schau ich sie mir genauer an, Wachar 10. Gut, kann man machen, ist dann aber halt ne, no comment. Auch so einer von diesen schönen Funden in irgendeiner der gelockten Abfragen, fiel mir dieses etwas wilde Konstrukt auf. Ich nehm's mal ganz kurz auseinander, da wird also irgendein Wert, komm mal gleich zu, wird nach Float, also seine Floatzahl gekastet, sichergestellt, dass es ne Zahl ist, zwei Werte voneinander abgezogen, dann mit Abs dafür sichergestellt, dass ne positive Zahl rauskommt und geschaut, ob denn das größer als ein 10-Million-Zel ist. Hm, was sind das für Werte? Oh, DateTimes, die rechnen also das geändertem Datum in ein Float um, um es voneinander abzuziehen, um dann zu schauen, ob der Unterschied größer als ein 10-Million-Zel ist, wie wär's mit? Ist es unterschiedlich? Keine Ahnung, könnte Rechenzeit sparen, Gerüchte zu? Auch äußerst beliebt bei den Datentypen ist die Sache mit dem Null, also N-U-L-L, Null und Leer. Null ist ein bisschen schwierig, da können wir auch gerne irgendwie noch den kompletten Abend bei diversen Chunks drüber philosophieren, ob das jetzt sinnvoll, nicht sinnvoll oder wie auch immer ist. Ein bisschen, also Null sagt man, da fehlen Daten, also da gibt es jetzt keine Information zu, ob das jetzt irgendwie plus, minus oder überhaupt irgendwas ist. Man könnte auch sagen, da fehlt noch ein Eintrag vom User. Ich hab hier mal wild was rausgegriffen, als Beispiel auch wieder dieser Artikel-Tabelle. Bestand 10, Beschreibung vom Artikel irgendwie bla laba, völlig egal. Wenn man jetzt wenigstens durchziehen würde mit diesem Null oder Leer, aber nein, es finden sich alle Werte drin. Also wie man Null bei einem Bestand verwenden kann, fällt mir ein bisschen schwierig, weil da ist entweder Null oder er ist von mir auch sogar negativ, kann man diskutieren, aber Null sich ja nicht. Und auch in so einer Beschreibungsspalte mache ich halt ein Leerzeichen rein oder halt empty Spaces, da brauche ich kein Null. Das Problem ist dann nämlich auch, dass man dann hinterher diese wunderschönen Abfragen ständig braucht, if Null bestand, es bestand und so weiter. Geht dann Kopierpasten, aber wird halt lang und hässlich. Kurz zusammengefasst, gehen wir auch gar nicht näher drauf ein. Passenden Datentyp-Wählen ist eigentlich immer ganz gut, also Timestamps vielleicht nicht unbedingt als Tring abspeichern, wissen schon. Performance-Indizierbarkeit, Speicherbedarf ist da eigentlich immer ganz wichtig. Null sagt man so vielleicht eher vermeiden, seit man weiß, was man tut, kann aber auch durchaus mal sinnvoll sein. Bitte, bitte, bitte unbedingt in Datenbanken, lasst die Finger von Unix Timestamps in Datenbanken. Ich sag jetzt nur so schöne Dinge wie Zeitzonen, wird schwierig, macht keinen Spaß. Daytime lässt sich super verarbeiten, ist gut lesbar, die Datenbanken können das alle, die können das auch alle flott. Man kann so schöne Sachen machen, wie gibt mir alle Daten aus dem letzten Jahr und schreibt dann einfach nur hier hinten dran und wunderbar. Man kann danach gruppieren, nach Tag und so weiter. Wer das mal versucht hat mit Unix Timestamps zu bauen, der weiß, dass es überhaupt gar keine Freude. Und irgendwie 2038 oder was ist jetzt auch nicht mehr so lange her. Ansonsten bei den Datentypen gilt wie immer RTFM, die stehen nämlich tatsächlich alle manuell, nur so als Erinnerung. Abfragen, auch immer wieder eine der schönen Dinge. Man hat so den Profiler offen und dann wundert man sich, warum das Aufrufen eines Kunden 380 Abfragen an die Datenbank braucht. Schaut mal mal so, naja, 2, 3, 4, das sind alles einzelne Abfragen. Einmal komplett, 42 Abfragen hintereinander. Da hat jemand eine Schleife gebaut. Schleifenden Datenbanken, Abfragen, ganz schlechte Idee, also so auch nicht mal in Ausnahmen, weil das eskaliert sehr schnell. Riesenflaschenhals. Und vor allem ist eine Datenbank dazu da genau sowas zu verarbeiten. Ich habe da mal ein paar Vorschläge aufgeschrieben. Inner Join, Left Outer Join mit Is Not Null oder auch dann Wear In und hinterher irgendwie eine Ladung von IDs reinwerfen. Also irgendwie ein Array fletten und so weiter. Kann eigentlich jede Datenbank. Geht bei allen. Ein Weg findet sich sicher. Sobald ihr in einer Vor- oder Weilschleife eine Datenbankabfrage startet, setzt euch noch mal ein Meter zurück. Es geht meistens schief. Ich habe mal gesagt, so lieber eine große Abfrage statt vieler kleiner. Bei kleinen Abfragen habt ihr ganz gerne oder bei vielen Abfragen habt ihr gerne ein Overhead drin. Also Aufbauverbindungen, Authentifizierung zur Datenbank etc. Spart man sich da dann. Was die Joins betrifft, ich habe da ein schönes Wenddiagramm gefunden. Hat ein guter Herr Moffat irgendwo veröffentlicht. Link steht drunter. Die komplette Slides liegen mittlerweile online. Link blendet später ein. Veröffentlicht das auch. Da kann man sich das nochmal ganz gut anschauen. Und diese Grafik fand ich gerade am Anfang immer sehr angenehm. Weil man hat nicht unbedingt immer im Kopf, wie genau man jetzt gerade sein Joint erbauen soll. Datenbankabfragen nutzen habe ich extra nochmal aufgeschrieben. Zum Beispiel so Sachen wie Summe oder Average, also Durchschnittbilden. In der einen Software habe ich entdeckt, dass die 50.000 Rechnungen, also alle Rechnungen, die mit der Software geschrieben worden sind, zieht, um sich dann eine Summe daraus zu bilden im Frontend. Zwei Abfragen über zwei Spalten aus der gleichen Tabelle mit den gleichen Einschränkungen. Also geht auch in einer, weiß ich nicht, warum die das nicht so machen. Oder sie suchen irgendwie, ziehen sich eine Liste von wirklich allen Kundennamen aus der Größenordnung 30.000, 40.000 Kunden um dann im Frontend über ein schlecht geschriebenes JavaScript zu suchen. Muss auch nicht sein, da empfehle ich starken Volltextindex. Bitte auch, wenn ihr irgendwo so die Like-Prozent seht, das ist auch immer so ein Hinweis dafür. Da hat sich jemand nicht ganz genau Gedanken darüber gemacht. Kann man machen? Like ist so, finde mir irgendein Datensatz, wo womöglich dieser String drinsteht. Mit Prozent als Wildcard muss ja dann wirklich jeder einzelne Zeile anfassen. Da gibt es kaum Optimierungsmöglichkeiten. Wenn ihr irgendwelche Suchen braucht, setzt euch hin. Es dauert nicht viel länger, ein Volltextindex zu bauen, geht aber sehr viel schneller. Dann stößt man auf interessante Sachen. Gibt es irgendjemand, der ZFMT-Only schon mal gesehen hat? Microsoft-Datenbank. Ich auch nicht. Ist er mir ja vorbeigeflattert, so jede dritte, vierte Anfrage fing damit an. Dann guckt man mal nach, was sagt denn da die Microsoft dazu? Returns only metadata to the client. Can be used to test the format of the response without actually running the query. Heißt auf gut Deutsch. Man kann die Abfrage hinschmeißen. Es kommt zurück, was für Tabellen oder Spaltenamen das sind. In der Entwicklung verstehe ich es, in der Production definitiv nicht. Vor allem, wenn man dann noch den nächsten Satz bei der Microsoft-Doku liest. Steht 1 zu 1, denn ich habe mich sehr gefreut. Schön sind dann auch so Dinge, wo man weiß, nein, er hat das manuell nicht gelesen. Cast count Stern es int. Was sagt Microsoft dazu? Ich habe extra nachgeschaut. Count always returns an int data type value. Gibt es jemand, der weiß, ob es eine Datenbank gibt, die auf count kein Integer zurückgibt? Okay, danke. Ich habe es vermutet. Kommen wir mal einen kleinen Ausflug zum Thema Security. Kannst du jemand direkt lesen? Nein, nein, nein. Also irgendjemand hätte 4 mal 0 raten können. Schar 1 ungesalzen, klarer Fall. Ich glaube, da habe ich was im Titel vergessen. Okay, Security, diesmal jetzt aber mal so wirklich, so richtig. Also so mit Profis und so, nämlich bei Obscurity. Ich habe das nachgebaut aus Gründen, um es ein bisschen erklären zu können. Aber nehmen wir mal an, ich mache einen neuen Eintrag in einer Datenbank. Also schreibe irgendwas im Frontend rein, klick auf speichern und schau hinterher nach. Neuer Eintrag, Random ID in dieser Tabelle, in der Random Table. Dann steht da drin, Ersteller ID, ID 23 und Bearbeiter ID 42. Moment, das habe ich jetzt doch gerade eben eingetippt. Wieso hat das jemand anders bearbeitet? Dann guckt man in diese User-Table. Dann gibt es da zwei Einträge, der User mit der ID 42. Aha, Austritt, also da hat das Unternehmen verlassen, 2016. Wieso kommt diese 42 da rein? Dann gräbt man noch ein bisschen weiter und findet dann eine Tabelle mit dem wunderschönen Namen Secure User Table, in dem dann eigene IDs für die Sicherheitsbenutzer vergeben werden. Also der Benutzer von Mia, mein Experimental Benutzer Fuba, ist dann auch noch so dieses schöne Detail, dass die in dieser Secure User Table, die Spalten-Spalten-Name, ist das Kurzzeichen aus der Spalten-User-Table und der Spalten, also irgendwie Servier, stellt sich raus, dass es tatsächlich geschafft haben, in derselben Tabelle unterschiedliche User-IDs aus unterschiedlichen Tabellen zu verwenden und das nicht zu kennzeichnen. Wir hatten es vorher mit der Referenzierung. Ihr könnt Gift drauf nehmen, das geht schief. Irgendwann platzt da mal was. Und dann weiß kein Mensch mehr, wer was wo eingetragen hat, weil es ist alles ein Heilosensböchernander. Schön ist dann auch, dass die in der Secure User Table, da stehen natürlich die Kennwörter, wäre ja schön, wenn es da eine Spalte-Kennwörter gibt, die gibt es auch, da ist aber Null. Benutzer Info 2, da stehen die Passwörter. Ich frage mich dann zwar, ob meine Benutzer-Infos dann in Kennwörter gespeichert werden, wie man das theoretisch vielleicht machen würde, um uns dann anzuschauen, was die gebaut haben. Als Beispiel hier so eine Country-Stable, kennt man alle, gibt es mittlerweile auch schon schöne Dumps zum Download. Da hat man dann alle ISO-Codes drin und so weiter. Schön, Primary-Key, Country-ID, Country-Code, kurz Zeichen, also DE für Deutschland, und so weiter, was man da halt alles so drin speichern will. Wenn ich jetzt die Daten für Deutschland rausziehen will, dann mache ich einfach hier, keine Ahnung, Select-Stern, Country-Isware, Country-Code, gleich DE, oder auch Country-ID gleich 1, whatever. Geht schnell, sauber, straight forward, total einfaches SQL. Ja, zu dem Teil, in der Mitte kommen wir gleich. Also, bei Wear 1, gleich 1, okay, ich kenne das, das war so, als ich das erste Mal mit Datenbank und mir ein Query-Bilder irgendwie zusammengehackt hat. Da habe ich das auch mal ausprobiert, schnell festgestellt, keine gute Idee. Sie haben da ja ein Query-Bilder nicht im Griff, aber was dann der Rest war, ja. Also jedes einzelne Feld nochmal in Aper wandeln und hinterher mit Like und mit Wildcards zu arbeiten, um dann die Daten für Deutschland zu ziehen. Also das tut mir leid, da ist mir dann eigentlich nur noch eingefallen. Moment, kam das jetzt nicht? Oh, shit, ich habe meine Präsentation nicht im Griff, ich habe da was Schönes vorbereitet. Ja, vielen Dank. Also das war es soweit. Fragen und Antworten, gerne. Genau, habt ihr noch Fragen? Da sehe ich es auch schon vorne einem Publikum, ich komme sofort rüber, damit die Anfrage auch auf dem Stream und auf der Aufzeichnung drauf ist. Oh mein Gott, das will ich nicht. Ja, wenn ein Count immer einen Int zurückliefert, was ist da, wenn man eine Ergebnismenge größer ist, als wenn das Int größer ist, als ein Ergebnismenge größer als ein Int? Es wird dann irgendwann ein Big Int. Also das passt schon, nur dieses Casten nochmal ist so ein bisschen überflößt. Also hoffentlich rechnet das der Optimizer raus, bevor er die Anfrage raus schiebt. Müsste man mal tun, ja. Also persönliche Meinung, warum passiert das? Es rennen ja nun nicht nur Vollidioten draußen rum. Ja, warum passiert das? Ja, warum passiert das? Ich kann vielleicht mal von mir aus gehen. Ich habe irgendwie Ende der 90er angefangen, und ich werde mal sagen, so die ersten 3, 4 Jahre habe ich genau die Nummern auch gemacht. Das ist auch nicht schlimm, wenn man sowas macht, aber man muss sich irgendwann mal bewusst werden. Ich werfe das eigentlich auch keinem vor, nur dass es Software, die verlangen so 5-stellige Lizenzgebühren pro Monat, den werfe ich das vor. Die Frage war, warum wird es gereffektet? Also, oder nicht gereffektet? Also warum aus Tell 1, Phone 1 wird? Ja, sie steigen jetzt von Delphi Fettkleint auf VB Fettkleint um. Anscheinend ändert sich da leider nicht mehr. Ich weiß es wirklich nicht, warum es würde mich auch interessieren. Und ich finde es eigentlich auch schön, wenn sich das zukünftig ein bisschen ändert. Und vielleicht firmen auch mal auf die Idee kommen so, hey, Datenbanken, wir haben da zwar einer, der sagt, er kennt es sich aus, aber vielleicht fragt man nochmal jemand, der sich wirklich auskennt, um das besser zu machen. Weiß ich ausgesichert, der Queller haben sie nicht. Es gibt keinen outsourced, outsourced, das tun wir im Ausland. Okay. Also wir hatten vorhin gehört, dass man seine IDs immer gleich benennen soll, mit den Referenzen. Wie soll man das jetzt machen, wenn man eine UserID-Referenzieren will, aber sagen, okay, der hat es bearbeitet, er hat es erstellt, wir hatten ja vorhin gesehen, ErstellerID und BearbeiterID. Würde man es dann ein UserID-Unterstrich-Edit machen, dann kannst du dir selber finden, aber genauso würd ich es machen. Also ich hatte es vorhin mal kurz drin, irgendwie changed by userID, oder edited by userID, inserted by userID. Also einfach genau die zwei Sachen, was ist es eigentlich, was ist in dieser Tabelle plus, wenn es eine Referenzierung, also ein Foreign Key ist, einfach da hinten dran, dann liest man es in einem Satz runter und du siehst sofort, der referenziert hier auf die UserID-Table. Ich glaube, das Problem ist halt auch, dass niemand wirklich Bock hat, das Systeme zu schreiben. Hundert Punkte. Ja, haben wir sonst noch eine Frage? Ansonsten vielen Dank an SMTV. Einen großen Applaus. Dankeschön.