Thích chuẩn hóa cơ sở dữ liệu so với Schema Trans minh bạch?


10

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.


2
Bạn có thể thấy ý tưởng của Martin Fowler về vai trò là một điều thú vị.
Marjan Venema

Nó thực sự là thú vị. Đáng buồn là không có quá nhiều cái nhìn sâu sắc về vấn đề cụ thể của tôi
GeminiDomino

Bạn sẽ nhận được các giáo sư trở thành quản trị viên và sinh viên có được công việc quản trị hoặc thậm chí trở lại 10 năm sau đó làm giảng viên. Bạn có thể đã có chúng. Bạn sẽ giữ những người riêng biệt hoặc cố gắng để thống nhất?
Elin

Các vai trò chỉ là ví dụ, nhưng tôi thấy quan điểm của bạn. Trong thực tế, ngay cả khi người dùng đã chuyển đổi vai trò, họ vẫn sẽ giữ các bản ghi riêng biệt.
GeminiDomino

Nếu sẽ tuyệt vời nếu bạn diễn đạt lại đoạn đầu tiên. Có một chút không rõ ràng. Ý tôi là, rõ ràng có một vấn đề nhưng nó không đủ rõ ràng nó là gì.
Tulains Córdova

Câu trả lời:


1

Ý tưởng thứ hai của bạn là chính xác. Cách tiếp cận này cho phép bạn thực hiện tất cả các ánh xạ mà bạn cần thực hiện để tích hợp ba không gian khóa va chạm của mình.

Điều quan trọng, nó cho phép cơ sở dữ liệu áp đặt hầu hết tính nhất quán mà bạn cần phải có bằng các ràng buộc khai báo .

Bạn đã có nhiều mã hơn bạn muốn có, vì vậy đừng thêm nhiều mã hơn mức cần thiết để giữ cho danh sách khóa tích hợp của bạn nhất quán. Hãy để công cụ cơ sở dữ liệu của bạn làm những gì nó được xây dựng để làm.

"Vấn đề con" gây khó chịu cho bạn trong Bản đồ 2USER_TYPEcột. Cột này rất quan trọng vì bạn cần nó để đảm bảo rằng INTERNAL_IDchỉ xuất hiện nhiều nhất một lần cho mỗi loại người dùng. Lần duy nhất bạn cần bất kỳ mã nào thậm chí nhận thức được USER_TYPElà mã chèn và xóa khỏi bảng ánh xạ của bạn. Điều này có thể được địa phương hóa khá tốt. Tôi cho rằng bạn sẽ tạo một điểm duy nhất trong mã của mình, nơi nội dung bảng ánh xạ được duy trì. Một cột thêm ở vị trí này nơi dữ liệu được viết không phải là vấn đề lớn. Những gì bạn thực sự muốn tránh là thêm cột thêm ở mọi nơi dữ liệu được đọc .

Mã trong các ứng dụng phụ của bạn cần sử dụng ánh xạ có thể không biết gì về USER_TYPEđơn giản bằng cách cung cấp cho mỗi ứng dụng phụ một chế độ xem ánh xạ xuống một loại người dùng dành riêng cho ứng dụng.


3

Từ kinh nghiệm, khuyến nghị của tôi là chọn sự nhất quán trên sự thanh lịch hoặc 'thực hành tốt nhất'. Đó là để phù hợp với thiết kế hiện có và đi với BA bảng gửi thư (một bảng cho mỗi vai trò) với mailing_id, user_idcấu trúc trường đơn giản .

Nó không phù hợp nhưng nó có một vài lợi thế ...

  1. Phù hợp với cấu trúc hiện tại sẽ dễ dàng hơn cho bất kỳ ai khác sẽ làm việc trên lược đồ này trước khi đưa ra đồng cỏ.
  2. Bạn không có các trường bị lãng phí và bạn không yêu cầu db khớp với những thứ không tồn tại.
  3. Bởi vì mỗi bảng sẽ chỉ cho nhau và sẽ tương đối dễ dàng để tạo chế độ xem liên kết tất cả dữ liệu cho thói quen của bạn để sử dụng.

Tôi chắc chắn rằng nhiều người khác sẽ không đồng ý với cách tiếp cận này, nhưng mục đích chính của bình thường hóa và thực tiễn tốt nhất là làm cho mã trở nên nhất quán hơn để dễ theo dõi và gỡ lỗi hơn ... và rõ ràng việc đưa toàn bộ cơ sở mã lên đầu có lẽ là không khả thi.


Vấn đề với cách tiếp cận đó là cơ sở dữ liệu sau đó không thể thực thi tính duy nhất trong id gửi thư, đó là mục đích chính của ánh xạ ở vị trí đầu tiên: nếu không, ghép các trường ID riêng lẻ từ mỗi bảng, với chỉ báo "loại người dùng" thực hiện mà không có bất kỳ thay đổi.
GeminiDomino

Tôi thấy những gì bạn đang làm nhưng đã làm việc trên loại hệ thống đó tôi đã đưa ra một tùy chọn mà bạn có thể chưa xem xét. Theo như tôi thấy thì id mail sẽ cần một số nội dung để đề cập đến một nơi nào đó (những gì đã được gửi qua thư hoặc cách tìm tài liệu) vì vậy id gửi thư dù sao cũng phải là một khóa ngoại, điều đó có nghĩa là các vấn đề duy nhất sẽ được giải quyết ở nơi khác. Khi tôi đọc nó, sinh viên quản trị và bảng dữ liệu prof được liên kết đến có thể có các cấu trúc khác nhau để tôi không thể thấy trường loại người dùng thêm giá trị. Các nhà phát triển ban đầu phải đánh vào vấn đề này, họ đã làm gì?
James Snell

Trường "loại người dùng" sẽ xác định bảng nào sẽ liên kết với bản ghi cụ thể đó. Nó sẽ phải được xử lý ở cấp độ ứng dụng, và vì chúng ở các bảng khác nhau, không có cách nào tốt để biến nó thành một ràng buộc khóa ngoài. Các nhà phát triển ban đầu dường như không xem xét vấn đề này chút nào, thật không may, đó là lý do tại sao nó biến thành một mớ hỗn độn như vậy. :)
GeminiDomino
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.