連接表還是非規範化?
我正在使用 MariaDB。
我正在設計一個簡單的應用程序,它可以在訂閱者訂閱的某些網站已更新時向訂閱者發送通知。
一個使用者可以訂閱幾個不同的站點,多個使用者可以訂閱同一個站點。
因此,兩個表在真空中都是獨立的。兩者的簡單模式,只是一個
- 包含 id 和 url 的站點表
- 包含 ID 和電話號碼的訂閱者表
我對效率和可擴展性的暫定流程如下所示
- 每小時從站點表中獲取所有站點的 Cron 作業
- 為所有站點發出並行 Web 請求
- 檢測已更改的站點(這將與站點表中的另一列進行比較)
- 提醒已更改站點的使用者哪些站點已更新(可能還會並行發送警報)
是否有必要為此引入連接表?我覺得它會引入複雜性,因為我必須每次都加入並更新每次對任一訂閱者表進行更改時。
或者..我應該只是非規範化..
似乎網站在這裡是一種“共同點”(即我會一直檢查每個網站是否都發生了變化,但我不一定需要所有訂閱者)
所以給定^,我在想也許只是添加一個 Sites.subsriber_ids 欄位..
或者..我應該採用 NoSQL 方法嗎?
有什麼想法和建議嗎?
謝謝!
聯結表不會影響您的性能,尤其是對於僅以每小時一次的頻率執行的程序。
NoSQL 在這裡也不會為您帶來任何優勢,並且 IMO 僅應在有無法在正常 RDBMS 中完成的案例時使用。
至於為什麼我認為這裡不需要非規範化:數據完整性是數據庫中最重要的事情,IMO。非規範化通常會導致數據冗餘,這對完整性具有更高的潛在風險。它還會導致更重的表,這些表也可能對性能產生影響。我真的看不出有什麼理由讓你在這裡非規範化一個簡單的連接表。維護它的額外工作應該是微不足道的,而不是性能瓶頸。
數據完整性可能受到質疑的一個範例是,當您多次冗餘儲存數據(例如 a
subscriber
)時phoneNumber
,因為您將在非規範化表中多次擁有相同的記錄(對於site
他們訂閱的每個記錄)。當它們phoneNumber
發生變化時,您需要一種事務一致的方式來更新它們在表中的所有實例,否則您將失去數據完整性。phoneNumber
當然,在您的簡單範例中,簡單的答案是通過 編寫更新語句
subscriberId
,您通常會被覆蓋。(這只是一個簡單的範例,因為您的案例非常簡單。)但是現在您還更新了許多記錄而不是一條記錄來更改,phoneNumber
這意味著需要定位更多行,從磁碟載入,鎖定(這可能導致整個表上的鎖升級——不確定這是否發生在 MariaDB 中)、更新並以事務方式寫回磁碟。這是非規範化表的性能影響的一個範例。