Đây là một thiết kế OO cổ điển với trở kháng bảng quan hệ không phù hợp. Thiết kế bảng mà bạn đã mô tả được gọi là 'bảng trên mỗi lớp con'. Ba thiết kế phổ biến nhất đều là sự thỏa hiệp so với những gì đối tượng của bạn thực sự trông giống như trong ứng dụng của bạn:
- Bảng cho mỗi lớp cụ thể
- Bảng trên mỗi hệ thống phân cấp
- Bảng trên mỗi lớp con
Thiết kế mà bạn không thích - "trong đó các bảng có 100 cột và hầu hết các giá trị là NULL" - là 2. một Bảng để lưu trữ toàn bộ hệ thống phân cấp chuyên môn hóa. Điều này là kém linh hoạt nhất vì tất cả các loại lý do, bao gồm - nếu ứng dụng của bạn yêu cầu một lớp phụ mới, bạn cần thêm các cột. Thiết kế mà bạn mô tả phù hợp sẽ thay đổi tốt hơn nhiều vì bạn có thể thêm mở rộng nó bằng cách thêm một bảng lớp con mới được mô tả bằng một giá trị trong product_type.
Tùy chọn còn lại - 1. Bảng cho mỗi lớp cụ thể - thường là không mong muốn vì sự trùng lặp liên quan đến việc triển khai tất cả các trường chung trong mỗi bảng chuyên môn. Mặc dù, ưu điểm là bạn sẽ không cần thực hiện bất kỳ phép nối nào và các bảng lớp con thậm chí có thể nằm trên các phiên bản db khác nhau trong một hệ thống rất lớn.
Thiết kế mà bạn mô tả là hoàn toàn khả thi. Biến thể bên dưới là giao diện của nó nếu bạn đang sử dụng công cụ ORM để thực hiện các hoạt động CRUD của mình. Lưu ý cách ID trong mỗi bảng lớp con LÀ giá trị FK cho bảng mẹ trong hệ thống phân cấp. ORM tốt sẽ tự động quản lý bảng lớp phụ CRUD chính xác dựa trên giá trị của các giá trị phân biệt trong product.id và product.product_type_id. Cho dù bạn có định sử dụng ORM hay không, hãy xem tài liệu về lớp con được kết hợp của hibernate, nếu chỉ để xem các quyết định thiết kế mà họ đã đưa ra.
product
=======
id INT
product_name VARCHAR
product_type_id INT -> Foreign key to product_type.product_type_id
valid_since DATETIME
valid_to DATETIME
magazine
========
id INT -> Foreign key to product.product_id
title VARCHAR
..
web_site
========
id INT -> Foreign key to product.product_id INT
name VARCHAR
..