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

如何表示資料庫(kù)中的繼承?
P粉041856955
P粉041856955 2023-08-29 13:56:14
0
2
815
<p>我正在考慮如何在 SQL Server 資料庫(kù)中表示複雜的結(jié)構(gòu)。 </p> <p>考慮一個(gè)需要儲(chǔ)存一系列物件的詳細(xì)資訊的應(yīng)用程序,這些物件共享一些屬性,但有許多其他不常見的屬性。例如,商業(yè)保險(xiǎn)套餐可能在同一保單記錄中包括責(zé)任險(xiǎn)、機(jī)動(dòng)險(xiǎn)、財(cái)產(chǎn)險(xiǎn)和賠償險(xiǎn)。 </p> <p>在 C# 等實(shí)現(xiàn)這一點(diǎn)很簡(jiǎn)單,因?yàn)槟梢越糠旨系牟呗?,其中部分根?jù)各種類型的覆蓋的需要繼承。然而,關(guān)係資料庫(kù)似乎不允許這樣做。 </p> <p>我可以看到有兩個(gè)主要選擇:</p> <ol> <li><p>建立一個(gè)策略表,然後建立一個(gè)部分錶,其中包含所有可能的變體所需的所有字段,其中大部分為空。 </p></li> <li><p>建立策略表和多個(gè)部分錶,每個(gè)表對(duì)應(yīng)一種保險(xiǎn)。 </p></li> </ol> <p>這兩種替代方案似乎都不能令??人滿意,特別是因?yàn)樾枰缢胁糠志帉懖樵儯@將涉及大量聯(lián)接或大量空檢查。 </p> <p>此場(chǎng)景的最佳實(shí)踐是什麼? </p>
P粉041856955
P粉041856955

全部回覆(2)
P粉476475551

第三個(gè)選項(xiàng)是建立一個(gè)「Policy」表,然後建立一個(gè)「SectionsMain」表,用於儲(chǔ)存跨不同類型的部分所共有的所有欄位。然後為每種類型的部分建立其他表,僅包含不常見的欄位。

決定哪個(gè)最好主要取決於您有多少欄位以及您想要如何編寫 SQL。他們都會(huì)工作。如果你只有幾個(gè)字段,那麼我可能會(huì)選擇#1。對(duì)於「很多」領(lǐng)域,我傾向於#2 或#3。

P粉722521204

@Bill Karwin 在他的 SQL Antipatterns 書,在提出 SQL 實(shí)體屬性值反模式。這是一個(gè)簡(jiǎn)短的概述:

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

像第一個(gè)選項(xiàng)一樣使用單一表格可能是最簡(jiǎn)單的設(shè)計(jì)。正如您所提到的,許多特定於子類型的屬性必須在這些屬性不適用的行上被賦予 NULL 值。使用此模型,您將擁有一個(gè)策略表,如下所示:

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

保持設(shè)計(jì)簡(jiǎn)單是一個(gè)優(yōu)點(diǎn),但這種方法的主要問(wèn)題如下:

  • 在新增的子類型時(shí),您必須變更表格以適應(yīng)描述這些新物件的屬性。當(dāng)您有許多子類型或您計(jì)劃定期添加子類型時(shí),這很快就會(huì)成為問(wèn)題。

  • 資料庫(kù)將無(wú)法強(qiáng)制執(zhí)行哪些屬性適用,哪些不適用,因?yàn)闆]有元資料來(lái)定義哪些屬性屬於哪些子類型。

  • 您也無(wú)法強(qiáng)制執(zhí)行本應(yīng)強(qiáng)制執(zhí)行的子類型屬性 NOT NULL。您必須在應(yīng)用程式中處理這個(gè)問(wèn)題,這通常並不理想。

具體表繼承:

解決繼承問(wèn)題的另一種方法是為每個(gè)子類型建立一個(gè)新表,重複每個(gè)表中的所有公共屬性。例如:

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

這種設(shè)計(jì)基本上將解決單表方法所確定的問(wèn)題:

  • 現(xiàn)在可以透過(guò) NOT NULL 強(qiáng)制執(zhí)行強(qiáng)制屬性。

  • 新增子類型需要新增資料表,而不是新增資料表列。

  • 也不存在為特定子類型設(shè)定不適當(dāng)屬性的風(fēng)險(xiǎn),例如屬性策略的 vehicle_reg_no 欄位。

  • 不需要像單表方法中的 type 屬性。該類型現(xiàn)在由元資料定義:表名稱。

但是這種模型也有一些缺點(diǎn):

  • 公共屬性與子類型特定屬性混合在一起,沒有簡(jiǎn)單的方法來(lái)識(shí)別它們。資料庫(kù)也不知道。

  • 定義表格時(shí),您必須為每個(gè)子類型表重複公共屬性。這絕對(duì)不是。

  • 無(wú)論子類型如何,搜尋所有策略都變得很困難,並且需要一堆 UNION

無(wú)論類型為何,您都必須透過(guò)以下方式查詢所有策略:

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;

請(qǐng)注意,新增的子類型將需要為每個(gè)子類型使用附加的 UNION ALL 來(lái)修改上述查詢。如果忘記此操作,很容易導(dǎo)致應(yīng)用程式出現(xiàn)錯(cuò)誤。

類別表繼承(又稱每個(gè)類型的表繼承):

這是@David 在中提到的解決方案另一個(gè)答案。您為基類建立一個(gè)表,其中包括所有公共屬性。然後,您將為每個(gè)子類型建立特定的表,其主鍵也充當(dāng)基底表。範(fàn)例:

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

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

  • 可以透過(guò) NOT NULL 強(qiáng)制執(zhí)行強(qiáng)制屬性。

  • 新增子類型需要新增資料表,而不是新增資料表列。

  • 沒有為特定子類型設(shè)定不適當(dāng)屬性的風(fēng)險(xiǎn)。

  • 不需要 type 屬性。

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

  • 我們終於可以保持乾燥了。建立表格時(shí)無(wú)需重複每個(gè)子類型表的公共屬性。

  • 管理策略的自動(dòng)遞增 id 變得更容易,因?yàn)檫@可以由基底表處理,而不是每個(gè)子類型表獨(dú)立產(chǎn)生它們。

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

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


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

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