Использование char в качестве первичного / внешнего ключа - нет, нет? - PullRequest
9 голосов
/ 14 сентября 2009

Учтите, что существует множество таблиц, которые ссылаются на таблицы "стран" или "валют".

Для облегчения чтения данных я бы хотел, чтобы поле CHAR с кодом страны (например, США, ГБ, AU) и кодом валюты (USD, AUD) использовалось в качестве первичных ключей в каждой из этих двух таблиц, а во всех остальных таблицах этот CHAR в качестве ключа foregin.

База данных mysql с движком innodb.

Это вызовет проблемы с производительностью? Это то, что я должен избегать?

Ответы [ 3 ]

21 голосов
/ 14 сентября 2009

Производительность на самом деле не главная проблема, по крайней мере, не для меня. Проблема больше в суррогате и натуральном ключе.

Коды стран не являются статичными. Они могут и действительно измениться. Страны меняют названия (например, Эфиопия на Эритрея). Они возникают (например, распад Югославии или Советского Союза), и они перестают существовать (например, Западная и Восточная Германия). Когда это происходит, код стандарта ISO меняется.

Больше в Изменение имени с 1990 года: страны, города и многое другое

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

По этой причине я был бы более склонен создавать таблицы стран и валют с использованием первичного ключа int.

При этом ключевые поля varchar будут занимать больше места и иметь определенные недостатки производительности, которые, вероятно, не будут проблемой, если вы не выполняете огромное количество запросов.

Для полноты вы можете обратиться к Ошибки разработки баз данных, сделанные AppDevelopers .

1 голос
/ 14 сентября 2009

Важно прочитать ссылку Джеймса Скидмора.

Если вы ограничиваете себя кодами страны и валюты (2 и 3 символа соответственно), вы вполне можете избежать объявления столбцов char (2) и char (3).

Я бы предположил, что это не будет нет-нет. Если вы используете 8-битную кодировку символов, вы смотрите на столбцы размером smallint или mediumint соответственно.

0 голосов
/ 14 сентября 2009

Мой ответ таков: четкого ответа нет. Просто выберите подход в вашем проекте и будьте последовательны. У обоих есть свои плюсы и минусы.

@ cletus хорошо подходит для использования сгенерированных ключей, но когда вы сталкиваетесь с ситуацией, когда данные относительно статичны, например, коды стран, введение сгенерированного ключа для них кажется слишком сложным. Несмотря на политику реального мира, наличие и исчезновение кодов стран на самом деле не станет большой проблемой для большинства проблем бизнеса (но если ваши данные активно касаются всех 190-210 стран, следуйте этому совету).

Универсальное использование суррогатных ключей - хорошая и популярная стратегия. Но помните, это происходит в ответ на моделирование баз данных с использованием естественных ключей для всего. Ack! Откройте 15-летнюю книгу базы данных. Повсеместное использование естественных ключей определенно приводит вас к трудным ситуациям, поскольку первоначальное понимание проблемных областей оказывается неверным. Вы действительно хотите быть последовательными в своих методах моделирования, но использование различных методов для совершенно разных ситуаций - это нормально.

Я подозреваю, что производительность для большинства современных баз данных по внешним ключам var (2) будет такой же (или выше), что и у полей int. Базы данных годами поддерживают текстовые внешние ключи.

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

...