Một yêu cầu mới đã xuất hiện trên một cơ sở mã cũ, về cơ bản cho phép giao tiếp trực tiếp (nội bộ) giữa hai lớp người dùng trước đây không liên quan trực tiếp (được lưu trữ trong các bảng khác nhau với lược đồ hoàn toàn khác nhau và thật đáng buồn, mã này hầu như không nhận biết được OO ít được thiết kế, vì vậy không có lớp cha mẹ). Vì chúng tôi không thể treo túi trên thiết lập cũ này mà không bao giờ xem xét chức năng này, nên không có gì đảm bảo rằng không có xung đột PK - được cung cấp cho tập dữ liệu được sử dụng, thực tế đảm bảo rằng CÓ.
Vì vậy, giải pháp có vẻ hiển nhiên: giết nó bằng lửa và viết lại toàn bộ bảng ánh xạ lộn xộn . Tôi đã nhận được hai hướng cho các cách có thể để thực hiện bản đồ, nhưng tôi không phải là một DBA, vì vậy tôi không chắc chắn nếu có bất kỳ ưu và nhược điểm nào tôi đã bỏ lỡ.
Để làm rõ sự trừu tượng, hãy xem xét ba nhóm dữ liệu người dùng khác nhau: Giáo sư, Quản trị, Sinh viên (Không, đây không phải là bài tập về nhà. Hứa hẹn!)
Ánh xạ 1
(GS_id, admin_id và student_id là các khóa ngoại đối với các bảng tương ứng của chúng)
| mailing_id (KEY) | professor_id | admin_id | student_id |
-------------------------------------------------------
| 1001 | NULL | 87 | NULL |
| 1002 | 123 | NULL | NULL |
| 1003 | NULL | NULL | 123 |
+/- cho cách tiếp cận này có vẻ khá nặng về nhược điểm:
- Hai trường "lãng phí" mỗi hàng
- Vi phạm 2NF
- Dễ bị chèn / cập nhật dị thường (một hàng chỉ có trường 0-1 đặt NULL, vd)
Những ưu điểm không phải là không có giá trị riêng của họ, mặc dù:
- Ánh xạ có thể được thực hiện với một tra cứu duy nhất
- Dễ dàng xác định dữ liệu "nguồn" cho một người dùng nhất định từ mailing_id
Sự thật mà nói, trong ruột của tôi, tôi không thích ý tưởng này chút nào.
Ánh xạ 2
(giả sử MSG_ * là các hằng số xác định, loại enum hoặc mã định danh phù hợp khác)
| mailing_id (KEY) | user_type (UNIQUE1) | internal_id (UNIQUE2)|
------------------------------------------------------------------
| 1001 | MSG_ADMIN | 87 |
| 1002 | MSG_PROF | 123 |
| 1003 | MSG_STUDENT | 123 |
Với thiết lập này và một chỉ mục tổng hợp duy nhất của {user_type, Internal_id} mọi thứ trở nên sạch sẽ hơn, 3NF được duy trì và mã ứng dụng không phải kiểm tra dị thường I / U.
Mặt khác, có một chút mất minh bạch trong việc xác định các bảng nguồn người dùng phải được xử lý bên ngoài DB, về cơ bản lên tới ánh xạ mức ứng dụng của các giá trị user_type vào các bảng. Ngay bây giờ, tôi (khá mạnh mẽ) nghiêng về bản đồ thứ 2 này, vì nhược điểm là khá nhỏ.
NHƯNG tôi đau đớn nhận ra những hạn chế của chính mình và chắc chắn rằng tôi có thể đã bỏ lỡ những lợi thế hoặc vấp ngã ở cả hai hướng, vì vậy tôi chuyển sang những suy nghĩ khôn ngoan hơn tôi.