Tránh dữ liệu được nhập theo chuỗi bằng cách thay thế VALUE
với NUMBER_VALUE
, DATE_VALUE
, STRING_VALUE
. Ba loại đó hầu hết đều tốt. Bạn có thể thêm XMLTYPE và các cột ưa thích khác sau này nếu chúng cần. Và đối với Oracle, hãy sử dụng VARCHAR2 thay vì CHAR để tiết kiệm dung lượng.
Luôn cố gắng lưu trữ các giá trị dưới dạng đúng loại. Các loại dữ liệu gốc nhanh hơn, nhỏ hơn, dễ sử dụng hơn và an toàn hơn.
Oracle có hệ thống kiểu dữ liệu chung (ANYTYPE, ANYDATA và ANYDATASET), nhưng những kiểu đó rất khó sử dụng và cần tránh trong hầu hết các trường hợp.
Các kiến trúc sư thường nghĩ rằng việc sử dụng một trường duy nhất cho tất cả dữ liệu sẽ giúp mọi thứ dễ dàng hơn. Nó làm cho việc tạo ra các bức ảnh đẹp về mô hình dữ liệu trở nên dễ dàng hơn nhưng lại làm cho mọi thứ trở nên khó khăn hơn. Hãy xem xét các vấn đề sau:
- Bạn không thể làm bất cứ điều gì thú vị với dữ liệu mà không biết loại. Ngay cả khi hiển thị dữ liệu, việc biết loại để căn chỉnh văn bản cũng rất hữu ích. Trong 99,9% trường hợp sử dụng, người dùng sẽ thấy rõ cột nào trong 3 cột có liên quan.
-
Việc phát triển các truy vấn an toàn kiểu chống lại dữ liệu được gõ theo chuỗi là một việc khó khăn. Ví dụ:giả sử bạn muốn tìm "Ngày sinh" cho những người sinh trong thiên niên kỷ này:
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'
Bạn có thể phát hiện ra lỗi không? Truy vấn trên rất nguy hiểm, ngay cả khi bạn đã lưu trữ ngày ở định dạng chính xác và rất ít nhà phát triển biết cách sửa nó đúng cách. Oracle có những tối ưu hóa gây khó khăn cho việc buộc một thứ tự hoạt động cụ thể. Bạn sẽ cần một truy vấn như thế này để an toàn:
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';
Bạn không muốn phải yêu cầu mọi nhà phát triển viết các truy vấn của họ theo cách đó.