Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cập nhật giá trị khóa chính bằng khung thực thể

Tôi có bằng Tiến sĩ. trong cs - trong lĩnh vực Cơ sở dữ liệu, vì vậy câu trả lời này sẽ khác một chút so với quan điểm của lập trình viên. Đối với Oliver Hanappi, một chiếc chìa khóa đôi khi có thể thay đổi nếu nó không phải là chìa khóa thay thế. Ví dụ. Một khóa tự nhiên hoặc một khóa tổng hợp. Ví dụ. Có thể thay đổi số SSN của bạn ở Hoa Kỳ. Nhưng nhiều lập trình viên trong nhiều năm sẽ coi đây là một chìa khóa không thể thay đổi và sử dụng nó như vậy. Việc thay đổi một khóa chính tổng hợp được tạo thành từ các khóa ngoại phổ biến hơn nhiều.

Tôi đang xử lý một cơ sở dữ liệu có mối quan hệ bậc ba. Cụ thể là ba thực thể (với khóa ngoại là khóa chính thay thế trong bảng tương ứng của chúng). Tuy nhiên, để duy trì mối quan hệ giữa hai thực thể trong khi thay đổi thực thể thứ ba yêu cầu thay đổi một phần của bảng giao nhau (còn gọi là bảng nối thuần túy trên MSDN) khóa chính. Đây là một thiết kế hợp lệ và chỉ có thể được cải thiện bằng cách loại bỏ bảng giao nhau của mối quan hệ bậc ba và thay thế nó bằng hai bảng quan hệ nhị phân (có thể có các khóa thay thế của riêng chúng). EF sẽ xử lý tốt điều này. Thay đổi thiết kế này sẽ tạo ra mô hình (Nhiều-> nhiều) -> nhiều hoặc Parent1-Parent2 -> Con-cháu (nếu điều đó không rõ ràng, hãy đọc ví dụ bên dưới). Khung thực thể sẽ hoạt động tốt với điều này vì mỗi mối quan hệ thực sự là một trong nhiều mối quan hệ. Nhưng nó là một thiết kế điên rồ từ góc nhìn DB. Hãy để tôi chỉ cho bạn một ví dụ tại sao.

Hãy xem xét rằng Khóa học, Lớp học và Người hướng dẫn được liên kết với nhau trong một lớp học. Lớp có thể bao gồm:CourseID, ClassroomID, CoachID làm khóa ngoại và chứa khóa chính tổng hợp bao gồm cả ba. Mặc dù một mô hình bậc ba rõ ràng, ngắn gọn (mối quan hệ 3 chiều), chúng tôi có thể chia nó thành các mối quan hệ nhị phân. Điều này sẽ cho hai bảng giao nhau. Việc thêm các khóa thay thế sẽ đáp ứng EF như sau:

Lớp ( SurrogateKeyClass , ID người hướng dẫn , CourseID )

ClassRoomUsed ( SurrogateKeyClassroomUsed , SurrogateKeyClass , ClassRoomID )

Vấn đề với thiết kế này là chúng ta có thể có cùng một khóa học và người hướng dẫn được liên kết nhiều lần, điều mà mô hình trước tránh được. Để tránh vấn đề này, bạn có thể thêm một ràng buộc trong cơ sở dữ liệu về tính duy nhất của hai trường ID, nhưng tại sao bạn lại muốn làm điều này khi bạn chỉ xử lý các khóa thay thế để bắt đầu? Tuy nhiên giải pháp này sẽ hoạt động tốt nhất như tôi có thể nói. Tuy nhiên, đây không phải là một thiết kế cơ sở dữ liệu logic vì ràng buộc duy nhất bất thường được yêu cầu trong DB.

NHƯNG, nếu bạn không muốn thay đổi cơ sở dữ liệu của mình hoặc không thể thay đổi cơ sở dữ liệu của mình, thì đây là giải pháp thứ hai :Các bảng giao điểm / liên kết chỉ có vậy, các liên kết liên kết hai thực thể trở lên với nhau. Nếu một thay đổi, hãy xóa liên kết và tạo lại liên kết mới có khóa ngoại thích hợp (thuộc tính điều hướng). Điều đó có nghĩa là bạn sẽ không được phép yêu cầu các thực thể con trong bất kỳ mối quan hệ nào, nhưng điều đó là cực kỳ phổ biến.

Tôi đề nghị rằng Entity Framework (trong tương lai) cho phép những người trong chúng ta, những người có thể thiết kế một mô hình DB thanh lịch để thay đổi các phần của khóa trong các bảng giao nhau / liên kết khi chúng ta muốn!

Một ví dụ khác miễn phí:

Hãy xem xét một Hiệp hội Sinh viên, Khóa học, Lớp. Học sinh được liên kết với một khóa học thông qua một cấp lớp. Thông thường, đây là một liên kết nhiều đến nhiều giữa Sinh viên và một Khóa học với một trường bổ sung trong bảng liên kết được gọi là điểm (các bảng liên kết có dữ liệu trọng tải như điểm, các bảng giao nhau không có tải trọng và được tham chiếu đến trong MSDN dưới dạng bảng tham gia thuần túy tại thuê tại một nơi):

Sinh viên ( StudentID , ....)

Khóa học ( CourseID , ...)

Đang tham gia ( StudentID , CourseID , lớp)

Nếu ai đó mắc lỗi nhập dữ liệu từ menu thả xuống và đưa học sinh vào nhầm lớp, bạn muốn họ thay đổi điều đó sau bằng cách chọn lại menu thả xuống và chọn một khóa học khác. Ở chế độ nền, bạn sẽ cần xóa đối tượng EF khỏi Bảng lấy và tạo lại nó mà không làm mất điểm nếu có. Chỉ cần thay đổi Khoá ngoại CourseID có vẻ như là một sự thay thế tốt hơn. Hãy đưa ra liên tưởng của riêng bạn nếu điều này có vẻ như giả tạo, nhưng với tư cách là một giáo sư, điều đó là tự nhiên đối với tôi.

Kết luận:Khi bạn có một chuỗi các mối quan hệ, tốt hơn là không nên cho phép xếp tầng và / hoặc thay đổi FK, nhưng vẫn tồn tại các tình huống hợp lý / hợp lý khi nó cần thiết, ngay cả khi không được khuyến nghị là phương pháp hay nhất trong chung .

Sự cố này có thể tự biểu hiện với các Ngoại lệ sau tùy thuộc vào việc bạn đang thay đổi thuộc tính điều hướng hay thuộc tính khóa trong mô hình tương ứng:

Đã xảy ra vi phạm ràng buộc toàn vẹn tham chiếu:Thuộc tính khóa chính là một phần của ràng buộc toàn vẹn tham chiếu không thể thay đổi khi đối tượng phụ thuộc là Không thay đổi trừ khi nó đang được đặt thành đối tượng chính của liên kết. Đối tượng chính phải được theo dõi và không được đánh dấu để xóa.

Thuộc tính 'X' là một phần của thông tin quan trọng của đối tượng và không thể sửa đổi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sắp xếp tự nhiên (chữ-số của con người) trong Microsoft SQL 2005

  2. SQL Server:Có thể chèn vào hai bảng cùng một lúc không?

  3. Chuyển đổi ‘datetime2’ thành ‘smalldatetime’ trong SQL Server (Ví dụ T-SQL)

  4. Tôi có nên thiết kế một bảng với khóa chính là varchar hoặc int?

  5. SQL Server:Đính kèm phiên bản 661 không chính xác