Tôi đã kế thừa một ứng dụng liên kết nhiều loại hoạt động khác nhau với một trang web. Có khoảng 100 loại hoạt động khác nhau và mỗi loại có 3-10 trường khác nhau. Tuy nhiên, tất cả các hoạt động đều có ít nhất một trường ngày (có thể là bất kỳ sự kết hợp nào giữa ngày, ngày bắt đầu, ngày kết thúc, ngày bắt đầu dự kiến, v.v.) và một trường người có trách nhiệm. Tất cả các trường khác rất khác nhau và trường ngày bắt đầu sẽ không nhất thiết được gọi là "Ngày bắt đầu".
Tạo một bảng phụ cho mỗi loại hoạt động sẽ dẫn đến một lược đồ với 100 bảng phụ khác nhau, điều này sẽ quá khó để xử lý. Giải pháp hiện tại cho vấn đề này là lưu trữ các giá trị hoạt động dưới dạng cặp khóa-giá trị. Đây là một lược đồ được đơn giản hóa rất nhiều của hệ thống hiện tại để có được điểm.
Mỗi Activity có nhiều ActivityFields; mỗi Trang web có nhiều Hoạt động và bảng SiteActivityData lưu trữ KVP cho mỗi SiteActivity.
Điều này làm cho ứng dụng (dựa trên web) rất dễ mã hóa bởi vì tất cả những gì bạn thực sự cần làm là lặp lại các bản ghi trong SiteActivityData cho một hoạt động nhất định và thêm nhãn và điều khiển đầu vào cho mỗi hàng vào một biểu mẫu. Nhưng có rất nhiều vấn đề:
- Liêm chính là xấu; có thể đặt một trường trong SiteActivityData không thuộc loại hoạt động và DataValue là trường varchar nên số và ngày cần phải được liên tục truyền.
- Báo cáo và truy vấn đặc biệt của dữ liệu này là khó khăn, dễ bị lỗi và chậm. Ví dụ: để có được một danh sách tất cả các hoạt động của một loại nhất định có Ngày kết thúc trong một phạm vi được chỉ định, cần có các trục xoay và chuyển các biến thành các ngày. Các nhà văn báo cáo ghét lược đồ này, và tôi không đổ lỗi cho họ.
Vì vậy, những gì tôi đang tìm kiếm là một cách để lưu trữ một số lượng lớn các hoạt động gần như không có trường chung theo cách làm cho báo cáo dễ dàng hơn. Những gì tôi đã nghĩ ra cho đến nay là sử dụng XML để lưu trữ dữ liệu hoạt động theo định dạng giả:
Bảng Activity sẽ chứa XSD cho từng hoạt động, loại bỏ sự cần thiết của bảng ActivityField. SiteActivity sẽ chứa XML giá trị khóa để mỗi hoạt động cho một trang web sẽ nằm trong một hàng.
Một hoạt động sẽ trông giống như thế này (nhưng tôi chưa hoàn thành nó):
<SomeActivityType>
<SomeDateField type="StartDate">2000-01-01</SomeDateField>
<AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
<EmployeeId type="ResponsiblePerson">1234</EmployeeId>
<SomeTextField>blah blah</SomeTextField>
...
Ưu điểm:
- XSD sẽ xác thực XML, bắt các lỗi như đặt một chuỗi vào trường số ở cấp cơ sở dữ liệu, một điều không thể với lược đồ cũ lưu trữ mọi thứ trong varchar.
- Các bản ghi của KVP được sử dụng để xây dựng các biểu mẫu web có thể dễ dàng được sao chép bằng cách sử dụng
select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
- Một truy vấn con xpath của XML có thể được sử dụng để tạo ra một tập kết quả có các cột cho ngày bắt đầu, ngày kết thúc, v.v. mà không cần sử dụng một trục, đại loại như
select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...
Điều này có vẻ như là một ý tưởng tốt? Tôi không thể nghĩ ra những cách khác để lưu trữ một số lượng lớn các bộ tài sản khác nhau như vậy. Một suy nghĩ khác mà tôi đã có là giữ lược đồ hiện có và dịch nó thành một thứ dễ truy cập hơn trong kho dữ liệu, nhưng tôi chưa bao giờ thiết kế một lược đồ sao trước đây và sẽ không biết bắt đầu từ đâu.
Câu hỏi bổ sung: Nếu tôi xác định thẻ có kiểu dữ liệu ngày trong XSD bằng cách sử dụng xs:date
, SQL Server sẽ lập chỉ mục đó dưới dạng giá trị ngày? Tôi lo ngại nếu tôi truy vấn theo ngày, nó sẽ cần truyền chuỗi ngày thành giá trị ngày và thổi bay mọi cơ hội sử dụng chỉ mục.