Должен ли я хранить названия стран в mysql для каждого пользователя?
Ниже приведен массив PHP, который содержит список стран от 1 до 228 с именем и номером для этой страны. Я использовал это в старом проекте, где в базе данных mysql я сохранил страну пользователя в виде числа, а затем я мог бы использовать этот массив, чтобы избежать выполнения другого запроса 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 ответов
Быстрее всего держать таблицу под названием countries
и поле на вашем users
стол называется country
или же country_id
который содержит внешний ключ для каждой страны пользователя в countries
Таблица.
Соединение в MYSQL обычно (почти всегда) быстрее, чем итерация по списку возвращаемых записей и сопоставление страны с пользователем.
Изменить: на втором проходе, рассмотреть все, что я сказал ниже о строках, но выбрать поле enum. Создайте перечисление в базе данных, содержащей все страны, и используйте это, а не строки или другую таблицу. Он должен дать вам все преимущества использования строк (например, получение нужного значения без объединения) и все преимущества использования второй таблицы.
Если предположить, что ваш основной сценарий использования - это что-то вроде "получить мне всех пользователей и страну" или "получить мне пользователя N и страну", то самое быстрое, что вы можете сделать, это сохранить строку.
В этом есть некоторые подводные камни: сравнение строк обходится дороже, чем, скажем, индексированный подход (обсуждается в другом ответе), и если вы планируете часто запускать что-то с эффектом "приведите меня всех пользователей из страны X", где вы хорошо знаете индекс, тогда Вы можете избежать сравнения строк.
Даже если последний случай существует, он действительно платит за то, чтобы иметь другую таблицу, только если последний случай доминирует в использовании, данные будут меняться (вы планируете добавлять новые страны позже, обновлять названия стран), если хотите изменить язык названия страны для изменения в зависимости от локали пользователя и т. д.
Избегание объединений сэкономит вам время выполнения, но вторая таблица также может быть вам подойдет.
Чтобы повысить скорость, создайте таблицу с механизмом хранения MEMORY. Как только база данных начнет заполнять таблицу вашими значениями, это будет очень быстро.
Также доступ к вашему массиву очень быстрый, потому что вы не ищите массив, вы знаете позицию (с помощью клавиш int) и просто ищите там.
Я не очень знаком с PHP, но не могли бы вы сохранить список стран в БД (с FK в таблице пользователей в этом списке), сохранить список в кеше и обновлять кеш всякий раз, когда что-то меняется? Кажется, что при всей нестабильности в мире вы хотели бы иметь возможность обновлять этот список несколько чаще, и такое жесткое кодирование потребует от вас изменения кода каждый раз, когда происходит гражданская война.
Ключи должны быть целыми числами, а не строками, кроме того, это нормально.
Для начальной загрузки данных вы можете использовать данные ISO-3166. Большинство дистрибутивов Linux поставляются с пакетом (iso-коды), содержащим список всех стран и их названия, переведенные на многие языки. Также в нескольких форматах (CSV, XML и.po для переводов).
Обычно сравнение целочисленных значений более эффективно, чем сравнение строк.
Мне кажется, что размещение названий стран в таблице с именами пользователей сохранит вашу производительность памяти, поскольку вы не будете хранить названия стран в массиве. Но вы больше не сэкономите, так как вы делаете то же количество запросов, что и при использовании оригинального способа, за исключением того, что не запрашивает названия стран.