国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

如何表示數(shù)據(jù)庫中的繼承?
P粉041856955
P粉041856955 2023-08-29 13:56:14
0
2
816
<p>我正在考慮如何在 SQL Server 數(shù)據(jù)庫中表示復雜的結(jié)構(gòu)。</p> <p>考慮一個需要存儲一系列對象的詳細信息的應用程序,這些對象共享一些屬性,但有許多其他不常見的屬性。例如,商業(yè)保險套餐可能在同一保單記錄中包括責任險、機動險、財產(chǎn)險和賠償險。</p> <p>在 C# 等中實現(xiàn)這一點很簡單,因為您可以創(chuàng)建包含部分集合的策略,其中部分根據(jù)各種類型的覆蓋的需要繼承。然而,關系數(shù)據(jù)庫似乎不允許這樣做。</p> <p>我可以看到有兩個主要選擇:</p> <ol> <li><p>創(chuàng)建一個策略表,然后創(chuàng)建一個部分表,其中包含所有可能的變體所需的所有字段,其中大部分為空。 </p></li> <li><p>創(chuàng)建一個策略表和多個部分表,每個表對應一種保險。</p></li> </ol> <p>這兩種替代方案似乎都不能令人滿意,特別是因為需要跨所有部分編寫查詢,這將涉及大量聯(lián)接或大量空檢查。</p> <p>此場景的最佳實踐是什么?</p>
P粉041856955
P粉041856955

全部回復(2)
P粉476475551

第三個選項是創(chuàng)建一個“Policy”表,然后創(chuàng)建一個“SectionsMain”表,用于存儲跨不同類型的部分所共有的所有字段。然后為每種類型的部分創(chuàng)建其他表,僅包含不常見的字段。

決定哪個最好主要取決于您有多少字段以及您想要如何編寫 SQL。他們都會工作。如果你只有幾個字段,那么我可能會選擇#1。對于“很多”領域,我傾向于#2 或#3。

P粉722521204

@Bill Karwin 在他的 SQL Antipatterns 書,在提出 SQL 實體屬性值反模式。這是一個簡短的概述:

單表繼承(又名每層次結(jié)構(gòu)表繼承):

像第一個選項一樣使用單個表可能是最簡單的設計。正如您所提到的,許多特定于子類型的屬性必須在這些屬性不適用的行上被賦予 NULL 值。使用此模型,您將擁有一個策略表,如下所示:

+------+---------------------+----------+----------------+------------------+
| 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 -----/

保持設計簡單是一個優(yōu)點,但這種方法的主要問題如下:

  • 在添加新的子類型時,您必須更改表以適應描述這些新對象的屬性。當您有許多子類型或者您計劃定期添加子類型時,這很快就會成為問題。

  • 數(shù)據(jù)庫將無法強制執(zhí)行哪些屬性適用,哪些不適用,因為沒有元數(shù)據(jù)來定義哪些屬性屬于哪些子類型。

  • 您也無法對本應強制執(zhí)行的子類型屬性強制執(zhí)行 NOT NULL。您必須在應用程序中處理這個問題,這通常并不理想。

具體表繼承:

解決繼承問題的另一種方法是為每個子類型創(chuàng)建一個新表,重復每個表中的所有公共屬性。例如:

--// 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    |   
+------+---------------------+------------------+

這種設計將基本上解決單表方法所確定的問題:

  • 現(xiàn)在可以通過 NOT NULL 強制執(zhí)行強制屬性。

  • 添加新子類型需要添加新表,而不是向現(xiàn)有表添加列。

  • 也不存在為特定子類型設置不適當屬性的風險,例如屬性策略的 vehicle_reg_no 字段。

  • 不需要像單表方法中那樣的 type 屬性。該類型現(xiàn)在由元數(shù)據(jù)定義:表名稱。

但是這種模型也有一些缺點:

  • 公共屬性與子類型特定屬性混合在一起,沒有簡單的方法來識別它們。數(shù)據(jù)庫也不知道。

  • 定義表時,您必須為每個子類型表重復公共屬性。這絕對不是

  • 無論子類型如何,搜索所有策略都變得很困難,并且需要一堆 UNION。

無論類型如何,您都必須通過以下方式查詢所有策略:

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;

請注意,添加新的子類型將需要為每個子類型使用附加的 UNION ALL 來修改上述查詢。如果忘記此操作,很容易導致應用程序出現(xiàn)錯誤。

類表繼承(又名每個類型的表繼承):

這是@David 在中提到的解決方案另一個答案。您為基類創(chuàng)建一個表,其中包括所有公共屬性。然后,您將為每個子類型創(chuàng)建特定的表,其主鍵也充當基表。示例:

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)
);

該解決方案解決了其他兩種設計中發(fā)現(xiàn)的問題:

  • 可以通過 NOT NULL 強制執(zhí)行強制屬性。

  • 添加新子類型需要添加新表,而不是向現(xiàn)有表添加列。

  • 沒有為特定子類型設置不適當屬性的風險。

  • 不需要 type 屬性。

  • 現(xiàn)在公共屬性不再與子類型特定屬性混合。

  • 我們終于可以保持干燥了。創(chuàng)建表時無需重復每個子類型表的公共屬性。

  • 管理策略的自動遞增 id 變得更加容易,因為這可以由基表處理,而不是每個子類型表獨立生成它們。

  • 搜索所有策略(無論子類型如何)現(xiàn)在都變得非常容易:不需要 UNION - 只需 SELECT * FROM 策略。

我認為類表方法在大多數(shù)情況下是最合適的。


這三個模型的名稱來自Martin Fowler一本書企業(yè)應用架構(gòu)模式。

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板