Datamodules en controls
Luteijn Automatisering
(KvK: 60276037, BtwNr: NL062594862B01)
Artikelen over automatisering
Uitgangspunten technisch ontwerp, Toekomstige softwareontwikkeling, Databaseontwerp, SQL-Server en Hoofdpagina
Een recente ontwikkeling is de opkomst van het fenomeen datamodules samenwerkend met clientdatasets, speciale controls en stored procedures. Het is een enorm krachtige toevoeging aan derde generatietalen. Maar het moet wel goed gebruikt worden. Bij de eerste pogingen daartoe is er nogal wat misgegaan. Met als gevolg problemen met performance, bewerkelijkheid, complexiteit en onderhoud. Goed doordenken over de verschillende gereedschappen kan het resultaat aanmerkelijk verbeteren. Soberheid en spaarzaamheid is daarbij de leiddraad. Een datamodule is niet de panacee voor alle problemen. Zo nu en dan is een primitieve ouderwetse oplossing gewoon beter.
Een datamodule is een object waarop allerlei controls, die de verbinding met de database verzorgen, samengebracht worden. Grafisch worden alle objecten voor het behandelen van stored procedures, queries, clientdatasets, datasetproviders, etc. op één form gezet. De datamodule zorgt zelf voor het creëren en opruimen van deze objecten. Dat is best handig. Het zijn er al snel tamelijk veel. Aanmaken en vrijgeven van objecten is bewerkelijk. Vooral als je er zeker van wilt zijn, dat bij elke exceptie de boel netjes opgeruimd wordt. In een datamodule kunnen controls en hun achterliggende SQL-statements rechtstreeks getest worden op de actieve database en je kunt stored procedures aankoppelen, waarbij benodigde parameters automatisch verschijnen in de properties.
De voordelen van datamodules zijn evident. De nadelen blijken pas als het uit de hand is gelopen. Vaak worden teveel controls op een datamodule gezet, waardoor het overzicht verdwijnt. SQL-statements opgeslagen in het grafische object zijn onzichtbaar voor de zoekmachine, zodat een toegevoegd veld moeizaam opgezocht moet worden in de string properties van de verschillende queries. Vooral bij onderhoudsgevoelige primaire functies kan dit uiterst bewerkelijk zijn. Ook is het goed om na te denken over rationeel gebruik van stored procedures. Een stored procedures wijzigen is namelijk een 'database wijziging'. Die zijn bewerkelijk en duur. Ook moeten de parameters van steeds wijzigende stored procedures telkens opnieuw gechecked worden.
In principe kun je data bij een SQL-database op drie verschillende manieren ophalen, t.w. via stored procedure, normale query en geparametriseerde query. De stored procedures is het snelst, maar ook het bewerkelijkst. De gewone query is relatief langzaam. Dat wordt veroorzaakt door de wijze waarop een SQL-database zijn queries uitvoert. Eerst start hij een analysemodule. Deze bekijkt hoe de statements het snelst uitgevoerd kunnen worden. Bij kleine queries kost deze analyse meer tijd, dan het feitelijk ophalen van de data. Bij een stored procedure resp. een geparametriseerde query gebeurt dit slechts eenmaal. Stored procedures doen dit eenmalig in design time, terwijl dat bij geparametriseerde query eenmalig gebeurt tijdens runtime. Stel je hebt een SQL-statement, dat één record ophaalt. Stel dat het analyseren van het statement 10 milliseconde duurt en het ophalen van een record ook. Dan krijgt je de volgende getallen:
Stored procedure 10 milliseconde ophalen data
Geparametriseerde query 10 milliseconde ophalen data plus eenmalig 10 milliseconde.
Normale query altijd 10 milliseconde ophalen en 10 milliseconde analyseren.
Dit maakt natuurlijk niets uit als je maar een record wilt hebben. Maar als je er 10.000 hebt, dan krijg je de getallen:
Stored procedure 10.000 * 10 milliseconde ophalen data.
Geparametriseerde query eenmalig 10 milliseconde analyse + 10.000 * 10 milliseconde ophalen data.
Gewone query 10.000 * 20 milliseconde (10 + 10) voor ophalen en analyse.
Het is natuurlijk onzinnig om 10.000 records op te halen via 10.000 SQL-statement. Je kunt ze natuurlijk ook in een keer halen. Stel dat het ophalen van de data voor 10.000 records in een keer 2 seconde kost. Dan krijg je bij de drie methoden de getallen:
Stored procedure 2 seconde ophalen data.
Geparametriseerde query 10 milliseconde analyse + 2 seconde ophalen data.
Normale query 10 milliseconde analyse + 2 seconde ophalen data.
Het is duidelijk, dat de performance van de stored procedure altijd superieur is. Echter in het laatste geval is de winst slechts 10 milliseconde, terwijl het maken en onderhouden van de stored procedure gemakkelijk het tienvoudige kan kosten van beide andere varianten. Bijgevolg is de stored procedure alleen aantrekkelijk als er een substantiële performance winst mee te behalen is. Dat is soms het geval bij inserten of updaten van losse records. Echter bij het lezen van records is de winst zelden de moeite waard. Zelfs bij inserten en updaten is het de vraag of een stored procedure de extra inspanning waard is. Het wordt pas interessant als er veel records zijn in een tabel en het veelvuldig moet gebeuren. Ook zal je bij een stored procedure geneigd zijn alle velden van de tabel mee te geven. Als je slechts een veld hoeft te wijzigen, geeft dat veel onnodig dataverkeer over het lijntje.
Bij onderhoudgevoelige batchprocessen is de stored procedure de slechts mogelijke oplossing. Menig primair batchproces gaat tijdens de ontwikkelfase een paar dozijn keer over de kop. Veel mutaties hebben een databasewijziging ten gevolge. De broncode van het proces en de stored procedure staan op twee plekken. De programmeur is geneigd de mutaties alleen in de broncode te doen, omdat het wijzigen van de stored procedure veel werk is. Het gevolg is inefficiënte en complexe code, die onderhoudskosten omhoog jaagt. In een batchproces ligt het voor de hand bij het ophalen van de data van een gewone query gebruik te maken en bij het wegschrijven van een geparametriseerde query. Mijns inziens is het verstandig het SQL-statement toe te kennen aan de control in de broncode en niet in de datamodule. Dat is handig voor de zoekmachine, het verspreiden van onderdelen van een proces over twee plaatsen bemoeilijkt onderhoud en het plaatsen van het SQL-statement in de datamodule biedt te weinig voordelen. Testen van statements gaat beter in de query-analyser van de database.