Database-Design

組織評論表:如何證明選擇的合理性?

  • April 17, 2018

業務領域描述

與相關業務領域相關的一些感興趣的實體類型是金錢使用者進度

使用者可能需要發表關於金錢進展的評論。

未來,也許會出現更多與評論相關的實體類型,而不僅僅是金錢進度

我的考慮

我有三個解決方案:

  1. 一張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
);
  1. 一張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

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