Có một câu hỏi tương tự đây bằng cách sử dụng siêu loại Phương tiện và thêm các loại phụ của CD, VCR, DVD, v.v.
Điều này có thể mở rộng ở chỗ khi tạo kiểu con BluRay, bạn tạo bảng để chứa dữ liệu dành riêng cho BluRay và thêm một mục vào bảng MediaTypes. Không cần thay đổi đối với dữ liệu hoặc mã hiện có - tất nhiên là ngoại trừ việc thêm mã sẽ hoạt động với dữ liệu BluRay.
Trong trường hợp của bạn, Người dùng sẽ là bảng siêu kiểu với Giáo viên và Học sinh là bảng phụ.
create table Users(
ID int not null auto_generating,
Type char( 1 ) check( Type in( 'T', 'S' )),
-- other data common to all users,
constraint PK_Users primary key( ID ),
constraint UQ_UserType unique( ID, Type ),
constraint FK_UserTypes foreign key( Type )
references UserTypes( ID )
);
create table Teachers(
TeacherID int not null,
TeacherType char( 1 ) check( TeacherType = 'T' )),
-- other data common to all teachers...,
constraint PK_Teachers primary key( TeacherID ),
constraint FK_TeacherUser foreign key( TeacherID, TeacherType )
references Users( ID, Types )
);
Trang trí của bảng Học sinh sẽ tương tự như bảng Giáo viên.
Vì cả giáo viên và học sinh đều có thể tuyển dụng giáo viên và học sinh khác, bảng có chứa mối quan hệ này sẽ tham chiếu đến bảng Người dùng.
create table Employment(
EmployerID int not null,
EmployeeID int not null,
-- other data concerning the employment...,
constraint CK_EmploymentDupes check( EmployerID <> EmployeeID ),
constraint PK_Employment primary key( EmployerID, EmployeeID ),
constraint FK_EmploymentEmployer foreign key( EmployerID )
references Users( ID ),
constraint FK_EmploymentEmployee foreign key( EmployeeID )
references Users( ID )
);
Theo tôi hiểu, Thông báo được nhóm theo nhà tuyển dụng:
create table Notifications(
EmployerID int not null
NotificationDate date,
NotificationData varchar( 500 ),
-- other notification data...,
constraint FK_NotificationsEmployer foreign key( EmployerID )
references Users( ID )
);
Các truy vấn phải đủ đơn giản. Ví dụ:nếu người dùng muốn xem tất cả các thông báo từ (các) chủ nhân của mình:
select e.EmployerID, n.NotificationDate, n.NotificationData
from Employment e
join Notifications n
on n.EmployerID = e.EmployerID
where e.EmployeeID = :UserID;
Tất nhiên, đây là bản phác thảo ban đầu. Có thể cải tiến. Nhưng đối với các điểm được đánh số của bạn:
- Bảng Việc làm liên quan đến người sử dụng lao động với nhân viên. Cách kiểm tra duy nhất để khiến người sử dụng lao động không thể tự mình làm nhân viên, nhưng nếu không thì bất kỳ người dùng nào cũng có thể vừa là nhân viên vừa là chủ.
- Bảng Người dùng buộc mỗi người dùng phải là giáo viên ('T') hoặc sinh viên ('S'). Chỉ những người dùng được định nghĩa là "T" mới có thể được đặt trong bảng Giáo viên và chỉ những người dùng được định nghĩa là "S" mới có thể được đặt trong bảng Học sinh.
- Bảng Việc làm chỉ tham gia vào bảng Người dùng, không tham gia vào cả bảng Giáo viên và Học sinh. Nhưng điều này là do cả giáo viên và sinh viên đều có thể là người sử dụng lao động và người lao động, không phải vì bất kỳ lý do hiệu suất nào. Nói chung, đừng lo lắng về hiệu suất trong quá trình thiết kế ban đầu. Mối quan tâm chính của bạn tại thời điểm này là tính toàn vẹn của dữ liệu. Cơ sở dữ liệu quan hệ rất tốt với các phép nối. Nếu một vấn đề về hiệu suất sẽ xuất hiện, sau đó khắc phục nó. Đừng cấu trúc lại dữ liệu của bạn để giải quyết các vấn đề chưa tồn tại và có thể không bao giờ tồn tại.
- Chà, hãy dùng thử cái này và xem nó hoạt động như thế nào.