Database-Design

數據庫設計 - 記錄在多個表中時記錄相同的值

  • January 3, 2020

我需要記錄對特定值的更改,該值作為多個事件的一部分被讀取,這些事件都是單獨跟踪的,並且以後能夠查看所有值的日誌。

我認為一個例子可以更好地描述這個問題:假設我正在為一家汽車租賃公司設計一個數據庫。該公司有一份他們所有汽車的清單,他們希望盡可能多地跟踪每輛車的里程表讀數。因此,該公司將里程表讀取為許多不同事件的一部分,這些事件也被記錄下來,例如租賃、轉讓、維護等。

數據庫可能看起來像這樣(注意 OdometerReading 是如何重複的):

Cars             Rentals             Transfers           Maintenance
====             =======             =========           ===========
Car_ID           Rental_ID           Transfer_ID         Maintenance_ID
SerialNumber     Car_ID              Car_ID              Car_ID
...              RentalDate          TransferDate        MaintenanceDate
                OdometerReading     OfficeFrom          Notes
                ...                 OfficeTo            OdometerReading
                                    OdometerReading     ...
                                    ...

**這是繼續向下的好路線嗎?**像這樣在不同的表中有相同的欄位(OdometerReading)似乎很奇怪。

我需要能夠生成一份報告,顯示里程表讀數隨時間的歷史。

我可以寫一個查詢,例如:

SELECT RentalDate, OdometerReading
FROM Rentals
UNION ALL
SELECT TransferDate, OdometerReading
FROM Transfers
UNION ALL
SELECT MaintenanceDate, OdometerReading
FROM Maintenance
ORDER BY RentalDate

或者,我可以從所有表中刪除 OdometerReading 欄位,並有一個像這樣的里程表讀數表:

Rentals                 OdometerReadings
=======                 ================
Rental_ID               OdometerReading_ID
Car_ID                  Date
RentalDate              Mileage
OdometerReadings_ID
...

--(other tables removed for brevity)

這樣,在查看所有租賃事件時,仍然可以包括里程表讀數。

但這似乎給我帶來了其他問題。日期現在記錄在兩個地方(例如,Rentals.RentalDate 和 OdometerReadings.Date),並且似乎更難以確定里程表讀數的來源(儘管我相信您可以離開加入 OdometerReadings 表以及潛在的源表和過濾器其中右表為空)。


將相同值記錄為許多不同記錄/事件的一部分的好方法是什麼,每個記錄/事件都有自己的表?

另一種選擇是為您的事件使用簡單的表繼承,並將事件作為基本類型:

CarEvents              RentalEvents
=========              ============
ID <------------------ EventID
EventType         |    CustomerID
CarID             |    RentalDetail03
EventDate         |         ...
MilageReading     |    RentalDetailNN
GeneralDatail05   |
   ...           |
GeneralDatailNN   |    TransferEvents
                 |    ==============
                 `--- EventID
                 |    SourceOfficeID
                 |    DestinationOfficeID
                 |    TransferDetail04
                 |          ...
                 |    TransferDetailNN
                 |
                 |
                 |    MaintEvents
                 |    ==============
                 `--- EventID
                        ...

這意味著關於一般屬性(事件日期、涉及的汽車等)的查詢只針對一張表,而不需要合併不同的來源,而無需複制一般細節。當然,要報告給定的事件類型,您需要加入相關的子表,而要報告多種事件類型,您必須加入多個子表。

一些數據庫已經內置了對這種繼承形式的支持,這使得它的行為更加自動化(有點像分區),這意味著你作為開發人員要做的工作略少,但這本質上是語法糖,你可以看到基本結構根本不是火箭科學。

引用自:https://dba.stackexchange.com/questions/256630