Veelgemaakte fouten in databases.
Uit Yapf
Varchar voor datums en tijden
Deze fout wordt veel gemaakt omdat mensen niet weten hoe ze het standaardformaat van datums en tijden in databases kunnen aanpassen. In plaats van dit uit te zoeken beslissen ze om dan maar zelf en formaat te maken en dat op te slaan in een VARCHAR veld.
Dit is fout omdat je een string opslaat, geen datum. Als je uit de "datum" iets op wilt halen zoals het nummer van de maand, dan heb je een verassend groot probleem. Je kunt wel met substring() een deel van de string ophalen, maar welk deel? Vandaag is het bijvoorbeeld 2-1-2009, en over twee weken is het 16-1-2009. Punt is dat er nu twee tekens voor de dag staan, waardoor de maand een positie opschuift. Dan is het over tien maanden 2-11-2009, en twee weken daarna is het 16-11-2009. Dat zijn vier vormen waarin de datum voor kan komen en dus zou je ook vier versies van substring moeten maken. En da moet je nog een manier verzinnen om te bepalen welke van de vier je moet toepassen...
Daarna krijg je nog het probleem dat substring een string is en geen getal en dus 1 altijd komt voor 2, ook als er 16 staat, en tot slot heb je het gebrek aan indexes waardoor de toch al trage handeling van substring nog eens extra vertraagd wordt.
Kortom, niet doen. Als je het formaat van ee datum wilt aanpassen, zoek dan even in de handleiding va je database naar functies als TO_CHAR() en DATE_FORMAT()
Fix
Deze fout is vrij eenvoudig te repareren, maar het is nog al een ingrijpende handeling dus maak een backup voordat je begint en probeer het eerst uit op een testdatabase!
Dit is geen geintje, maak een backup!
- Maak een nieuwe kolom, ditmaal wel van het DATETIME type.
- Kopieer de data van de VARCHAR kolom naar de nieuwe DATETIME kolom. Hierbij is het soms nodig om het formaat van de datum aan te passen, hiervoor kun je [SUBSTRING] gebruiken, of een [regular expression], of de excellente functies to_timestamp() in PostgreSQL, of [str_to_date()] in MySQL. De query zou iets worden als
UPDATEtabel
SETnieuwe_kolom = oude_kolom;
- Verwijder de oude VARCHAR kolom.
- Hernoem de nieuwe DATETIME kolom naar de naam van de oude kolom.
Als het formaat van de datum hierdoor verandert dan moet je bij het uitlezen een functie als TO_CHAR of DATE_FORMAT gebruiken. Noot dat je in databases altijd het formaat bepaalt bij het uitlezen, en nooit in het datamodel.