ДИЗАЙН БАЗЫ ДАННЫХ - первичный ключ для СТРАНЫ, ВАЛЮТЫ int или varchar - PullRequest
11 голосов
/ 02 февраля 2011
  • Для моей таблицы стран я использовал код страны в качестве первичного ключа "АС, США, Великобритания, FR "и т. Д.

  • Для своей таблицы валют я использовал код валюты в качестве первичного ключа «AUD, GBP, USD» и т. Д.

Я думаю, что я сделал все в порядке, но другой разработчик хочет, чтобы я изменил все первичные ключи на int, потому что код страны, код валюты может измениться когда-нибудь в будущем, сказал он. Мы просто не знаем, что в данном случае он прав, его путь - самый безопасный путь.

Должен ли я заменить первичные ключи на int, чтобы быть безопасным, а не сожалеть? Разве я не могу просто оставить это?

Ответы [ 8 ]

14 голосов
/ 02 февраля 2011

Я бы использовал коды ISO со столбцами символов.

Если страна когда-либо разделится, вы получите новые коды ISO (скажем, SC, WL, EN), но Великобритания будет по-прежнему действительна для исторических данных.

То же самое для валюты.Сделка в 2000 году была бы в валюте , в то время : французские франки, немецкие марки, бельгийский банан, но не евро.

3 голосов
/ 03 февраля 2011

С логической точки зрения добавление суррогата означает дополнительные столбцы, дополнительные ключевые ограничения и более сложную логику для запроса и манипулирования данными.Это одна вещь, которую следует учитывать.

С физической точки зрения, в SQL Server ключ INTEGER занимает более чем в два раза больше места, чем CHAR (2) или CHAR (3).Это означает, что ваши ссылочные таблицы и индексы становятся больше.Это также делает любые обновления этих значений внешних ключей намного дороже.Я не знаю ваших данных, но вполне возможно, что ссылочные данные в этих столбцах внешнего ключа могут обновляться гораздо чаще, чем значения кода страны и кода валюты в родительской таблице.Напротив, коды ISO для валюты и страны почти никогда не меняются, так что это, вероятно, очень мало о чем беспокоиться.Переключившись на ключи INTEGER, вы вполне можете увеличить стоимость обновления этих значений внешнего ключа.

Если вы рассматриваете такое изменение как оптимизацию производительности, то я предлагаю вам очень тщательно оценитьКлючи INTEGER сделают обновление этих значений более дорогостоящим или менее затратным.Я предлагаю вам игнорировать людей, которые говорят "всегда делай Х".Догма не помогает в проектировании баз данных.Оцените, каково будет реальное влияние на практике, и примите соответствующее решение.

3 голосов
/ 02 февраля 2011

Я бы сказал, что "рождение нации" или исчезновение валюты - это, в общем-то, довольно редкий случай, который вряд ли произойдет несколько раз в году, каждый год.

Так что в этом отношении я думаю, что использование ISO и страновых кодов для вашего первичного ключа должно быть в порядке.

Да, если что-то случится с еврозоной или если другая страна будет разделена на две части, вам, возможно, придется заняться домашним хозяйством вручную - но вам придется делать это и с INT. В таком случае я бы сказал, что искусственный суррогатный ключ (такой как INT) действительно только увеличивает накладные расходы и не помогает сделать вещи проще / более явными.

Поскольку эти коды действительно короткие и обычно имеют одинаковую длину, я бы порекомендовал использовать CHAR(3) или CHAR(5) - нет смысла использовать VARCHAR для такой короткой строки, а также VARCHAR в качестве переменной поля длины ведут себя совершенно иначе (и не "лучше" с точки зрения производительности), чем поля фиксированной длины, такие как INT или CHAR

1 голос
/ 12 мая 2015

Я думаю, что ваша система устареет в десять раз, прежде чем подойдет стандарт ISO о коде страны и валюты.

Так что я действительно не вижу никакой выгоды от использования 01010101 01010011 или 21843 вместо "US".

0 голосов
/ 16 декабря 2016

Я бы использовал INT-идентификаторы в качестве ключа вместо кодов ISO и объяснил вам, почему:

Организация, в которой я работал, использует «собственную валюту» (LBP) - например, когда пользователь выполняет некоторую транзакцию, он получает некоторое количество LBP в качестве бонуса. Кроме того, он может обменять эти LBP на доллары, евро и т. Д. И наоборот, оплатить услуги с LBP и т. Д. Кроме того, я не нашел валюту BTC (Биткойн) в стандарте ISO.

Да, это не официальные валюты, но с точки зрения системы и пользователей более гибко использовать их в качестве валют, а не в качестве дополнительного продукта, который пользователь может покупать и продавать.

Организация, в которой я работал, не использует INTS в качестве первичного ключа, они используют коды ISO в качестве идентификаторов (плюс эти дополнительные валюты).

Официально LBP является стандартом ISO для ливанского фунта - поэтому они не смогут плавно добавлять ливанский фунт в систему.

Если вы идентифицируете свои валюты по коду, и в будущем некоторая новая валюта будет зарегистрирована как стандарт ISO (скажем, LBE или BTC) - тогда эти валюты будут конфликтовать с «вашими» валютами.

Кто-то упомянул здесь, что наличие дополнительного ключа int для валют является дополнительным индексом. Но извините, это проблема для 300 записей (приблизительное количество валют)? Более того, если вы используете INT в качестве первичного ключа для валют, это дает дополнительное преимущество: представьте себе таблицу с 1M транзакциями, которая содержит суммы и валюты, и что является более эффективным: INTS или CHARS?

Так что я бы пошел на INT.

0 голосов
/ 02 февраля 2011

Плохая практика - использовать что-то в качестве первичного ключа, который изменяется.Предположим, что значение изменилось, а затем вам пришлось обновить все дочерние записи.Это может заблокировать вашу базу данных на несколько часов или даже дней.Вот почему целочисленный FK с уникальным индексом естественного ключа является лучшей практикой для информации, которая непостоянна.

0 голосов
/ 02 февраля 2011

Пока любые внешние ключи, которые ссылаются на эти первичные ключи, объявлены с ON UPDATE CASCADE, кого волнует , если эти коды изменятся?

Есть дополнительная выгода при запросе любой из ссылочных таблиц - если все, что вам нужно, это код страны / валюты, то нет необходимости присоединяться к этим таблицам - вы уже получили код, включенный в эти таблицы.


И если вы решите перейти к суррогату INT, пожалуйста, не забудьте наложить уникальные ограничения на эти столбцы - они являются реальным ключом для этих таблиц.

0 голосов
/ 02 февраля 2011

Да, переход на целочисленный ключ был бы хорошей идеей, пока не стало слишком поздно.

Например, что если Великобритания присоединится к еврозоне?

...