ภายในเว็บแอปพลิเคชั่นตัวหนึ่งที่ฉันทำงานอยู่การดำเนินการฐานข้อมูลทั้งหมดจะถูกทำให้เป็นนามธรรมโดยใช้แหล่งเก็บข้อมูลทั่วไปที่กำหนดไว้ผ่าน Entity Framework ORM
อย่างไรก็ตามเพื่อให้มีการออกแบบที่เรียบง่ายสำหรับที่เก็บข้อมูลทั่วไปตารางที่เกี่ยวข้องทั้งหมดจะต้องกำหนดจำนวนเต็มเฉพาะ ( Int32
ใน C #, int
ใน SQL) จนถึงขณะนี้ได้รับเสมอ PK IDENTITY
ของตารางและยังได้
คีย์ต่างประเทศมีการใช้งานอย่างหนักและจะอ้างอิงคอลัมน์จำนวนเต็มเหล่านี้ จำเป็นสำหรับทั้งความสอดคล้องและสำหรับการสร้างคุณสมบัติการนำทางโดย ORM
โดยทั่วไปแล้วแอปพลิเคชันเลเยอร์จะดำเนินการดังต่อไปนี้:
- การโหลดข้อมูลเริ่มต้นจากตาราง (*) -
SELECT * FROM table
- อัพเดท -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- ลบ -
DELETE FROM table WHERE Id = IdVal
- ส่วนแทรก -
INSERT INTO table (cols) VALUES (...)
การดำเนินการน้อยกว่าปกติ:
- แทรกจำนวนมาก -
BULK INSERT ... into table
ติดตาม (*) โดยโหลดข้อมูลทั้งหมด (เพื่อดึงข้อมูลตัวระบุที่สร้างขึ้น) - การลบแบบกลุ่ม - เป็นการดำเนินการลบแบบปกติ แต่ "ใหญ่" จากมุมมองของ ORM:
DELETE FROM table where OtherThanIdCol = SomeValue
- การอัปเดตจำนวนมาก - เป็นการดำเนินการอัปเดตตามปกติ แต่ "ใหญ่" จากมุมมองของ ORM:
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* ตารางเล็ก ๆ ทั้งหมดถูกแคชในระดับแอปพลิเคชันและเกือบทั้งหมดSELECTs
จะไม่สามารถเข้าถึงฐานข้อมูลได้ รูปแบบทั่วไปคือการโหลดครั้งแรกและจำนวนมากของINSERT
s, UPDATE
s และDELETE
s
ขึ้นอยู่กับการใช้งานแอปพลิเคชันปัจจุบันมีโอกาสน้อยมากที่จะเข้าถึงระเบียน 100M ในตารางใด ๆ
คำถาม: จากมุมมองของ DBA มีปัญหาที่สำคัญที่ฉันสามารถพบเจอได้ด้วยการ จำกัด การออกแบบตารางนี้หรือไม่?
[แก้ไข]
หลังจากอ่านคำตอบ (ขอบคุณสำหรับข้อเสนอแนะที่ยอดเยี่ยม) และบทความอ้างอิงฉันรู้สึกว่าฉันต้องเพิ่มรายละเอียดเพิ่มเติม:
เฉพาะแอปพลิเคชันปัจจุบัน - ฉันไม่ได้พูดถึงเกี่ยวกับแอปพลิเคชันเว็บปัจจุบันเนื่องจากฉันต้องการเข้าใจว่าสามารถนำโมเดลนี้ไปใช้กับแอปพลิเคชันอื่นได้หรือไม่ อย่างไรก็ตามกรณีเฉพาะของฉันคือแอปพลิเคชันที่ดึงข้อมูลเมตาจำนวนมากจาก DWH ข้อมูลต้นฉบับค่อนข้างยุ่งเหยิง (denormalized ในทางที่แปลกมีความไม่สอดคล้องกันไม่มีตัวระบุตามธรรมชาติในหลาย ๆ กรณี ฯลฯ ) และแอปของฉันกำลังสร้างเอนทิตีแยกชัดเจน นอกจากนี้ตัวบ่งชี้ที่สร้างขึ้นจำนวนมาก
IDENTITY
จะปรากฏขึ้นเพื่อให้ผู้ใช้สามารถใช้เป็นรหัสธุรกิจได้ นี้นอกจากรหัส refactoring ใหญ่ไม่รวมการใช้งานของ guid ของ"พวกเขาไม่ควรเป็นวิธีเดียวที่จะระบุแถวที่ไม่ซ้ำกัน" (Aaron Bertrand ♦) - นั่นคือคำแนะนำที่ดีมาก ตารางทั้งหมดของฉันยังกำหนด UNIQUE CONSTRAINT เพื่อให้แน่ใจว่าไม่อนุญาตให้ทำซ้ำธุรกิจ
การออกแบบที่ขับเคลื่อนด้วยแอพ Front-end และการออกแบบที่ขับเคลื่อนด้วยฐานข้อมูล - ตัวเลือกการออกแบบเกิดจากปัจจัยเหล่านี้
ข้อ จำกัด Entity Framework - อนุญาตให้มีหลาย PKs ได้ แต่ไม่สามารถอัพเดตค่าได้
ข้อ จำกัด ที่กำหนดเอง - การมีคีย์จำนวนเต็มเดี่ยวช่วยลดความซับซ้อนของโครงสร้างข้อมูลและรหัสที่ไม่ใช่ SQL เช่นรายการทั้งหมดมีคีย์จำนวนเต็มและค่าที่แสดง ที่สำคัญกว่านั้นคือรับประกันได้ว่าตารางใด ๆ ที่ทำเครื่องหมายไว้สำหรับแคชจะสามารถใส่ลงใน
Unique int key -> value
แผนที่ได้
แบบสอบถามแบบใช้เลือกข้อมูลที่ซับซ้อน - สิ่งนี้แทบจะไม่เกิดขึ้นเพราะข้อมูลตารางเล็ก ๆ (<20-30K ระเบียน) ถูกแคชในระดับแอปพลิเคชัน สิ่งนี้จะทำให้ชีวิตของคุณหนักขึ้นเล็กน้อยเมื่อเขียนรหัสแอปพลิเคชัน (ยากที่จะเขียน LINQ) แต่ฐานข้อมูลนั้นยอดเยี่ยมกว่า:
มุมมองรายการ - จะไม่สร้าง
SELECT
ข้อความค้นหาในการโหลด (ทุกอย่างถูกแคช) หรือแบบสอบถามที่มีลักษณะดังนี้:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
ค่าที่ต้องการอื่น ๆ ทั้งหมดจะถูกดึงผ่านการค้นหาแคช (O (1)) ดังนั้นจึงไม่มีการสร้างแบบสอบถามที่ซับซ้อน
แก้ไขมุมมอง - จะสร้าง
SELECT
คำสั่งเช่นนี้:SELECT allcolumns FROM BigTable WHERE PKId = value1
(ตัวกรองและค่าทั้งหมดคือint
s)