Database-Design
組織評論表:如何證明選擇的合理性?
業務領域描述
與相關業務領域相關的一些感興趣的實體類型是金錢、使用者和進度。
使用者可能需要發表關於金錢和進展的評論。
未來,也許會出現更多與評論相關的實體類型,而不僅僅是金錢和進度。
我的考慮
我有三個解決方案:
- 一張
comments
表,保留“註釋實體 id”和“實體類型”的相關性。CREATE TABLE comment ( user_id …, -- the identifier of who leaves comment text …, -- text of the comment created_at …, -- tells when comment has been left subject_type …, -- 'money' or 'progress' subject_id … -- identifier from 'money' or 'progress', depends on the 'subject_type' value );
- 一張
comment
桌子供所有人使用。comment_id
每個表在列中保留一個外鍵。該表有一個“複雜”的主鍵(id, created_at)
,並且id
值不是唯一的。CREATE TABLE comment ( id…, -- not unique created_at…, -- indicates when the comment was left user_id…, -- identifier of who leaves comment text…, -- the text of the comment CONSTRAINT comment_pk PRIMARY KEY (id, created_at) -- "complex" primary key );
當我需要獲取與給定實體實例關聯的所有註釋時,我通過類似
SELECT * FROM comment WHERE id = comment_id
. 3. 單獨的表格,例如comment_money
,comment_job
, … 所有表格看起來都一樣:CREATE TABLE comment_<entityName> ( id…, entity_id…, -- id of the commented entity user_id…, -- who leaves comment text…, -- text of the comment create_at… -- when the comment was left );
儘管我必須創建更多表,但我更喜歡第三種變體,因為邏輯非常簡單,而且這種方法易於管理和支持。
題
我會將數據庫模型(參見“業務領域描述”)傳遞給老師,但我不確定如何證明我的選擇是合理的。我認為老師可以說我的方法不好,因為我所有的表都有相同的列和結構。
- 什麼是好的論據?
- 也許有更多的解決方案?
這並不是真正的答案,而是更多的反思。但是,評論太久了,所以無論如何我都會將其添加為答案。如果我做對了,這些是基表:
CREATE TABLE USER ( USER_ID ... NOT NULL PRIMARY KEY , ... ); CREATE TABLE MONEY ( MONEY_ID ... NOT NULL PRIMARY KEY , ... ); CREATE TABLE PROGRESS ( PROGRESS_ID ... NOT NULL PRIMARY KEY , ... );
由於我不了解您的業務,因此我只是發明了一些標識符作為主鍵。它很可能是一個複合鍵,但為了簡單起見,我這樣做。
備選方案 1:
CREATE TABLE comment ( user_id ... not null references USER (user_id) , text ... , created_at ... , subject_type ... -- 'money' or 'progress' , subject_id ... -- identifier from 'money' or 'progress' );
總的來說,這是一個用於評論 MONEY 或 PROGRESS 的聯合類型。這是一種不太適合關係世界的結構。一個主要缺點是無法實現參照完整性(外鍵)。我不確定這裡的主鍵是什麼。
備選方案 2:
我不確定我明白你在這裡說什麼。金錢是否取決於評論?IE
CREATE TABLE comment ( id…, -- not unique created_at ... not null user_id… not null references USER (user_id) text ... not null CONSTRAINT comment_pk PRIMARY KEY (id, created_at) ); ALTER TABLE MONEY ADD CONSTRAINT ... FOREIGN KEY (MONEY_ID, created_at) -- add created_at in MONEY REFERENCES COMMENT (id, created_at);
和類似的進展。如果這就是你的意思,那麼評論必須在 MONEY 或 PROGRESS 之前存在,這對我來說似乎違反直覺。
備選方案 3
我可能會將名稱更改為:
CREATE TABLE MONEY_COMMENT ( MONEY_ID ... REFERENCES MONEY (MONEY_ID) , USER_ID ... REFERENCES USER (USER_ID) , CREATED_AT ... , ... , PRIMARY KEY (MONEY_ID, USER_ID, CREATED_AT) );
和一個類似的表 PROGRESS_COMMENT。我同意你的想法,這是最優雅的解決方案。如果您對使用者的所有評論感興趣,您可以創建如下視圖:
CREATE VIEW COMMENTS AS SELECT 'money' as COMMENT_TYPE , MONEY_ID AS COMMENT_ID , USER_ID , CREATED_AT , ... FROM MONEY_COMMENT UNION ALL SELECT 'progress' as COMMENT_TYPE , PROGRESS_ID AS COMMENT_ID , USER_ID , CREATED_AT , ... FROM PROGRESS_COMMENT