ฉันรับแอปพลิเคชันที่เชื่อมโยงกิจกรรมหลายประเภทกับไซต์ มีประเภทกิจกรรมที่แตกต่างกันประมาณ 100 ประเภทและแต่ละประเภทมีชุดของฟิลด์ 3-10 ที่แตกต่างกัน อย่างไรก็ตามกิจกรรมทั้งหมดมีฟิลด์วันที่อย่างน้อยหนึ่งวัน (อาจเป็นการรวมกันของวันที่วันที่เริ่มต้นวันที่สิ้นสุดวันที่เริ่มต้นที่กำหนด ฯลฯ ) และเขตข้อมูลบุคคลที่รับผิดชอบหนึ่งรายการ ฟิลด์อื่นทั้งหมดนั้นแตกต่างกันอย่างมากและฟิลด์วันที่เริ่มต้นไม่จำเป็นต้องเรียกว่า "วันที่เริ่มต้น"
การสร้างตารางย่อยหนึ่งตารางสำหรับแต่ละประเภทกิจกรรมจะส่งผลให้สคีมามี 100 ตารางย่อยที่แตกต่างกันซึ่งจะเกินกว่าที่จะจัดการได้อย่างไม่เหมาะสม ทางออกปัจจุบันของปัญหานี้คือการเก็บค่ากิจกรรมเป็นคู่ของคีย์ - ค่า นี่เป็นสคีมาที่ง่ายขึ้นอย่างมากของระบบปัจจุบันเพื่อให้ได้คะแนน
แต่ละกิจกรรมมี ActivityField หลายรายการ แต่ละไซต์มีหลายกิจกรรมและตาราง SiteActivityData จะเก็บ KVP สำหรับแต่ละ SiteActivity
สิ่งนี้ทำให้แอปพลิเคชัน (บนเว็บ) ง่ายต่อการเขียนโค้ดเพราะสิ่งที่คุณต้องทำคือวนรอบเรคคอร์ดใน SiteActivityData สำหรับกิจกรรมที่กำหนดและเพิ่มเลเบลและการควบคุมเลเบลและอินพุตสำหรับแต่ละแถวในฟอร์ม แต่มีปัญหามากมาย:
- ความซื่อสัตย์นั้นไม่ดี เป็นไปได้ที่จะวางเขตข้อมูลใน SiteActivityData ที่ไม่ได้อยู่ในประเภทกิจกรรมและ DataValue เป็นเขตข้อมูล varchar ดังนั้นตัวเลขและวันที่จะต้องถูกโยนอย่างต่อเนื่อง
- การรายงานและการสอบถามแบบเฉพาะกิจของข้อมูลนี้เป็นเรื่องยากเกิดข้อผิดพลาดได้ง่ายและช้า ตัวอย่างเช่นการรับรายการกิจกรรมทั้งหมดของบางประเภทที่มีวันที่สิ้นสุดภายในช่วงที่ระบุต้องใช้ pivots และการคัดเลือก varchars จนถึงวันที่ ผู้เขียนรายงานเกลียดชังสคีมานี้และฉันไม่ตำหนิพวกเขา
ดังนั้นสิ่งที่ฉันกำลังมองหาคือวิธีเก็บกิจกรรมจำนวนมากที่แทบไม่มีฟิลด์เหมือนกันในแบบที่ทำให้การรายงานง่ายขึ้น สิ่งที่ฉันได้มาด้วยคือการใช้ XML เพื่อเก็บข้อมูลกิจกรรมในรูปแบบหลอก-noSQL:
ตารางกิจกรรมจะมี XSD สำหรับแต่ละกิจกรรมโดยไม่จำเป็นต้องใช้ตารางกิจกรรมของฟิลด์ SiteActivity จะมี XML คีย์ - ค่าดังนั้นแต่ละกิจกรรมสำหรับไซต์จะอยู่ในแถวเดียว
กิจกรรมจะมีลักษณะเช่นนี้ (แต่ฉันยังไม่ได้ทำให้มันสมบูรณ์):
<SomeActivityType>
<SomeDateField type="StartDate">2000-01-01</SomeDateField>
<AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
<EmployeeId type="ResponsiblePerson">1234</EmployeeId>
<SomeTextField>blah blah</SomeTextField>
...
ข้อดี:
- XSD จะตรวจสอบ XML จับข้อผิดพลาดเช่นการใส่สตริงในฟิลด์ตัวเลขที่ระดับฐานข้อมูลบางอย่างที่เป็นไปไม่ได้ด้วยสคีมาเก่าที่เก็บทุกอย่างใน varchar
- ชุดระเบียนของ KVP ที่ใช้ในการสร้างเว็บฟอร์มสามารถทำซ้ำได้อย่างง่ายดายโดยใช้
select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
- แบบสอบถามย่อย xpath ของ XML สามารถใช้ในการสร้างชุดผลลัพธ์ที่มีคอลัมน์สำหรับวันที่เริ่มต้น, วันที่สิ้นสุด ฯลฯ โดยไม่ต้องใช้เดือยเช่น
select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...
ดูเหมือนว่าเป็นความคิดที่ดีใช่ไหม ฉันไม่สามารถคิดวิธีอื่นในการจัดเก็บชุดคุณสมบัติที่แตกต่างจำนวนมากเช่นนั้น อีกความคิดหนึ่งที่ฉันมีคือเก็บสคีมาที่มีอยู่และแปลมันเป็นสิ่งที่สามารถสืบค้นได้ง่ายขึ้นในคลังข้อมูล แต่ฉันไม่เคยออกแบบสคีมาของดาวมาก่อนและคงไม่รู้ว่าจะเริ่มต้นอย่างไร
คำถามเพิ่มเติม: ถ้าฉันกำหนดแท็กว่ามีชนิดข้อมูลวันที่ใน XSD โดยใช้xs:date
SQL Server จะทำดัชนีเป็นค่าวันที่หรือไม่ ฉันกังวลว่าถ้าฉันค้นหาตามวันที่จะต้องใช้สตริงวันที่เป็นค่าวันที่และสร้างโอกาสในการใช้ดัชนี