Mysql

創建和查詢數據庫以設置組、使用者、項目和點之間的層次關聯

  • March 29, 2019

我正在使用三種實體類型,組、使用者和項目。組由使用者組成,使用者由項目組成。

現在,我必須使用第四種實體類型:Point。我希望能夠在組、使用者和項目級別上分配這些積分。點是可以在多個級別上分配的實體。

假設我在“第 1 組”中有一個點,那麼所有使用者和項目都可以訪問它。因此,假設我添加了一個新使用者並將其附加到“組 1”,那麼它將自動訪問應用程序中的該點,因為它是“組 1”的成員。

假設我想給“A組”一個點,那麼一個點應該與該組、所有使用者和這些使用者的項目相關聯。

例如,如果我給“使用者 2”一個點,則該點與該使用者以及與該使用者關聯的所有項目相關聯。

我對這三個級別的想法是動態添加新數據並因此繼承這些權限,同時如果您決定只有一個項目應該能夠看到它,則能夠將 Point 權限一直添加到 Item 級別。

我將如何為這種情況制定數據方案?

到目前為止我的嘗試

實體關係圖

我嘗試繪製重要實體類型如何在我的腦海中連接的圖表:

在此處輸入圖像描述

數據操作

將 GROUP 1 分配給 POINT 1 的範例:

INSERT INTO Point_group
  (group_id,point_id) 
VALUES 
  (1,1);

將 USER 1 和 2 分配給 POINT 1 的範例:

INSERT INTO Point_user
   (user_id,point_id) 
VALUES 
   (1,1);
INSERT INTO Point_user
   (user_id,point_id) 
VALUES 
   (2,1);

然後編寫一些邏輯來確定基於此標記的條目。我覺得有點失落。

我認為您的方法 - 擁有 3 個連接表(Point_group, Point_user, Point_item)是合理的。

這種設計的考慮是:

  • 添加“權限”很容易 - 如果使用者選擇添加到User,那麼您插入Point_user
  • 以 開頭Point,如果您想詢問“哪些組、使用者和項目有權限?” 那麼您將需要針對所有 3 個連接表建構一個查詢。您可以在您的應用程序中有 3 個單獨的查詢和聚合結果,或者您可以有一個UNION3SELECT秒的單個查詢(一列表示SELECT包含一行的 ,其值如user等)
  • 如果您想從組、使用者或項目開始,並詢問“該組/使用者/項目允許哪些點?” 那麼你的查詢越往下越複雜。例如 - 如果您從一個項目開始,您必須查詢Point_item具有該項目 ID 的所有行。您還必須找到所有連結User的行 - 對於這些行中的每一行,檢查Point_user. 同樣,您必須找到所有連結的Group行,然後搜尋Point_group所有匹配項。在直接的 SQL 中,這將是一個很大的SELECT- 但這可能完全沒問題 - 這只是需要考慮的事情。

以另一種方式來解決這個問題 - 你有什麼選擇?

  • 您可以有一個表以某種方式將權限從點映射到其他對象。它的設計當然會有point_id,然後是一個列來指定這個點映射到什麼 - 即。Group, User, 或Item. 然後,當然,您需要一個id列 - 它將連結到相關表。

我之前已經看到過類似這種替代方案的模型,坦率地說,我認為這是一個更糟糕的設計。這樣的設計意味著當你想從你的點連接到另一個實體時,你需要檢查這個映射標誌列,以便決定應該連接哪個表。它是混亂、醜陋和性能密集型的。

然而,還有另一種選擇:

  • 將您的 Group、User 和 Item 表合併到一個表中。Entity在這個例子中,如果想要一個更好的名字,就叫它。您現在需要一個標誌來指示給定行上的實體類型 - 例如Group,UserItem。您還需要指定一列parent- 這樣Item您就可以為一行指定User其父級。

最後一個建議意味著您只需要一個實體和點之間的映射表。但是,再次執行上述所有場景 - 如果您從一個點開始,並且想知道哪些組、使用者和項目有權查看,您將如何查詢?獲取所有實體的列表將是一個簡單的查詢,但如果要列出所有實體的所有成員,則需要實體表多次連接自身。

最後一種設計可能有其好處,但我認為您的原始提案是最容易維護和理解的。

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