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

Làm thế nào bạn có thể biểu diễn sự kế thừa trong cơ sở dữ liệu?

@Bill Karwin mô tả ba mô hình kế thừa trong cuốn sách Phản vật chất SQL của mình, khi đề xuất giải pháp cho phản vật chất-Thuộc tính-Giá trị SQL. Đây là tổng quan ngắn gọn:

Kế thừa một bảng (hay còn gọi là Kế thừa theo hệ thống theo bảng):

Sử dụng một bảng đơn như trong tùy chọn đầu tiên của bạn có lẽ là thiết kế đơn giản nhất. Như bạn đã đề cập, nhiều thuộc tính dành riêng cho kiểu phụ sẽ phải được cung cấp NULL giá trị trên các hàng không áp dụng các thuộc tính này. Với mô hình này, bạn sẽ có một bảng chính sách, trông giống như sau:

+------+---------------------+----------+----------------+------------------+
| id   | date_issued         | type     | vehicle_reg_no | property_address |
+------+---------------------+----------+----------------+------------------+
|    1 | 2010-08-20 12:00:00 | MOTOR    | 01-A-04004     | NULL             |
|    2 | 2010-08-20 13:00:00 | MOTOR    | 02-B-01010     | NULL             |
|    3 | 2010-08-20 14:00:00 | PROPERTY | NULL           | Oxford Street    |
|    4 | 2010-08-20 15:00:00 | MOTOR    | 03-C-02020     | NULL             |
+------+---------------------+----------+----------------+------------------+

\------ COMMON FIELDS -------/          \----- SUBTYPE SPECIFIC FIELDS -----/

Giữ cho thiết kế đơn giản là một lợi thế, nhưng các vấn đề chính của cách tiếp cận này là:

  • Khi nói đến việc thêm các kiểu phụ mới, bạn sẽ phải thay đổi bảng để phù hợp với các thuộc tính mô tả các đối tượng mới này. Điều này có thể nhanh chóng trở thành vấn đề khi bạn có nhiều kiểu con hoặc nếu bạn định thêm kiểu con thường xuyên.

  • Cơ sở dữ liệu sẽ không thể thực thi thuộc tính nào áp dụng và thuộc tính nào không áp dụng, vì không có siêu dữ liệu để xác định thuộc tính nào thuộc về kiểu con nào.

  • Bạn cũng không thể thực thi NOT NULL trên các thuộc tính của một kiểu con cần phải bắt buộc. Bạn sẽ phải xử lý vấn đề này trong ứng dụng của mình, điều này nói chung không phải là lý tưởng.

Kế thừa Bảng Bê tông:

Một cách tiếp cận khác để giải quyết sự kế thừa là tạo một bảng mới cho mỗi kiểu con, lặp lại tất cả các thuộc tính chung trong mỗi bảng. Ví dụ:

--// Table: policies_motor
+------+---------------------+----------------+
| id   | date_issued         | vehicle_reg_no |
+------+---------------------+----------------+
|    1 | 2010-08-20 12:00:00 | 01-A-04004     |
|    2 | 2010-08-20 13:00:00 | 02-B-01010     |
|    3 | 2010-08-20 15:00:00 | 03-C-02020     |
+------+---------------------+----------------+
                          
--// Table: policies_property    
+------+---------------------+------------------+
| id   | date_issued         | property_address |
+------+---------------------+------------------+
|    1 | 2010-08-20 14:00:00 | Oxford Street    |   
+------+---------------------+------------------+

Thiết kế này về cơ bản sẽ giải quyết các vấn đề được xác định cho phương pháp bảng đơn:

  • Các thuộc tính bắt buộc hiện có thể được thực thi với NOT NULL .

  • Việc thêm một kiểu phụ mới yêu cầu phải thêm một bảng mới thay vì thêm các cột vào một bảng hiện có.

  • Cũng không có rủi ro rằng một thuộc tính không phù hợp được đặt cho một loại phụ cụ thể, chẳng hạn như vehicle_reg_no trường cho chính sách tài sản.

  • Không cần loại type thuộc tính như trong phương pháp bảng đơn. Loại hiện được xác định bởi siêu dữ liệu:tên bảng.

