MySQL: использование char (n) против десятичного (n) с нулевой заливкой - PullRequest
0 голосов
/ 24 августа 2011

Меня попросили использовать базу данных, в которой большинство первичных ключей, а также другие поля используют char (n) для хранения числовых значений с заполнением, например:

product_id: char(8) [00005677]
user_id: char(6) [000043]
category_id: char(2) [05]

Причинаони хотят использовать его таким образом, чтобы иметь возможность использовать символы (в далеком будущем), если они хотят.Однако у них есть много правил, основанных на числах, например, category_id от 01 до 79 соответствует общей категории, а от 80 до 89 - особая категория, а от 90 до 99 - определяемая пользователем категория.

Я лично считаю, чтоиспользование char (n) для хранения чисел - плохая практика.Мои причины:

  1. , используя char, ""! = 0, 0! = 00, 05! = 5, 00043! = 000043 и так далее.По этой причине значения должны постоянно проверяться (для предотвращения повреждения данных).
  2. Если я дополняю число: 0 -> 00, то я должен обратить внимание, чтобы не дописывать символ (A ->0A)
  3. Если используются символы, то диапазоны становятся странными, что-то вроде: от 01 до 79 и AB и RX, TZ и S и т. Д. ...
  4. В результате индексации чисел вместо символовв прирост производительности

Я предлагаю изменить его на десятичное (n) с нулевым заполнением, чтобы сделать его более «защищенным от ошибок», так как эта информация модифицируется различными источниками (веб, клиент Windows)Загрузите CSV).Если они хотят добавить больше категорий, например, то будет проще перейти с десятичной (2) на десятичную (3).

Тогда у меня вопрос: я ошибаюсь?можно ли доверять char (n) для этой задачи?Если «цифры» являются злом с числами, то какие еще недостатки я пропускаю в приведенном выше списке (мне могут потребоваться более веские причины, если я хочу выиграть дело)?

TIA (любые комментарии / ответы будут оценены).

Ответы [ 2 ]

1 голос
/ 24 августа 2011

Если бы это был SQL Server или Oracle или любая другая СУБД, я бы порекомендовал применить проверочное ограничение для этих столбцов, чтобы данные всегда соответствовали полной емкости столбца - это обеспечило бы ваши идентификаторы единообразными.

К сожалению MySQL не поддерживает это .

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

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

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

Очень часто иметь естественные ключи (которые могут быть кандидатами на первичный ключ) сvarchar / char data, но вместо этого принудительно применяют ссылочную целостность суррогатных ключей (обычно это своего родацелое число mbering, которое является просто внутренней ссылкой, и часто это кластеризованный индекс и первичный ключ).

1 голос
/ 24 августа 2011

Цитируя ваш вопрос:

... сохранять числовые значения с отступом ...

Вы не показывали никаких примеров числовых данных, только символьные данные, которыебывает состоять из цифр.Если бы вы сказали, что их столбец OrderTotal представляет собой символ (10), я бы начал беспокоиться.

Просто отнеситесь к этому как к символьным данным, и все будет в порядке.Я не вижу никаких деловых или технических причин для изменения базы данных (если только вы не начинаете почти полное переписывание).

Что касается производительности ... Если это на самом деле , то у вас, скорее всего, есть гораздо более серьезные проблемы, с которыми вам придется иметь дело.MySQL быстр и точен.

-

Напишите где-нибудь функцию, которая будет обнулять введенные пользователем идентификаторы для запроса.Используйте эту функцию везде вам нужно принять пользовательский ввод.НИКОГДА не используйте числовой тип данных для хранения ваших данных (если PHP никогда не использует +, всегда используйте . для конкататации и т. Д.)

Помните, это не отличается чем Item_Number = "SHIRT123" или любой другой идентификатор строки, с которым вы можете столкнуться.

Берегите себя

...