Vyhněte se řetězcovým datům nahrazením VALUE
s NUMBER_VALUE
, DATE_VALUE
, STRING_VALUE
. Tyto tři typy jsou většinou dost dobré. XMLTYPE a další efektní sloupce můžete přidat později, pokud jsou potřeba. A pro Oracle použijte VARCHAR2 místo CHAR, abyste ušetřili místo.
Vždy se snažte uložit hodnoty jako správný typ. Nativní datové typy jsou rychlejší, menší, snadněji použitelné a bezpečnější.
Oracle má obecný systém datových typů (ANYTYPE, ANYDATA a ANYDATASET), ale použití těchto typů je obtížné a je třeba se jim ve většině případů vyhnout.
Architekti si často myslí, že použití jednoho pole pro všechna data usnadňuje práci. Usnadňuje generování pěkných obrázků datového modelu, ale ztěžuje vše ostatní. Zvažte tyto problémy:
- Bez znalosti typu nemůžete s daty dělat nic zajímavého. I pro zobrazení dat je užitečné znát typ pro zarovnání textu. V 99,9 % případů bude uživateli zřejmé, který ze 3 sloupců je relevantní.
-
Vyvíjení typově bezpečných dotazů na data s řetězci je bolestivé. Řekněme například, že chcete najít „Datum narození“ pro lidi narozené v tomto tisíciletí:
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'
Dokážete najít chybu? Výše uvedený dotaz je nebezpečný, i když jste datum uložili ve správném formátu, a jen velmi málo vývojářů ví, jak jej správně opravit. Oracle má optimalizace, které znesnadňují vynucení konkrétního pořadí operací. Pro jistotu budete potřebovat dotaz jako je tento:
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';
Nechcete říkat každému vývojáři, aby psal své dotazy tímto způsobem.