0

我正在爲一個Web應用程序項目設計一個數據庫,並且我得出結論我可能會有很少的查詢需要大量的連接表來進行一次檢查。存儲「冗餘」外鍵以避免加入

我想知道如何將外鍵存儲在某處,以減少這些查詢所需的連接數量?

爲了給你什麼,我都在這一刻一個例子: 服務=>預訂=>交易=>錢包=> BonusOffer

我需要檢查服務是否已經買了一個相關的錢包獎金。將BonusOffer ID存儲爲Transaction的外鍵是否明智?

你可以問爲什麼交易 - 這是因爲大多數這些查詢將「通過」交易和交易將在中間的某個地方。

+0

我的心說你不應該,但我的想法說你可以嘗試,如果你想。一如既往地檢查'EXPLAIN PLAN'來檢查是否有任何改進。因爲有時候你花了很多時間去優化db已經設計的優化,所以不需要擔心'太多'加入 –

+0

@JuanCarlosOropeza我的心也是這樣!我想過使用助手錶來連接'BonusOffer'和'Transaction'。這樣我就可以避免冗餘,並且查詢會得到滿足。你認爲這是一個更好的做法?事實上,我很確定這些查詢的速度會很快,但我希望在實際需要優化數據庫的性能之前獲得更多信息,而不是在出現性能問題時快速完成。 – user1970395

+0

我不認爲是更好的做法,因爲過於複雜而且會超出正常範圍。這意味着更難以維持,你需要向每個人都解釋你的聰明捷徑。 –

回答

0

聯合是關係數據庫管理系統的工作原理。瞭解並使用規範化。

我需要檢查服務是否與錢包相關的獎金購買。

如果每個服務都是這樣,那麼你的數據庫受到約束。它是(select service from Service_has_transaction join Transaction_has_wallet)(select service from Service_has_transaction join Transaction_has_wallet join Wallet_has_bonus)的子集。

大多數SQL DBMS不允許您以聲明方式表示該約束,並且不知道如何優化它的實施。然而,我們可以使用SQL語句來表達&以聲明方式強制執行它。 (在您的表格定義中猜測:)首先,將bonus列添加到Transaction_has_wallet,並將外鍵從Transaction_has_wallet (wallet, bonus)更改爲Wallet_has_bonus。然後將錢包&獎勵列添加到Service_has_transactionService_has_transaction (transaction, wallet, bonus)Transaction的外鍵。這會添加冗餘列,但是會將數據庫限制爲有效狀態,因爲外鍵約束會阻止冗餘值出錯。 (希望這是一個學習關於通過觸發器表達任意約束的動機示例。)