將兩個整數儲存為小數
將兩個整數儲存為小數有什麼缺點?
我將資產詳細資訊儲存在表中,每種資產類型都有自己的表(每種資產都非常不同)並使用另一個表來定義資產表,因此每個資產表都有一個整數 id,每個資產也有一個整數 id。
我有兩種不同的情況,這可能很方便:
- 有一個“審計”表來儲存如下資訊:這個使用者對那個項目做了這個
- 有人被指派處理這種類型的資產。我正在考慮像assetType.assetID一樣儲存它,所以資產類型5和id 99將是十進制5.99
我很少需要基於 5.99 進行選擇,我只需查詢儲存 5.99 的記錄,然後將其拆分並使用函式轉到表 5 記錄 99。
我無法將assetID 綁定到特定表;assetType 是表中引用資產表的條目的 id(定義表名、主鍵列等),所以看起來我無法使用外鍵約束。
有很多資產表,例如
asset_tmv
和asset_backflow
。資產根據其所在的表分配類型,因為要為每個資產儲存的數據差異很大。我意識到我可以使用 2 個整數欄位來實現這一點。我想知道的是:缺點是什麼?
- 有人被指派處理這種類型的資產。我正在考慮像assetType.assetID一樣儲存它,所以資產類型5和id 99將是十進制5.99
但是使用者沒有工作
assetID=99
,使用者正在工作assetID=990
。我確信 MySQL 會匹配5.99
兩者。您應該將兩個不同的值儲存在兩個不同的列中。
注意:為了展示通過其專用(邏輯級)列處理每個離散數據點的優勢,此答案僅基於以下摘錄:
…有人被指派處理這種類型的資產。我正在考慮像assetType.assetID一樣儲存它,所以資產類型5和id 99將是十進制5.99……
為了全面分析場景(每個實體類型、屬性和相關關聯),對您正在處理的特定業務領域的*所有資訊需求的描述是必不可少的;*換句話說,必須知道適用的業務規則,在此編輯時尚未提供。
如果您想提供所需的所有資訊以及涉及的所有相關細節,請告訴我,我很樂意分享我對整個場景的看法。
您通過評論澄清您的意圖是建構一個關係數據庫,因此在同一列中保留兩個不同的資訊將意味著多個缺點,例如:
- 所考慮的數據庫的邏輯抽象級別不會以所需的精度表示相應的概念模式。
- 以聲明方式設置邏輯級約束(值驗證)將更加困難(或不可能)(必須求助於過時的、次優的程序方法來保護數據完整性)。
- 邏輯級別的數據操作變得不必要地繁瑣。
- 為了優化甚至支持邏輯操作,數據庫管理系統必須在物理級別執行的工作變得更加複雜。
- 一般來說,數據庫的使用會變得不必要地更加困難,因為數據庫結構和約束會讓 DBA、應用程序程序員,更重要的是最終使用者感到困惑(在某些環境中,有高級使用者在沒有應用程序幫助的情況下訪問數據庫)。
資產範例_
讓我們以關於Asset實體類型的場景為例。所以,從概念層面開始分析,可以說:
- 資產主要通過其ID來區分
- 資產也可以通過完全相同的名稱來區分
- 資產按完全相同的類型分類。
- 類型對零個或多個資產進行分類
因此,該特定業務領域的資訊需求需要跟踪兩個不同的數據點,即Asset.Id和Asset.Type,每個數據點都具有確切的含義;因此,在這個階段,很明顯他們每個人:
- 需要一組特定的約束;和
- 有可能單獨進行操縱。
隨後,可以通過以下邏輯級 SQL-DDL 佈局來表示所述概念元素:
CREATE TABLE asset_type ( asset_type_id INT NOT NULL, name CHAR(30) NOT NULL, -- CONSTRAINT asset_type_PK PRIMARY KEY (asset_type_id), CONSTRAINT asset_type_AK UNIQUE (name) -- ALTERNATE KEY. ); CREATE TABLE asset ( asset_id INT NOT NULL, name CHAR(30) NOT NULL, asset_type_id INT NOT NULL, -- CONSTRAINT asset_PK PRIMARY KEY (asset_id), CONSTRAINT asset_AK UNIQUE (name), -- ALTERNATE KEY. CONSTRAINT asset_to_asset_type_FK FOREIGN KEY (asset_type_id) REFERENCES asset_type (asset_type_id) );
如圖所示,每個數據都將保存在其專用列中,並且採用這種安排:
- 可以以聲明方式將其約束
asset.asset_id
為asset
表的 PRIMARY KEY,從而防止在此類列中接受重複值的可能性。多年來,數據庫管理系統程序員一直致力於優化“幕後”執行的相關物理級流程。- 被聲明為 PRIMARY KEY,
asset.asset_id
列現在可以從一個或多個 FOREIGN KEY 約束中“用作目標”,以防萬一。asset.asset_type_id
通過在列上聲明 FOREIGN KEY 約束,對asset_type.asset_type_id
.- 在數據操作操作中,您不必求助於訪問列值子部分的函式(如非原子組合列的情況),無論是 INSERT、SELECT、UPDATE、DELETE 還是它們的組合。函式會(1)增加物理級別的處理時間,(2)會降低程式碼的可讀性。
- (a) 邏輯佈局準確地反映了 (b) 概念模式,有助於所有相關方解釋資料結構和結果集。自己編寫查詢要簡單得多,因為每一列都代表一條清晰且單獨的資訊。
- 在物理級別,擁有一個單獨的
asset.asset_type_id
列允許為該表修復一個(或多個)單列或多列索引,這可以加快邏輯查詢的執行,例如,將該列作為條件包含在WHERE 子句。因此,鑑於上述所有情況,我的主要觀點是:每個感興趣的數據點都應在邏輯級別由其對應的(正確鍵入和適當約束的)單獨列表示。
我建議您自己徹底重新分析場景,從 (i) 概念級別開始,然後進行 (ii) 相應的邏輯設計,因為該方法有助於獲得精確的映射,並且您將能夠避免不必要的直接破解。
審計追踪
您在問題中提到您有興趣為有問題的數據庫啟用某種審計跟踪,因此,鑑於此,我建議採用類似於我在這個答案和另一個答案中公開的方法(兩者都關於時間能力)當然還有相關的適應。