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

StackOverflow https://stackoverflow.com/questions/1419210

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

Подробнее в Изменения имен с 1990 года: страны, города и многое другое

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

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

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

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

Другие советы

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top