2013-07-18 59 views
4

我想將每個訪問者的國家插入到我的數據庫中。 Maxmind返回2個字母的國家ISO,我可以存儲在一個VARCHAR(2),這將使用2個字節,或者,我可以使用一個UNSIGNED TINYINT將使用1個字節,並將是所有國家的表中的ID。MySQL從另一個表插入國家iso或國家/地區編號

但是我碰到一個凹凸;我需要MyISAM引擎來實現快速插入,但是MyISAM不支持FOREIGN KEYS,所以我猜想對於每個插入,我必須在國家/地區表中進行選擇以檢索國家/地區ID。

我不知道什麼是最好的選擇,我絕對需要使用MyISAM,因爲會有大量的插入,但我不想不斷地讓SELECTs檢索國家ID。

回答

1

如果你只需要2個字母的ISO國家代碼(而不是國家名稱,語言或其他信息),那麼我會說它存儲爲CHAR(2)而不是將其存儲爲SMALLINT(TINYINT不足以覆蓋所有國家),並查找附加表。

注意:在這種情況下不需要VARCHAR(2),CHAR(2)會更有效。

+0

關於CHAR存儲類型的好主意,我完全忘記了它,然而UNSIGNED TINYINT只能使用一個字節就能達到255,並且最多有196個國家。 – user2593609

0

您可以從國家/地區表創建關聯數組。將國家ID作爲此陣列的關鍵字。然後將其提供給您的意見。因此,從觀點來看,您可以對國家陣列進行查詢並顯示相關國家。例如

<?php echo $country[$customer['country_id']]['country_name']; ?> 
+0

這種方法不會每次構建一個php數組,這相當於在mysql數據庫中進行選擇嗎? – user2593609

+0

不是真的,你可以將它存儲在像'memcache'這樣的東西里。 – DevZer0

+0

嗯,從來沒有用過memcache,我會去看看它是如何工作的,謝謝你的建議! – user2593609

0

有FK支持和沒有它的唯一區別是確保完整性。如果您要使用支持FK的引擎,它不允許您在沒有該記錄ID的情況下設置國家/地區。

這就是說,國家的數量是半靜態的,我們只是在數百... ...你可能會保留所有這些在內存中,並有ID的可愛。

或者你可以在插入過程中做一個選擇,如:

INSERT INTO sometable (col1,col2,country_id) VALUES('val1','val2', (SELECT id FROM countries WHERE iso_code = ?))

?將是你的ISO值。

+0

該死的,我希望有一種方法可以避免在每次插入時執行選擇,這會減慢插入的速度嗎? – user2593609

+0

如果你在桌子上有適當的索引,可能不會。我的意思是我個人可能不會走出使用MyISAM的性能原因。我曾經使用它的唯一真正原因是全文搜索,但我更多地使用了像Solr這樣的外部特性,所以這也不是問題。到底什麼是應用程序的本質? – prodigitalson

+0

這是一個日誌表,所以每秒插入一次,因此MyISAM引擎可以快速插入。然後在後端統計部分。儘管沒有編輯,這就是爲什麼我不需要InnoDB的行鎖。 – user2593609