簡體   English   中英

關系數據庫設計問題

[英]Database Design Issues with relationships

我正在對現有數據庫進行升級,該數據庫的設計沒有任何代碼來實現正在考慮的設計。 現在,我在用代碼實現數據庫設計方面遇到了困難。 我確定是數據庫設計有問題,還是我只是沒有看到關於如何完成需要做的事情的正確解決方案。

基本邏輯規定如下:

  1. 用戶通過席位訪問在線培訓。 用戶可以擁有多個席位。
  2. 席位由公司購買,並且與產品存在多對多關系。
  3. 產品與模塊之間存在多對多關系。
  4. 模塊與課程之間存在多對多關系。
  5. 課程是最終用戶訪問他們的培訓。
  6. 為了攪渾水,出於某種原因或另一種原因,一些用戶擁有多個包含相同產品的席位。
  7. 認證是基於每個產品進行的,而不是基於每個席位的。
  8. 用戶與存儲他們當前狀態或課程分數的課程之間存在多對多關系。
  9. 用戶在完成產品所有模塊中的所有課程后,即獲得產品認證。
  10. 了解特定模塊的所有課程何時由用戶完成也很重要。
  11. 某些席位將用於重新認證,這意味着之前獲得產品認證的用戶可以注冊並參加重新認證考試。
  12. 由於規則 11,用戶可以並且將擁有多個認證記錄。
  13. 編輯:當用戶完成課程(得分高於 80%)時,則用戶(根據當前業務邏輯)完成了包含課程的所有產品和所有座位的課程。

正如我或多或少描述的那樣,我一直遇到當前設計和業務邏輯的麻煩是,我無法找到一種方法來有效地將用戶是否已獲得特定產品和座位的認證與他們何時獲得認證聯系起來沒有。 我一直在嘗試確定哪些產品的座椅已經為用戶認證,哪些沒有。 部分問題是因為如果他們當前在不同席位下注冊了多個相同產品,那么我只需要計算一次產品。

下面是所涉及的架構部分的副本。 任何關於如何改進設計或在代碼中繪制關聯的建議將不勝感激。 如果重要的話,這個站點是建立在 LAMPP 堆棧上的。

您可以在此處查看數據庫架構的相關部分: http://lpsoftware.com/problem_db_structure.png

你要找的是關系除法沒有直接在SQL中實現,但可以做到。 在谷歌搜索其他示例。

快速查看架構后,我認為您可以做的一件事是創建一個“to_be_certified”表。 當產品被分配給一個座位時(當 product_seat_rtab 被填充時),用 user_id、product_id 和seat_id 填充它。

在certification_rtab 表中添加記錄時,刪除'to_be_certified' 表中的相應記錄。 這將使您可以輕松訪問所有已為用戶認證的產品和未認證的產品。

要去除重復的 product_id,您可以按 product_id 分組。

您需要對課程狀態_rtab 表進行更改:

CREATE TABLE lessonstatus_rtab (
  user_id    INT NOT NULL,
  seat_id    INT NOT NULL,
  lesson_id  INT NOT NULL REFERENCES lesson_rtab,
  accessdate TIMESTAMP,
  score      NUMERIC(5,2) NOT NULL DEFAULT 0,
  PRIMARY KEY (user_id, seat_id, lesson_id),
  FOREIGN KEY (user_id, seat_id) REFERENCES user_seat_rtab (user_id, seat_id)
);

然后你可以查詢用戶有席位的每個產品,他是否認證? 這假設他獲得的課程數量(例如 50% 或更高)與產品所有模塊中的課程數量相同。

SELECT p.name, us.user_id, us.seat_id, COUNT(l.id) = COUNT(lu.lesson_id) AS is_certified
FROM user_seat_rtab AS us
 JOIN seat_rtab AS s ON (s.id = us.seat_id)
 JOIN product_seat_rtab AS ps ON (ps.seat_id = s.id)
 JOIN product_rtab AS p ON (p.id = ps.product_id)
 JOIN product_module_rtab AS pm ON (pm.product_id = p.id)
 JOIN module_rtab AS m ON (m.id = pm.module_id)
 JOIN module_lesson_rtab AS ml ON (ml.module_id = m.id)
 JOIN lesson_rtab AS l ON (l.id = ml.lesson_id)
 LEFT OUTER JOIN lessonstatus_rtab AS lu 
   ON (lu.lesson_id = l.id AND lu.user_id = us.user_id 
     AND lu.seat_id = us.seat_id AND lu.score > 0.50)
GROUP BY p.id, us.user_id, us.seat_id;

更新:

我已經進一步考慮了這個問題,並考慮過簡單地刪除 user_seat_rtab 表,然后使用等效的certification_rtab 表(可能已重命名)來保存有關用戶席位狀態的所有信息是否能讓事情更好地工作。 通過這種方式,在用戶、他們的席位、席位內的每個產品以及用戶是否已針對特定產品和席位進行認證之間建立了直接關系。

因此,我會將以下更改應用於隨問題發布的架構:

DROP TABLE user_seat_rtab;
RENAME TABLE certification_rtab TO something_different;

進一步規范這個新結構的另一種方法是做這樣的事情:

ALTER TABLE user_seat_rtab 
    DROP PRIMARY KEY;
    ADD COLUMN product_id int(10) unsigned NOT NULL;
    ADD CONSTRAINT pk_user_seat_product PRIMARY KEY (user_id, seat_id, product_id);
    ADD CONSTRAINT fk_product_user_seat FOREIGN KEY (product_id) REFERENCES product_rtab(id) ON DELETE RESTRICT;

我不確定這是否會解決問題,或者它是否會在引入新問題的同時稍微改變問題的性質。 那么,有沒有人有任何其他批評或建議?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM