我应该为每个用户在MySQL中存储国家/地区名称吗?

时间:2010-01-09 02:57:04

标签: php mysql

下面是我拥有的PHP数组,它有国家/地区列表1到228,其中包含该国家/地区的名称和编号。我在一个旧项目中使用了这个,在MySQL DB中我将用户的国家/地区保存为数字然后我可以使用此数组来避免在页面上执行另一个MySQL查询。

现在我正在做一个性能很重要的不同网站。最好不要这样做,或者更改它并将实际的国家/地区名称存储到每个用户的数据库中?哪种方式最有可能性能明智?

$country_array = array("1" => "Afghanistan","2" => "Albania","3" => "Algeria","4" => "American Samoa","5" => "Andorra","6" => "Angola","7" => "Anguilla","8" => "Antarctica","9" => "Antigua and Barbuda","10" => "Argentina","11" => "Armenia","12" => "Aruba","13" => "Australia","14" => "Austria","15" => "Azerbaijan","16" => "Bahamas","17" => "Bahrain","18" => "Bangladesh","19" => "Barbados","20" => "Belarus","21" => "Belgium","22" => "Belize","23" => "Benin","24" => "Bermuda","25" => "Bhutan","26" => "Bolivia","27" => "Bosnia and Herzegowina","28" => "Botswana","29" => "Bouvet Island","30" => "Brazil","31" => "British Indian Ocean Territory","32" => "British Virgin Islands","33" => "Brunei Darussalam","34" => "Bulgaria","35" => "Burkina Faso","36" => "Burundi","37" => "Cambodia","38" => "Cameroon","40" => "Cape Verde","41" => "Cayman Islands","42" => "Central African Republic","43" => "Chad","44" => "Chile","45" => "China","46" => "Christmas Island","47" => "Cocos (Keeling) Islands","48" => "Colombia","49" => "Comoros","50" => "Congo","51" => "Cook Islands","52" => "Costa Rica","53" => "Cote D'ivoire","54" => "Croatia","55" => "Cuba","56" => "Cyprus","57" => "Czech Republic","58" => "Czechoslovakia","59" => "Denmark","60" => "Djibouti","61" => "Dominica","62" => "Dominican Republic","63" => "East Timor","64" => "Ecuador","65" => "Egypt","66" => "El Salvador","67" => "Equatorial Guinea","68" => "Eritrea","69" => "Estonia","70" => "Ethiopia","71" => "Falkland Islands (Malvinas)","72" => "Faroe Islands","73" => "Fiji","74" => "Finland","75" => "France","76" => "France, Metropolitan","77" => "French Guiana","78" => "French Polynesia","79" => "French Southern Territories","80" => "Gabon","81" => "Gambia","82" => "Georgia","83" => "Germany","84" => "Ghana","85" => "Gibraltar","86" => "Greece","87" => "Greenland","88" => "Grenada","89" => "Guadeloupe","90" => "Guam","91" => "Guatemala","92" => "Guinea","93" => "Guinea-Bissau","94" => "Guyana","95" => "Haiti","96" => "Heard and McDonald Islands","97" => "Honduras","98" => "Hong Kong","99" => "Hungary","100" => "Iceland","101" => "India","102" => "Indonesia","103" => "Iraq","104" => "Ireland","105" => "Islamic Republic of Iran","106" => "Israel","107" => "Italy","108" => "Jamaica","109" => "Japan","110" => "Jordan","111" => "Kazakhstan","112" => "Kenya","113" => "Kiribati","114" => "Korea","115" => "Korea, Republic of","116" => "Kuwait","117" => "Kyrgyzstan","118" => "Laos","119" => "Latvia","120" => "Lebanon","121" => "Lesotho","122" => "Liberia","123" => "Libyan Arab Jamahiriya","124" => "Liechtenstein","125" => "Lithuania","126" => "Luxembourg","127" => "Macau","128" => "Macedonia","129" => "Madagascar","130" => "Malawi","131" => "Malaysia","132" => "Maldives","133" => "Mali","134" => "Malta","135" => "Marshall Islands","136" => "Martinique","137" => "Mauritania","138" => "Mauritius","139" => "Mayotte","140" => "Mexico","141" => "Micronesia","142" => "Moldova, Republic of","143" => "Monaco","144" => "Mongolia","145" => "Montserrat","146" => "Morocco","147" => "Mozambique","148" => "Myanmar","149" => "Namibia","150" => "Nauru","151" => "Nepal","152" => "Netherlands","153" => "Netherlands Antilles","154" => "New Caledonia","155" => "New Zealand","156" => "Nicaragua","157" => "Niger","158" => "Nigeria","159" => "Niue","160" => "Norfolk Island","161" => "Northern Mariana Islands","162" => "Norway","163" => "Oman","164" => "Pakistan","165" => "Palau","166" => "Panama","167" => "Papua New Guinea","168" => "Paraguay","169" => "Peru","170" => "Philippines","171" => "Pitcairn","172" => "Poland","173" => "Portugal","174" => "Puerto Rico","175" => "Qatar","176" => "Reunion","177" => "Romania","178" => "Russian Federation","179" => "Rwanda","180" => "Saint Lucia","181" => "Samoa","182" => "San Marino","183" => "Sao Tome and Principe","184" => "Saudi Arabia","185" => "Senegal","186" => "Seychelles","187" => "Sierra Leone","188" => "Singapore","189" => "Slovakia","190" => "Slovenia","191" => "Solomon Islands","192" => "Somalia","193" => "South Africa","194" => "Spain","195" => "Sri Lanka","196" => "St. Helena","197" => "St. Kitts And Nevis","198" => "St. Pierre and Miquelon","199" => "St. Vincent And The Greadines","200" => "Sudan","201" => "Suriname","202" => "Svalbard and Jan Mayen Islands","203" => "Swaziland","204" => "Sweden","205" => "Switzerland","206" => "Syrian Arab Republic","207" => "Taiwan","208" => "Tajikistan","209" => "Tanzania, United Republic of","210" => "Thailand","211" => "Togo","212" => "Tokelau","213" => "Tonga","214" => "Trinidad and Tobago","215" => "Tunisia","216" => "Turkey","217" => "Turkmenistan","218" => "Turks and Caicos Islands","219" => "Tuvalu","220" => "Uganda","221" => "Ukraine","222" => "United Arab Emirates","225" => "United States Virgin Islands","226" => "Uruguay","227" => "Uzbekistan","228" => "Vanuatu","229" => "Vatican City State","230" => "Venezuela","231" => "Viet Nam","232" => "Wallis And Futuna Islands","233" => "Western Sahara","234" => "Yemen","235" => "Yugoslavia","236" => "Zaire","237" => "Zambia","238" => "Zimbabwe");

8 个答案:

答案 0 :(得分:5)

最快保留一个名为countries的表格和users表格中名为countrycountry_id的字段,其中包含每个用户所在国家/地区的外键countries表。

MYSQL中的连接通常(几乎总是)比遍历返回记录列表并将国家/地区与用户配对更快。

答案 1 :(得分:2)

编辑:在第二遍时,请考虑我在下面所说的关于字符串的所有内容,但选择enum字段。在包含所有国家/地区的数据库中创建枚举,并使用该枚举而不是字符串或其他表。它应该为您提供使用字符串的所有好处(比如在没有连接的情况下获取您想要的值)以及使用第二个表的所有好处。


假设您的主要用例是“让我所有用户和国家/地区”或“让我获得用户N和国家/地区”的效果,那么最快您可以做的是存储字符串

这有一些陷阱:字符串比较比索引方法(在另一个答案中讨论)更昂贵,如果你计划经常运行一些东西,以“让我所有用户来自X国”,你知道索引很好,那么你可以避免字符串比较。

即使存在后一种情况,如果后一种情况占主导地位,那么实际上只需要另一个表格,数据将会发生变化(您计划稍后添加新国家/地区,更新国家名称),如果要根据某些用户区域设置等更改要更改的国家/地区名称的语言

避免联接会节省一些执行时间,但第二个表 也适合你。

答案 2 :(得分:2)

要提高速度,请使用MEMORY 存储引擎创建一个表,一旦数据库开始使用您的值填充表格,它就会非常快。

同样访问你的数组非常快,因为你没有搜索数组,你知道位置(使用int键)并且只是寻找那里。

答案 3 :(得分:0)

通常,比较整数值比比较字符串更有效。

答案 4 :(得分:0)

在我看来,将表中国家/地区的名称与用户名一起使用可以节省内存性能,因为您不会在数组中存储国家/地区的名称。但是,除非没有获取国家/地区名称的查询,否则您将无法使用原始方式进行相同数量的查询,因此您不会节省太多其他内容。

答案 5 :(得分:0)

我不是很熟悉PHP,但是你不能将国家列表存储在数据库中(在你的用户表中有一个FK到这个列表中),将列表存储在缓存中,并在每当某些东西时更新缓存变化?看起来世界上的所有不稳定,你希望能够经常更新这个列表,并且像这样硬编码将要求你每次内战时都要更改你的代码。

答案 6 :(得分:0)

对于数据的初始加载,您可以使用ISO-3166数据。大多数Linux发行版附带一个包(iso-codes),其中包含所有国家/地区的列表及其名称​​翻译成多种语言。也有几种格式(CSV,XML和.po用于翻译)。

http://pkg-isocodes.alioth.debian.org/

答案 7 :(得分:0)

键应该是整数,而不是字符串,除了它没关系。