我在其中一家托管服務公司 -Hostinger- 上托管了 mysql 資料庫,該資料庫由 php API 從移動應用程式使用。有很多桌子。
為了更容易理解,我將僅將重要列作為物件顯示重要表:
user(id, username, password, balance, state);
cardsTrans(id, user_id, number, password, price, state);
customersTrans(id, user_id, location, state);
posTrans(id, user_id, number, state);
我想創建一張表而不是這三個交易表,這張表顯示如下:
allTransaction(id, user_id, target_id, type, card_number, card_pass, location);
我知道存在冗余并且某些列將變為空,并且我可以規范化該表,但是在查詢資料時會產生許多連接并且我對回應時間感興趣的規范化。解釋主要思想:用戶可以做三種型別的交易(每種型別有不同的表),這些交易存盤在allTransaction表中,user_id作為users表的外鍵,target_id作為其他表的外鍵,取決于方式。其他列也取決于型別,可能設定為 null。
我想要的是確定用戶使用應用程式時哪個更好的回應時間和性能。DML 操作(插入、更新、洗掉)經常應用在這些表上,還有非常多的查詢,通常通過 user_id 和 target_id 進行查詢。
如果我使用一個表,該表將有非常多的行和每行中的許多空值,因此會減慢查詢速度并占用大量存盤空間。
如果表有索引,索引會減慢插入或更新操作。
在沒有索引的表上為每個用戶創建磁區對于任何操作(選擇、插入、更新或洗掉)的回應時間會更好,還是創建多個表(每個用戶的表)更好。預期用戶數介于 (500 - 5000) 之間。
我搜索并發現了這個類似的問題MySQL performance: multiple tables vs. index on single table and partitions 但是當我對回應時間和性能感興趣時,它不在同一背景關系中,而且我的資料庫托管在托管服務器上而不是在與移動應用程式相同的設備中。
誰能告訴我什么更好,為什么?
uj5u.com熱心網友回復:
作為一般規則:
- 最差:多張桌子
- 更好:內置
PARTITIONing - 最佳:兩者都不是,只是更好的索引。
如果您想了解你的情況來具體談,請提供SHOW CREATE TABLE 與主SELECTs,DELETEs等。
有可能“過度規范化”。
三種型別的交易(每種型別都有不同的表)
這可能很棘手。最好有一張交易表。
“回應時間”——您是否期望每秒寫入數百次?
占用大量存盤空間。
通常正確的索引(尤其是“復合”索引)使表大小不是性能問題。
表上每個用戶的磁區
這并不比索引以user_id.
如果表有索引,索引會減慢插入或更新操作。
上的負擔寫入是多比的利益少讀。不要因為這個原因避免使用索引。
(如果您提供暫定CREATE TABLEs和 SQL 陳述句,我可以不那么含糊。)
uj5u.com熱心網友回復:
與其試圖預測未來,不如使用目前適用的最簡單模式,并準備在您通過實際使用了解更多資訊時進行更改。這意味著避免對代碼周圍的架構散布假設。查看架構遷移的概念以安全地更改架構和存盤庫模式以隱藏事物存盤方式的細節。5000 個用戶并不多(除非他們都同時使用系統)。
現在,采用提供最強參考完整性的設計。這意味著盡可能多的not null列。在開發產品時,您將引入一些錯誤,這些錯誤可能會意外地在應該插入值的地方插入空值。參照完整性提供了另一層保護。
例如,如果您有一個 AllTransactions 表,其中可能填充了一些欄位,并且可能不依賴于事務型別,您的架構必須使所有這些列都可以為空。架構無法防止您意外插入空值。
但是,如果您有單獨的 CardTransactions、CustomerTransactions 和 PosTransactions 表,則可以限制它們的模式以確保始終填寫所有必需的欄位。這將捕獲許多不同型別的錯誤。
對此的一個變體是擁有一個 UserTransaction 表,該表存盤有關用戶事務的所有通用資訊(user_id、時間戳),然后為每種型別的事務連接表。這是一個草圖。
user_transactions
id bigint primary key auto_increment
user_id integer not null references users on delete casade
-- Fields common to every transaction below
state enum(...) not null
price numeric not null
created_at timestamp not null default current_timestamp()
card_transactions
user_transaction_id bigint not null references user_transactions on delete cascade
card_id integer not null references cards on delete casade
..any other fields for card transactions...
pos_transactions
user_transaction_id bigint not null references user_transactions on delete cascade
pos_id integer not null references pos on delete cascade
..any other fields for POS transactions...
這提供了完全的參照完整性。沒有卡就不能進行卡交易。沒有 POS,您就無法進行 POS 交易。可以設定卡交易所需的任何欄位not null。可以設定 POS 交易所需的任何欄位not null。
獲取用戶的所有交易是一個簡單的索引查詢。
select *
from user_transactions
where user_id = ?
如果您只想要一種型別的左連接,那么也是一個簡單的索引查詢。
select *
from card_transactions ct
join user_transactions ut on ut.id = ct.user_transaction_id
where ut.user_id = ?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/355538.html
下一篇:如果滿足特定條件,如何復制表格?
