Vermijd stringly-typed data door VALUE
te vervangen met NUMBER_VALUE
, DATE_VALUE
, STRING_VALUE
. Die drie typen zijn meestal goed genoeg. Je kunt XMLTYPE en andere fraaie kolommen later toevoegen als ze nodig zijn. En voor Oracle, gebruik VARCHAR2 in plaats van CHAR om ruimte te besparen.
Probeer altijd waarden op te slaan als het juiste type. Native datatypes zijn sneller, kleiner, gebruiksvriendelijker en veiliger.
Oracle heeft een generiek gegevenstypesysteem (ANYTYPE, ANYDATA en ANYDATASET), maar deze typen zijn moeilijk te gebruiken en moeten in de meeste gevallen worden vermeden.
Architecten denken vaak dat het gebruik van één enkel veld voor alle gegevens dingen gemakkelijker maakt. Het maakt het gemakkelijker om mooie foto's van het datamodel te maken, maar het maakt al het andere moeilijker. Overweeg deze problemen:
- Je kunt niets interessants met gegevens doen zonder het type te kennen. Zelfs om gegevens weer te geven is het handig om het type te kennen om de tekst te rechtvaardigen. In 99,9% van alle gevallen zal het voor de gebruiker duidelijk zijn welke van de 3 kolommen relevant is.
-
Het ontwikkelen van typeveilige query's tegen stringly-getypte gegevens is pijnlijk. Stel dat u bijvoorbeeld 'geboortedatum' wilt vinden voor mensen die in dit millennium zijn geboren:
select * from ReportFieldValue join ReportField on ReportFieldValue.ReportFieldid = ReportField.id where ReportField.name = 'Date of Birth' and to_date(value, 'YYYY-MM-DD') > date '2000-01-01'
Zie jij de bug? De bovenstaande vraag is gevaarlijk, zelfs als je de datum in het juiste formaat hebt opgeslagen, en maar heel weinig ontwikkelaars weten hoe ze het op de juiste manier kunnen repareren. Oracle heeft optimalisaties die het moeilijk maken om een specifieke volgorde van bewerkingen af te dwingen. Je hebt een zoekopdracht als deze nodig om veilig te zijn:
select * from ( select ReportFieldValue.*, ReportField.* --ROWNUM ensures type safe by preventing view merging and predicate pushing. ,rownum from ReportFieldValue join ReportField on ReportFieldValue.ReportFieldid = ReportField.id where ReportField.name = 'Date of Birth' ) where to_date(value, 'YYYY-MM-DD') > date '2000-01-01';
Je wilt niet elke ontwikkelaar vertellen dat ze hun zoekopdrachten op die manier moeten schrijven.