Tuy nhiên, mô hình này cũng đi kèm với một số nhược điểm:

  • Các thuộc tính chung được trộn lẫn với các thuộc tính cụ thể của loại phụ và không có cách nào dễ dàng để xác định chúng. Cơ sở dữ liệu cũng sẽ không biết.

  • Khi xác định các bảng, bạn sẽ phải lặp lại các thuộc tính chung cho mỗi bảng kiểu con. Đó chắc chắn không phải là KHÔ.

  • Việc tìm kiếm tất cả các chính sách bất kể loại phụ trở nên khó khăn và sẽ yêu cầu một loạt UNION s.

Đây là cách bạn sẽ phải truy vấn tất cả các chính sách bất kể loại:

SELECT     date_issued, other_common_fields, 'MOTOR' AS type
FROM       policies_motor
UNION ALL
SELECT     date_issued, other_common_fields, 'PROPERTY' AS type
FROM       policies_property;

Lưu ý rằng việc thêm các kiểu phụ mới sẽ yêu cầu sửa đổi truy vấn trên bằng một UNION ALL bổ sung như thế nào cho mỗi loại con. Điều này có thể dễ dàng dẫn đến lỗi trong ứng dụng của bạn nếu bạn quên thao tác này.

Kế thừa bảng lớp (hay còn gọi là kế thừa bảng mỗi loại):

Đây là giải pháp mà @David đề cập trong câu trả lời khác. Bạn tạo một bảng duy nhất cho lớp cơ sở của mình, bảng này bao gồm tất cả các thuộc tính chung. Sau đó, bạn sẽ tạo các bảng cụ thể cho từng kiểu con, mà khóa chính của chúng cũng đóng vai trò là khóa ngoại cho bảng cơ sở. Ví dụ:

CREATE TABLE policies (
   policy_id          int,
   date_issued        datetime,

   -- // other common attributes ...
);

CREATE TABLE policy_motor (
    policy_id         int,
    vehicle_reg_no    varchar(20),

   -- // other attributes specific to motor insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

CREATE TABLE policy_property (
    policy_id         int,
    property_address  varchar(20),

   -- // other attributes specific to property insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

Giải pháp này giải quyết các vấn đề được xác định trong hai thiết kế còn lại:

  • Các thuộc tính bắt buộc có thể được thực thi với NOT NULL .

  • Việc thêm một kiểu phụ mới yêu cầu phải thêm một bảng mới thay vì thêm các cột vào một bảng hiện có.

  • Không có rủi ro rằng một thuộc tính không phù hợp được đặt cho một loại phụ cụ thể.

  • Không cần loại type thuộc tính.

  • Giờ đây, các thuộc tính chung không bị trộn lẫn với các thuộc tính cụ thể của loại phụ nữa.

  • Cuối cùng thì chúng ta cũng có thể ở DRY. Không cần phải lặp lại các thuộc tính chung cho mỗi bảng kiểu con khi tạo bảng.

  • Quản lý id tăng dần tự động đối với các chính sách trở nên dễ dàng hơn, vì điều này có thể được xử lý bởi bảng cơ sở, thay vì mỗi bảng loại phụ tạo ra chúng một cách độc lập.

  • Việc tìm kiếm tất cả các chính sách bất kể loại phụ giờ đây trở nên rất dễ dàng:Không có UNION cần thiết - chỉ cần một SELECT * FROM policies .

Tôi coi cách tiếp cận bảng lớp là phù hợp nhất trong hầu hết các tình huống.

Tên của ba mô hình này xuất phát từ cuốn sách Các mẫu kiến ​​trúc ứng dụng doanh nghiệp của Martin Fowler.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trả về tất cả các kết hợp giá trị có thể có trên các cột trong SQL

  2. Ngày xây dựng từ năm và số tuần trong MSSQL

  3. SQL Server 2005 và phạm vi bảng tạm thời

  4. Khám phá các thao tác lập chỉ mục trực tuyến cấp độ phân vùng trong SQL Server 2014 CTP1

  5. Khi xóa tầng cho bảng tự tham chiếu