2013-05-20 39 views
0

我想創建一個表,這個信息:拆分數據到兩個表

ID bigint(20) PK AI 
FID bigint(20) unique 
points int(10) index 
birthday date index 
current_city varchar(175) index 
current_country varchar(100) index 
home_city varchar(175) index 
home_country varchar(100) index 
Engine = MyISAM 

在學校學到:創建2個額外的表,一個與城市和一個與國家和FK到表插入數據時。我懷疑的原因是:

此表將有大約10M插入一小時。如果我插入一行,並且每次插入都必須查找城市FK和國家FK,我恐怕會失去很多速度?當我選擇僅在WHERE ID = ID時發生的行時,這是否值得我獲得的收益?將會有大約25M這些選擇一個小時。

+0

感謝您的編輯,因爲您看到我對於stackoverflow也很新穎:) –

+0

我會說要這樣做。使用外鍵維護您的完整性並改善查詢的好處將超過插入和更新的輕微開銷。插入速度非常快,無論如何,我懷疑插入開銷的影響是顯而易見的。 – Scotch

回答

2

過早的優化,如果所有罪惡的根源。首先設計乾淨,然後在有實際性能數據時進行優化。

一個乾淨的設計將是一個正確的標準化表格,即具有獨立的城市和一個國家的表。

我怕如果我插入一行,並有查找城市FK和國家FK每次插入,我可能會失去很多的速度?

實際上,varchar列中插入只是小的ID,而不是原國家/城市的名稱可能是更有效的:

  • 這將導致更少的磁盤寫入
  • 你有的MyISAM表;所以它沒有FK的支持,並沒有做任何外鍵查找/檢查
  • 與整數更換varchar列將把表fixed-length rows format,這可能比動態長度格式

基準與實際數據/工作量,並查看是否取消正火真的是值得的。

+0

我看到你的觀點,我對MySQL和PHP(用於在C#中編程)非常新,非常感謝這些信息。沒有FK查找檢查當然更不完整,但插入時會更快? –

1

還有就是爲什麼DB正常化存在的理由。
使用表的城市,一個國家,並通過FK是你的主表加入他們的行列。
另外,你知道哪個國家有100個字符的名字?
你認識哪個城市有175個字符?
ID可以是bigint,但是您確定需要BIGINT(20)嗎,INT(11)不會滿足嗎?無論如何,AUTOINCREMENT它,而不是UNIQUE它,它沒有任何意義。
另外,您在每列上都有索引,但沒有組合索引。這有很多原因是錯誤的。不要pre-index,但索引取決於您的查詢。使用explain來查看要編制索引的內容。
此外,不要害怕使用複合索引,並避免爲你擁有的每列創建索引。
做到以上的步驟,你將有快速的查詢(讓我們至少希望)

+0

扭曲,非常感謝您的回答,什麼意思是複合索引,是同時在多個列上的索引?對不起,我對數據庫和PHP相當陌生。 –

+0

167是最大的城市名稱,86是最大的國家名稱btw。 –

+0

@KevinVermaat - 好吧,我不知道那個長度的國家/城市名稱,很高興知道。是的,複合索引意味着在多個列上有一個索引,即:'選擇來自用戶的用戶名,其中a = 1和b = 2'將導致在列「a」和列「b」上的組合索引「ab」。 – Twisted1919

1

城市和鄉村的表將是小(相對而言),可能存放在內存漂亮所以查找會快。

如果速度不夠快,嘗試緩存查找客戶端(即您的php應用程序)。

由於您的行將會更小(int而不是varchar),因此您可以在每個頁面上放置更多行,從而加快索引查找速度。

試着先把它做正規化,它可能會足夠快。

並確保您使用InnoDB而不是MyISAM。它有更好的鎖定,你的應用程序看起來非常併發。

+0

非常感謝信息,我會正常化。 –

+0

謝謝,我確實創建了新的結構,它的性能更好。但你確定這個innodb?我使用了很多count查詢,這在innoDB中非常緩慢,因爲它們是全表掃描。我相信你,如果你說InnoDB更適合我的應用程序,但是我有辦法處理count(*)查詢嗎? –

+0

這不是詳細介紹的地方,但您確信MyISAM的計數(*)查詢速度更快。如果您進行任何類型的併發寫入/讀取(而不是純讀取),MyISAM中的表鎖定將快速限制您的吞吐量。如果你只讀MyISAM可能會更好。對於InnoDB計數(*),可以使用觸發器維護一個表計數,但可能比MyISAM更糟糕。 –