3

我正在開發具有多租戶的SaaS應用程序,並且我決定爲客戶端數據使用單個數據庫(MySQL Innodb)。我選擇使用複合主鍵,如PK(client_id,id)。我有2種方式在這裏,複合主鍵和自動增量?什麼是好的做法?

1:增量 「編號」 由我自己(通過觸發器或代碼)

2:製作 「身份證」,通過MySQL的自動遞增。

在第一種情況下,我將有獨特的的ID爲每一個客戶,所以每個客戶都會有編號1,2,3等。 在第二種情況下的ID將所有客戶拓展業務。 這裏最好的做法是什麼?我的優先級是:性能,安全&縮放。謝謝!

+1

第一個選項確實不會讓你非常滿意,必須予以維護。這個新表與客戶表有一對多的關係嗎?究竟是什麼讓記錄顯而易見?如果沒有,那麼使用自動增量。這實際上只取決於情況。 – sgeddes

+1

作爲最後一條評論的後續,client_id是一個外鍵?也就是說,它是否引用客戶端表中的現有ID? –

+1

你的主鍵應該只是自動增量編號。不要包含client_id,它不會添加其他信息。帶innodb的auto_increment id的PK(client_id,id)只有在添加一個索引(id)時纔可能實現,這將再次不會添加其他信息。而具有自我維護ID的PK(client_id,id)會增加開銷,同時又不會添加額外信息(例如,如果您不想通過測試來檢查新數據是否已存在以確保數據完整性 - 如果添加新的一行,無論如何你都會增加ID)。所以:PK(id)和一個索引(客戶端)。 – Solarflare

回答

2

您一定要使用自動增量id值作爲主鍵。碰巧有很多原因。這裏有一些。

  1. 避免競爭條件(意外id重複)需要非常小心,如果你自己生成它們。花費精力開發,質量保證和操作 - 使您的SaaS非常出色,而不是在主鑰匙上重新設計輪胎。
  2. 即使不是PK,您仍然可以在(client_id, id)上放置索引。
  3. 您的JOIN操作將更容易編寫,測試和維護。
  4. 此查詢模式非常適合從表中獲取每個客戶端的最新行。它表現非常好。如果您生成自己的pks,則很難做到這一點。

    SELECT t.* 
         FROM table t 
         JOIN (SELECT MAX(id) id 
           FROM table 
          GROUP BY client_id 
         ) m ON t.id = m.id 
    
+0

我只是認爲,在客戶數據之間選擇時,組合鍵可以爲我提供某種安全性(防止拼寫錯誤的'id'等),並且可能會在未來進行某些縮放(分片)專業人員。但看起來我只是複雜的東西!) – teMkaa

1

「PK(CLIENT_ID,ID)」 -

id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(client_id, id), 
INDEX(id) 

是,該組合將工作。它會有效地工作。它不會爲每個客戶分配1,2,3,但這不重要。相反,連續的ID將分散在客戶端之中。

可能所有的查詢都會包含WHERE client_id = (constant),對嗎?這意味着將始終使用PRIMARY KEY(client_id, id),並且將不會使用INDEX(id),除非滿足AUTO_INCREMENT

此外,該PK將比具有INDEX(client_id, id)更高效。 (這是因爲InnoDB會將數據集羣「聚集」在一起)。